diff --git a/.github/workflows/test_benchmarks.yml b/.github/workflows/test_benchmarks.yml index ef06bf6a6..bc2a5dce3 100644 --- a/.github/workflows/test_benchmarks.yml +++ b/.github/workflows/test_benchmarks.yml @@ -38,8 +38,7 @@ jobs: SCIPY: 1 PYOPTSPARSE: 'v2.9.1' SNOPT: '7.7' - #OPENMDAO: 'latest' - OPENMDAO: '3.34.2' + OPENMDAO: 'latest' DYMOS: 'latest' SSH_PRIVATE_KEY: ${{secrets.SSH_PRIVATE_KEY}} SSH_KNOWN_HOSTS: ${{secrets.SSH_KNOWN_HOSTS}} diff --git a/.github/workflows/test_docs.yml b/.github/workflows/test_docs.yml index adb4cd351..31977627d 100644 --- a/.github/workflows/test_docs.yml +++ b/.github/workflows/test_docs.yml @@ -38,8 +38,7 @@ jobs: SCIPY: 1 PYOPTSPARSE: 'v2.9.1' SNOPT: '7.7' - #OPENMDAO: 'latest' - OPENMDAO: '3.34.2' + OPENMDAO: 'latest' DYMOS: 'latest' SSH_PRIVATE_KEY: ${{secrets.SSH_PRIVATE_KEY}} SSH_KNOWN_HOSTS: ${{secrets.SSH_KNOWN_HOSTS}} diff --git a/.github/workflows/test_workflow.yml b/.github/workflows/test_workflow.yml index 36242e636..7f028d92d 100644 --- a/.github/workflows/test_workflow.yml +++ b/.github/workflows/test_workflow.yml @@ -34,13 +34,14 @@ jobs: matrix: include: # oldest versions of openmdao/dymos + # Note: bugfixes sometimes require incrementing the minimal version of openmdao or dymos. - NAME: oldest PY: '3.9' NUMPY: '1.20' SCIPY: '1.6' PYOPTSPARSE: 'v2.9.1' SNOPT: '7.7' - OPENMDAO: '3.33.0' + OPENMDAO: '3.35.0' DYMOS: '1.8.0' # latest versions of openmdao/dymos @@ -50,8 +51,7 @@ jobs: SCIPY: 1 PYOPTSPARSE: 'v2.9.1' SNOPT: '7.7' - #OPENMDAO: 'latest' - OPENMDAO: '3.34.2' + OPENMDAO: 'latest' DYMOS: 'latest' steps: diff --git a/.github/workflows/test_workflow_dev_deps.yml b/.github/workflows/test_workflow_dev_deps.yml index a3fd58944..92daf1528 100644 --- a/.github/workflows/test_workflow_dev_deps.yml +++ b/.github/workflows/test_workflow_dev_deps.yml @@ -27,8 +27,7 @@ jobs: SCIPY: 1 PYOPTSPARSE: 'latest' SNOPT: '7.7' - #OPENMDAO: 'dev' - OPENMDAO: '3.34.2' + OPENMDAO: 'dev' DYMOS: 'dev' steps: diff --git a/.github/workflows/test_workflow_no_dev_install.yml b/.github/workflows/test_workflow_no_dev_install.yml index b4c9d1672..dd8f1f67e 100644 --- a/.github/workflows/test_workflow_no_dev_install.yml +++ b/.github/workflows/test_workflow_no_dev_install.yml @@ -70,7 +70,6 @@ jobs: echo "" echo "Temporarily install specific versions for now." pip install "numpy<2" - pip install "openmdao==3.34.2" pip install packaging pip install .[all] diff --git a/.gitignore b/.gitignore index 824371144..dd8663cd2 100644 --- a/.gitignore +++ b/.gitignore @@ -152,5 +152,9 @@ coloring_files/ # OpenMDAO N2 diagrams n2.html +# Input and output lists +input_list.txt +output_list.txt + # Windows downloads *:Zone.Identifier diff --git a/aviary/docs/developer_guide/codebase_overview.ipynb b/aviary/docs/developer_guide/codebase_overview.ipynb index cc4769bea..23cc6bc89 100644 --- a/aviary/docs/developer_guide/codebase_overview.ipynb +++ b/aviary/docs/developer_guide/codebase_overview.ipynb @@ -18,7 +18,7 @@ " 'interface':'is where most code that users interact with is located',\n", " 'mission':'contains OpenMDAO components and groups for modeling the aircraft mission',\n", " 'models':'contains aircraft and propulsion models for use in Aviary examples and tests',\n", - " 'subsystems':'is where the aerodynamic, propulsion, mass, and geometry core subsystems are located',\n", + " 'subsystems':'is where the aerodynamic, atmosphere, energy, propulsion, mass, and geometry core subsystems are located',\n", " 'utils':'contains utility functions for use in Aviary code, examples, and tests',\n", " 'validation_cases':'contains validation cases for testing and benchmarking Aviary',\n", " 'variable_info':'contains the variable meta data as well as several variable classes that are used in Aviary',\n", diff --git a/aviary/docs/examples/coupled_aircraft_mission_optimization.ipynb b/aviary/docs/examples/coupled_aircraft_mission_optimization.ipynb index 899e3de38..1546e6ae6 100644 --- a/aviary/docs/examples/coupled_aircraft_mission_optimization.ipynb +++ b/aviary/docs/examples/coupled_aircraft_mission_optimization.ipynb @@ -197,7 +197,7 @@ "aircraft_filename = 'models/test_aircraft/aircraft_for_bench_FwFm.csv'\n", "optimizer = \"IPOPT\"\n", "make_plots = True\n", - "max_iter = 200\n", + "max_iter = 100\n", "\n", "prob = av.run_aviary(aircraft_filename, phase_info, optimizer=optimizer,\n", " make_plots=make_plots, max_iter=max_iter)" diff --git a/aviary/docs/getting_started/onboarding_ext_subsystem.ipynb b/aviary/docs/getting_started/onboarding_ext_subsystem.ipynb index 9d9a491fc..72c54d7a2 100644 --- a/aviary/docs/getting_started/onboarding_ext_subsystem.ipynb +++ b/aviary/docs/getting_started/onboarding_ext_subsystem.ipynb @@ -217,7 +217,7 @@ "\n", "The steps in bold are related specifically to subsystems. So, almost all of the steps involve subsystems. As long as your external subsystem is built based on the guidelines, Aviary will take care of your subsystem.\n", "\n", - "The next example is the [battery subsystem](https://github.com/OpenMDAO/Aviary/blob/main/aviary/docs/user_guide/battery_subsystem_example). The battery subsystem provides methods to define the battery subsystem's states, design variables, fixed values, initial guesses, and mass names. It also provides methods to build OpenMDAO systems for the pre-mission and mission computations of the subsystem, to get the constraints for the subsystem, and to preprocess the inputs for the subsystem. This subsystem has its own set of variables. We will build an Aviary model with full phases (namely, `climb`, `cruise` and `descent`) and maximize the final total mass: `Dynamic.Mission.MASS`." + "The next example is the [battery subsystem](https://github.com/OpenMDAO/Aviary/blob/main/aviary/docs/user_guide/battery_subsystem_example). The battery subsystem provides methods to define the battery subsystem's states, design variables, fixed values, initial guesses, and mass names. It also provides methods to build OpenMDAO systems for the pre-mission and mission computations of the subsystem, to get the constraints for the subsystem, and to preprocess the inputs for the subsystem. This subsystem has its own set of variables. We will build an Aviary model with full phases (namely, `climb`, `cruise` and `descent`) and maximize the final total mass: `Dynamic.Vehicle.MASS`." ] }, { @@ -233,7 +233,7 @@ "source": [ "# Testing Cell\n", "from aviary.api import Dynamic\n", - "Dynamic.Mission.MASS;" + "Dynamic.Vehicle.MASS;" ] }, { @@ -399,7 +399,7 @@ "id": "ed8c764a", "metadata": {}, "source": [ - "Since our objective is `mass`, we want to print the value of `Dynamic.Mission.Mass`. Remember, we have imported Dynamic from aviary.variable_info.variables for this purpose.\n", + "Since our objective is `mass`, we want to print the value of `Dynamic.Vehicle.MASS`. Remember, we have imported Dynamic from aviary.variable_info.variables for this purpose.\n", "\n", "So, we have to print the final mass in a different way. Keep in mind that we have three phases in the mission and that final mass is our objective. So, we can get the final mass of the descent phase instead. Let us try this approach. Let us comment out the print statement of final mass (and the import of Dynamic), then add the following lines:" ] diff --git a/aviary/docs/getting_started/onboarding_level1.ipynb b/aviary/docs/getting_started/onboarding_level1.ipynb index c6afb1456..bbae17fe3 100644 --- a/aviary/docs/getting_started/onboarding_level1.ipynb +++ b/aviary/docs/getting_started/onboarding_level1.ipynb @@ -474,7 +474,7 @@ "\n", "In ground roll phase, throttle setting is set to maximum (1.0). Aviary sets a phase parameter:\n", "```\n", - "Dynamic.Mission.THROTTLE = 1.0\n", + "Dynamic.Vehicle.Propulsion.THROTTLE = 1.0\n", "```\n", "For the [`COLLOCATION`](https://openmdao.github.io/dymos/getting_started/collocation.html) setting, there is one [segment](https://openmdao.github.io/dymos/getting_started/intro_to_dymos/intro_segments.html) (`'num_segments': 1`) and polynomial interpolation degree is 3 (`'order': 3`). Increasing the number of segments and/or increasing the degree of polynomial will improve accuracy but will also increase the complexity of computation. For groundroll, it is unnecessary.\n", "\n", diff --git a/aviary/docs/getting_started/onboarding_level2.ipynb b/aviary/docs/getting_started/onboarding_level2.ipynb index 1ab60df9b..cbad194b5 100644 --- a/aviary/docs/getting_started/onboarding_level2.ipynb +++ b/aviary/docs/getting_started/onboarding_level2.ipynb @@ -629,12 +629,12 @@ "\n", "| objective_type | objective |\n", "| -------------- | --------- |\n", - "| mass | `Dynamic.Mission.MASS` |\n", + "| mass | `Dynamic.Vehicle.MASS` |\n", "| hybrid_objective | `-final_mass / {takeoff_mass} + final_time / 5.` |\n", "| fuel_burned | `initial_mass - mass_final` (for `FLOPS` mission only)|\n", "| fuel | `Mission.Objectives.FUEL` |\n", "\n", - "As listed in the above, if `objective_type=\"mass\"`, the objective is the final value of `Dynamic.Mission.MASS` at the end of the mission.\n", + "As listed in the above, if `objective_type=\"mass\"`, the objective is the final value of `Dynamic.Vehicle.MASS` at the end of the mission.\n", "If `objective_type=\"fuel\"`, the objective is the `Mission.Objectives.FUEL`.\n", "There is a special objective type: `hybrid_objective`. When `objective_type=\"hybrid_objective\"`, the objective is a mix of minimizing fuel burn and minimizing the mission duration:" ] @@ -659,7 +659,7 @@ "from aviary.utils.doctape import check_contains\n", "\n", "mo = Mission.Objectives\n", - "dm = Dynamic.Mission\n", + "dm = Dynamic.Vehicle\n", "expected_objective = {'mass':dm.MASS, 'hybrid_objective':'obj_comp.obj',\n", " 'fuel_burned':Mission.Summary.FUEL_BURNED, 'fuel':mo.FUEL}\n", "\n", diff --git a/aviary/docs/getting_started/onboarding_level3.ipynb b/aviary/docs/getting_started/onboarding_level3.ipynb index f235936b5..6b02bffa0 100644 --- a/aviary/docs/getting_started/onboarding_level3.ipynb +++ b/aviary/docs/getting_started/onboarding_level3.ipynb @@ -334,7 +334,7 @@ "# link phases #\n", "###############\n", "\n", - "traj.link_phases([\"climb\", \"cruise\", \"descent\"], [\"time\", av.Dynamic.Mission.MASS, av.Dynamic.Mission.DISTANCE], connected=strong_couple)\n", + "traj.link_phases([\"climb\", \"cruise\", \"descent\"], [\"time\", av.Dynamic.Vehicle.MASS, av.Dynamic.Mission.DISTANCE], connected=strong_couple)\n", "\n", "param_vars = [av.Aircraft.Nacelle.CHARACTERISTIC_LENGTH,\n", " av.Aircraft.Nacelle.FINENESS,\n", @@ -474,9 +474,9 @@ " av.Dynamic.Mission.ALTITUDE, ys=[alt_i_climb, alt_f_climb]), units='m')\n", "prob.set_val(\n", " 'traj.climb.controls:mach', climb.interp(\n", - " av.Dynamic.Mission.MACH, ys=[mach_i_climb, mach_f_climb]), units='unitless')\n", + " av.Dynamic.Atmosphere.MACH, ys=[mach_i_climb, mach_f_climb]), units='unitless')\n", "prob.set_val('traj.climb.states:mass', climb.interp(\n", - " av.Dynamic.Mission.MASS, ys=[mass_i_climb, mass_f_climb]), units='kg')\n", + " av.Dynamic.Vehicle.MASS, ys=[mass_i_climb, mass_f_climb]), units='kg')\n", "prob.set_val('traj.climb.states:distance', climb.interp(\n", " av.Dynamic.Mission.DISTANCE, ys=[range_i_climb, range_f_climb]), units='m')\n", "\n", @@ -487,9 +487,9 @@ " av.Dynamic.Mission.ALTITUDE, ys=[alt_i_cruise, alt_f_cruise]), units='m')\n", "prob.set_val(\n", " 'traj.cruise.controls:mach', cruise.interp(\n", - " av.Dynamic.Mission.MACH, ys=[cruise_mach, cruise_mach]), units='unitless')\n", + " av.Dynamic.Atmosphere.MACH, ys=[cruise_mach, cruise_mach]), units='unitless')\n", "prob.set_val('traj.cruise.states:mass', cruise.interp(\n", - " av.Dynamic.Mission.MASS, ys=[mass_i_cruise, mass_f_cruise]), units='kg')\n", + " av.Dynamic.Vehicle.MASS, ys=[mass_i_cruise, mass_f_cruise]), units='kg')\n", "prob.set_val('traj.cruise.states:distance', cruise.interp(\n", " av.Dynamic.Mission.DISTANCE, ys=[range_i_cruise, range_f_cruise]), units='m')\n", "\n", @@ -500,9 +500,9 @@ " av.Dynamic.Mission.ALTITUDE, ys=[alt_i_descent, alt_f_descent]), units='m')\n", "prob.set_val(\n", " 'traj.descent.controls:mach', descent.interp(\n", - " av.Dynamic.Mission.MACH, ys=[mach_i_descent, mach_f_descent]), units='unitless')\n", + " av.Dynamic.Atmosphere.MACH, ys=[mach_i_descent, mach_f_descent]), units='unitless')\n", "prob.set_val('traj.descent.states:mass', descent.interp(\n", - " av.Dynamic.Mission.MASS, ys=[mass_i_descent, mass_f_descent]), units='kg')\n", + " av.Dynamic.Vehicle.MASS, ys=[mass_i_descent, mass_f_descent]), units='kg')\n", "prob.set_val('traj.descent.states:distance', descent.interp(\n", " av.Dynamic.Mission.DISTANCE, ys=[distance_i_descent, distance_f_descent]), units='m')\n", "\n", diff --git a/aviary/docs/user_guide/SGM_capabilities.ipynb b/aviary/docs/user_guide/SGM_capabilities.ipynb index b8e008215..f6ff901cd 100644 --- a/aviary/docs/user_guide/SGM_capabilities.ipynb +++ b/aviary/docs/user_guide/SGM_capabilities.ipynb @@ -132,14 +132,14 @@ " problem_name=phase_name,\n", " outputs=[\"normal_force\", \"alpha\"],\n", " states=[\n", - " Dynamic.Mission.MASS,\n", + " Dynamic.Vehicle.MASS,\n", " Dynamic.Mission.DISTANCE,\n", " Dynamic.Mission.ALTITUDE,\n", " Dynamic.Mission.VELOCITY,\n", " ],\n", " # state_units=['lbm','nmi','ft'],\n", " alternate_state_rate_names={\n", - " Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL},\n", + " Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL},\n", " **simupy_args,\n", " )\n", "\n", @@ -196,11 +196,11 @@ "full_traj = FlexibleTraj(\n", " Phases=phase_info,\n", " traj_final_state_output=[\n", - " Dynamic.Mission.MASS,\n", + " Dynamic.Vehicle.MASS,\n", " Dynamic.Mission.DISTANCE,\n", " ],\n", " traj_initial_state_input=[\n", - " Dynamic.Mission.MASS,\n", + " Dynamic.Vehicle.MASS,\n", " Dynamic.Mission.DISTANCE,\n", " Dynamic.Mission.ALTITUDE,\n", " ],\n", @@ -210,11 +210,11 @@ " # third key is event_idx associated with input\n", " ('groundroll', Dynamic.Mission.VELOCITY, 0,),\n", " ('climb3', Dynamic.Mission.ALTITUDE, 0,),\n", - " ('cruise', Dynamic.Mission.MASS, 0,),\n", + " ('cruise', Dynamic.Vehicle.MASS, 0,),\n", " ],\n", " traj_intermediate_state_output=[\n", " ('cruise', Dynamic.Mission.DISTANCE),\n", - " ('cruise', Dynamic.Mission.MASS),\n", + " ('cruise', Dynamic.Vehicle.MASS),\n", " ]\n", ")" ] @@ -278,7 +278,7 @@ "from aviary.utils.doctape import check_value\n", "\n", "for phase_name, phase in descent_phases.items():\n", - " check_value(phase['user_options'][Dynamic.Mission.THROTTLE],(0, 'unitless'))" + " check_value(phase['user_options'][Dynamic.Vehicle.Propulsion.THROTTLE],(0, 'unitless'))" ] } ], @@ -298,7 +298,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 eb65a5b25..6f6da86e7 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 @@ -450,9 +450,9 @@ " av.Dynamic.Mission.ALTITUDE, ys=[alt_i_climb, alt_f_climb]), units='m')\n", "prob.set_val(\n", " 'traj.climb.controls:mach', climb.interp(\n", - " av.Dynamic.Mission.MACH, ys=[mach_i_climb, mach_f_climb]), units='unitless')\n", + " av.Dynamic.Atmosphere.MACH, ys=[mach_i_climb, mach_f_climb]), units='unitless')\n", "prob.set_val('traj.climb.states:mass', climb.interp(\n", - " av.Dynamic.Mission.MASS, ys=[mass_i_climb, mass_f_climb]), units='kg')\n", + " av.Dynamic.Vehicle.MASS, ys=[mass_i_climb, mass_f_climb]), units='kg')\n", "prob.set_val('traj.climb.states:distance', climb.interp(\n", " av.Dynamic.Mission.DISTANCE, ys=[distance_i_climb, distance_f_climb]), units='m')\n", "\n", @@ -463,9 +463,9 @@ " av.Dynamic.Mission.ALTITUDE, ys=[alt_i_cruise, alt_f_cruise]), units='m')\n", "prob.set_val(\n", " 'traj.cruise.controls:mach', cruise.interp(\n", - " av.Dynamic.Mission.MACH, ys=[cruise_mach, cruise_mach]), units='unitless')\n", + " av.Dynamic.Atmosphere.MACH, ys=[cruise_mach, cruise_mach]), units='unitless')\n", "prob.set_val('traj.cruise.states:mass', cruise.interp(\n", - " av.Dynamic.Mission.MASS, ys=[mass_i_cruise, mass_f_cruise]), units='kg')\n", + " av.Dynamic.Vehicle.MASS, ys=[mass_i_cruise, mass_f_cruise]), units='kg')\n", "prob.set_val('traj.cruise.states:distance', cruise.interp(\n", " av.Dynamic.Mission.DISTANCE, ys=[distance_i_cruise, distance_f_cruise]), units='m')\n", "\n", @@ -476,9 +476,9 @@ " av.Dynamic.Mission.ALTITUDE, ys=[alt_i_descent, alt_f_descent]), units='m')\n", "prob.set_val(\n", " 'traj.descent.controls:mach', descent.interp(\n", - " av.Dynamic.Mission.MACH, ys=[mach_i_descent, mach_f_descent]), units='unitless')\n", + " av.Dynamic.Atmosphere.MACH, ys=[mach_i_descent, mach_f_descent]), units='unitless')\n", "prob.set_val('traj.descent.states:mass', descent.interp(\n", - " av.Dynamic.Mission.MASS, ys=[mass_i_descent, mass_f_descent]), units='kg')\n", + " av.Dynamic.Vehicle.MASS, ys=[mass_i_descent, mass_f_descent]), units='kg')\n", "prob.set_val('traj.descent.states:distance', descent.interp(\n", " av.Dynamic.Mission.DISTANCE, ys=[distance_i_descent, distance_f_descent]), units='m')\n", "\n", diff --git a/aviary/docs/user_guide/hamilton_standard.ipynb b/aviary/docs/user_guide/hamilton_standard.ipynb index b6fa18475..ff1cfa736 100644 --- a/aviary/docs/user_guide/hamilton_standard.ipynb +++ b/aviary/docs/user_guide/hamilton_standard.ipynb @@ -91,21 +91,20 @@ "import aviary.api as av\n", "\n", "options = get_option_defaults()\n", - "options.set_val(av.Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, val=True, units='unitless')\n", - "options.set_val(av.Aircraft.Engine.NUM_PROPELLER_BLADES, val=4, units='unitless')\n", + "options.set_val(av.Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=True, units='unitless')\n", + "options.set_val(av.Aircraft.Engine.Propeller.NUM_BLADES, val=4, units='unitless')\n", "options.set_val(av.Aircraft.Engine.GENERATE_FLIGHT_IDLE, False)\n", "options.set_val(av.Aircraft.Engine.DATA_FILE, 'models/engines/turboshaft_4465hp.deck')\n", - "options.set_val(av.Aircraft.Engine.USE_PROPELLER_MAP, val=False)\n", "\n", "prob = om.Problem()\n", "group = prob.model\n", "for name in ('traj','cruise','rhs_all'):\n", " group = group.add_subsystem(name, om.Group())\n", "var_names = [\n", - " (av.Aircraft.Engine.PROPELLER_TIP_SPEED_MAX,0,{'units':'ft/s'}),\n", + " (av.Aircraft.Engine.Propeller.TIP_SPEED_MAX,0,{'units':'ft/s'}),\n", " # (av.Dynamic.Mission.PERCENT_ROTOR_RPM_CORRECTED,0,{'units':'unitless'}),\n", - " (av.Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR,0,{'units':'unitless'}),\n", - " (av.Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT,0,{'units':'unitless'}),\n", + " (av.Aircraft.Engine.Propeller.ACTIVITY_FACTOR,0,{'units':'unitless'}),\n", + " (av.Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT,0,{'units':'unitless'}),\n", " ]\n", "group.add_subsystem('ivc',om.IndepVarComp(var_names),promotes=['*'])\n", "\n", @@ -121,10 +120,10 @@ " promotes_inputs=['*'],\n", " promotes_outputs=[\"*\"],\n", ")\n", - "pp.set_input_defaults(av.Aircraft.Engine.PROPELLER_DIAMETER, 10, units=\"ft\")\n", - "pp.set_input_defaults(av.Dynamic.Mission.MACH, .7, units=\"unitless\")\n", - "# pp.set_input_defaults(av.Dynamic.Mission.TEMPERATURE, 650, units=\"degR\")\n", - "pp.set_input_defaults(av.Dynamic.Mission.PROPELLER_TIP_SPEED, 800, units=\"ft/s\")\n", + "pp.set_input_defaults(av.Aircraft.Engine.Propeller.DIAMETER, 10, units=\"ft\")\n", + "pp.set_input_defaults(av.Dynamic.Atmosphere.MACH, .7, units=\"unitless\")\n", + "# pp.set_input_defaults(av.Dynamic.Atmosphere.TEMPERATURE, 650, units=\"degR\")\n", + "pp.set_input_defaults(av.Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, 800, units=\"ft/s\")\n", "pp.set_input_defaults(av.Dynamic.Mission.VELOCITY, 100, units=\"knot\")\n", "prob.setup()\n", "\n", @@ -203,20 +202,20 @@ }, "outputs": [], "source": [ - "Aircraft.Engine.PROPELLER_DIAMETER\n", - "Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT\n", - "Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR\n", - "Aircraft.Engine.NUM_PROPELLER_BLADES\n", - "Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS\n", - "Dynamic.Mission.PROPELLER_TIP_SPEED\n", - "Dynamic.Mission.SHAFT_POWER" + "Aircraft.Engine.Propeller.DIAMETER\n", + "Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT\n", + "Aircraft.Engine.Propeller.ACTIVITY_FACTOR\n", + "Aircraft.Engine.Propeller.NUM_BLADES\n", + "Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS\n", + "Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED\n", + "Dynamic.Vehicle.Propulsion.SHAFT_POWER" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "To build a turboprop engine that uses the Hamilton Standard propeller model we use a `TurboPropModel` object with `propeller_model` set to `True` and `shaft_power_model` set to `False` (the default):" + "To build a turboprop engine that uses the Hamilton Standard propeller model we use a `TurbopropModel` object without providing a custom `propeller_model`, here it is set to `None` (the default). In this example, we also set `shaft_power_model` to `None`, another default that assumes we are using a turboshaft engine deck:" ] }, { @@ -229,7 +228,7 @@ }, "outputs": [], "source": [ - "engine = TurbopropModel(options=options, shaft_power_model=None, propeller_model=True)" + "engine = TurbopropModel(options=options, shaft_power_model=None, propeller_model=None)" ] }, { @@ -249,9 +248,9 @@ }, "outputs": [], "source": [ - "options.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10, units='ft')\n", - "options.set_val(Aircraft.Engine.NUM_PROPELLER_BLADES, val=4, units='unitless')\n", - "options.set_val(Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, val=True, units='unitless')" + "options.set_val(Aircraft.Engine.Propeller.DIAMETER, 10, units='ft')\n", + "options.set_val(Aircraft.Engine.Propeller.NUM_BLADES, val=4, units='unitless')\n", + "options.set_val(Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=True, units='unitless')" ] }, { @@ -271,9 +270,9 @@ }, "outputs": [], "source": [ - "prob.set_val(f'traj.cruise.rhs_all.{Aircraft.Engine.PROPELLER_TIP_SPEED_MAX}', 710., units='ft/s')\n", - "prob.set_val(f'traj.cruise.rhs_all.{Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR}', 150., units='unitless')\n", - "prob.set_val(f'traj.cruise.rhs_all.{Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT}', 0.5, units='unitless')" + "prob.set_val(f'traj.cruise.rhs_all.{Aircraft.Engine.Propeller.TIP_SPEED_MAX}', 710., units='ft/s')\n", + "prob.set_val(f'traj.cruise.rhs_all.{Aircraft.Engine.Propeller.ACTIVITY_FACTOR}', 150., units='unitless')\n", + "prob.set_val(f'traj.cruise.rhs_all.{Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT}', 0.5, units='unitless')" ] }, { @@ -284,7 +283,7 @@ "\n", "The Hamilton Standard model has limitations where it can be applied; for model aircraft design, it is possible that users may want to provide their own data tables. Two sample data sets are provided in `models/propellers` folder: `general_aviation.prop` and `PropFan.prop`. In both cases, they are in `.csv` format and are converted from `GASP` maps: `general_aviation.map` and `PropFan.map` (see [Command Line Tools](aviary_commands.ipynb) for details). The difference between these two samples is that the generatl aviation sample uses helical Mach numbers as input while the propfan sample uses the free stream Mach numbers. Helical Mach numbers appear higher, due to the inclusion of the rotational component of the tip velocity. In our example, they range from 0.7 to 0.95. To determine which mach type in a GASP map is used, please look at the first integer of the first line. If it is 1, it uses helical mach; if it is 2, it uses free stream mach. To determin which mach type is an Aviary propeller file is used, please look at the second item in the header. It is either `Helical_Mach` or `Mach`.\n", "\n", - "To use a propeller map, users can set `Aircraft.Engine.USE_PROPELLER_MAP` to `True` and provide the propeller map file path to `Aircraft.Engine.PROPELLER_DATA_FILE`. If helical Mach numbers are in the propeller map file, then an `OutMachs` component is added to convert helical Mach numbers to flight Mach numbers (`Dynamic.Mission.MACH`).\n", + "To use a propeller map, users can provide the propeller map file path to `Aircraft.Engine.Propeller.DATA_FILE`. If helical Mach numbers are in the propeller map file, then an `OutMachs` component is added to convert helical Mach numbers to flight Mach numbers (`Dynamic.Atmosphere.MACH`).\n", "\n", "In the Hamilton Standard models, the thrust coefficients do not take compressibility into account. Therefore, propeller tip compressibility loss factor has to be computed and will be used to compute thrust. If a propeller map is used, the compressibility effects should be included in the data provided. Therefore, this factor is assumed to be 1.0 and is supplied to post Hamilton Standard component. Other outputs are computed using the same formulas." ] diff --git a/aviary/examples/external_subsystems/engine_NPSS/table_engine_builder.py b/aviary/examples/external_subsystems/engine_NPSS/table_engine_builder.py index bd2f9e53a..af8baae33 100644 --- a/aviary/examples/external_subsystems/engine_NPSS/table_engine_builder.py +++ b/aviary/examples/external_subsystems/engine_NPSS/table_engine_builder.py @@ -2,10 +2,19 @@ import numpy as np import openmdao.api as om -from aviary.examples.external_subsystems.engine_NPSS.engine_variable_meta_data import ExtendedMetaData -from aviary.examples.external_subsystems.engine_NPSS.engine_variables import Aircraft, Dynamic -from aviary.examples.external_subsystems.engine_NPSS.NPSS_Model.DesignEngineGroup import DesignEngineGroup -from aviary.examples.external_subsystems.engine_NPSS.table_engine_connected_variables import vars_to_connect +from aviary.examples.external_subsystems.engine_NPSS.engine_variable_meta_data import ( + ExtendedMetaData, +) +from aviary.examples.external_subsystems.engine_NPSS.engine_variables import ( + Aircraft, + Dynamic, +) +from aviary.examples.external_subsystems.engine_NPSS.NPSS_Model.DesignEngineGroup import ( + DesignEngineGroup, +) +from aviary.examples.external_subsystems.engine_NPSS.table_engine_connected_variables import ( + vars_to_connect, +) from aviary.subsystems.propulsion.engine_model import EngineModel from aviary.utils.aviary_values import AviaryValues from aviary.utils.functions import get_aviary_resource_path @@ -79,16 +88,27 @@ def build_mission(self, num_nodes, aviary_inputs): # interpolator object for engine data engine = om.MetaModelSemiStructuredComp( - method=interp_method, extrapolate=True, vec_size=num_nodes, training_data_gradients=True) - - ref = os.path.join("examples", "external_subsystems", "engine_NPSS", - "NPSS_Model", "Output", "RefEngine.outputAviary") + method=interp_method, + extrapolate=True, + vec_size=num_nodes, + training_data_gradients=True, + ) + + ref = os.path.join( + "examples", + "external_subsystems", + "engine_NPSS", + "NPSS_Model", + "Output", + "RefEngine.outputAviary", + ) csv_path = get_aviary_resource_path(ref) engine_data = np.genfromtxt(csv_path, skip_header=0) # Sort the data by Mach, then altitude, then throttle - engine_data = engine_data[np.lexsort( - (engine_data[:, 2], engine_data[:, 1], engine_data[:, 0]))] + engine_data = engine_data[ + np.lexsort((engine_data[:, 2], engine_data[:, 1], engine_data[:, 0])) + ] zeros_array = np.zeros((engine_data.shape[0], 1)) # create a new array for thrust_max. here we take the values where throttle=1.0 @@ -97,49 +117,72 @@ def build_mission(self, num_nodes, aviary_inputs): # for a given mach, altitude, and hybrid throttle setting, the thrust_max is the value where throttle=1.0 for i in range(engine_data.shape[0]): # find the index of the first instance where throttle=1.0 - index = np.where((engine_data[:, 0] == engine_data[i, 0]) & ( - engine_data[:, 1] == engine_data[i, 1]) & (engine_data[:, 2] == 1.0))[0][0] + index = np.where( + (engine_data[:, 0] == engine_data[i, 0]) + & (engine_data[:, 1] == engine_data[i, 1]) + & (engine_data[:, 2] == 1.0) + )[0][0] thrust_max[i] = engine_data[index, 3] - print(Dynamic.Mission.THRUST, '--------------------------------------') + print( + Dynamic.Vehicle.Propulsion.THRUST, '--------------------------------------' + ) # add inputs and outputs to interpolator - engine.add_input(Dynamic.Mission.MACH, - engine_data[:, 0], - units='unitless', - desc='Current flight Mach number') - engine.add_input(Dynamic.Mission.ALTITUDE, - engine_data[:, 1], - units='ft', - desc='Current flight altitude') - engine.add_input(Dynamic.Mission.THROTTLE, - engine_data[:, 2], - units='unitless', - desc='Current engine throttle') - engine.add_output(Dynamic.Mission.THRUST, - engine_data[:, 3], - units='lbf', - desc='Current net thrust produced') - engine.add_output(Dynamic.Mission.THRUST_MAX, - thrust_max, - units='lbf', - desc='Max net thrust produced') - engine.add_output(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, - -engine_data[:, 4], - units='lbm/s', - desc='Current fuel flow rate ') - engine.add_output(Dynamic.Mission.ELECTRIC_POWER_IN, - zeros_array, - units='kW', - desc='Current electric energy rate') - engine.add_output(Dynamic.Mission.NOX_RATE, - zeros_array, - units='lb/h', - desc='Current NOx emission rate') - engine.add_output(Dynamic.Mission.TEMPERATURE_T4, - zeros_array, - units='degR', - desc='Current turbine exit temperature') + engine.add_input( + Dynamic.Atmosphere.MACH, + engine_data[:, 0], + units='unitless', + desc='Current flight Mach number', + ) + engine.add_input( + Dynamic.Mission.ALTITUDE, + engine_data[:, 1], + units='ft', + desc='Current flight altitude', + ) + engine.add_input( + Dynamic.Vehicle.Propulsion.THROTTLE, + engine_data[:, 2], + units='unitless', + desc='Current engine throttle', + ) + engine.add_output( + Dynamic.Vehicle.Propulsion.THRUST, + engine_data[:, 3], + units='lbf', + desc='Current net thrust produced', + ) + engine.add_output( + Dynamic.Vehicle.Propulsion.THRUST_MAX, + thrust_max, + units='lbf', + desc='Max net thrust produced', + ) + engine.add_output( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, + -engine_data[:, 4], + units='lbm/s', + desc='Current fuel flow rate ', + ) + engine.add_output( + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, + zeros_array, + units='kW', + desc='Current electric energy rate', + ) + engine.add_output( + Dynamic.Vehicle.Propulsion.NOX_RATE, + zeros_array, + units='lb/h', + desc='Current NOx emission rate', + ) + engine.add_output( + Dynamic.Vehicle.Propulsion.TEMPERATURE_T4, + zeros_array, + units='degR', + desc='Current turbine exit temperature', + ) return engine def get_bus_variables(self): @@ -170,8 +213,12 @@ def get_design_vars(self): Dictionary with keys that are names of variables to be made design variables and the values are dictionaries with the keys `units`, `upper`, `lower`, and `ref`. ''' - mass_flow_dict = {'units': 'lbm/s', 'upper': 450, 'lower': 100, - 'ref': 450} # upper and lower are just notional for now + mass_flow_dict = { + 'units': 'lbm/s', + 'upper': 450, + 'lower': 100, + 'ref': 450, + } # upper and lower are just notional for now design_vars = { Aircraft.Engine.DESIGN_MASS_FLOW: mass_flow_dict, } diff --git a/aviary/examples/external_subsystems/engine_NPSS/table_engine_connected_variables.py b/aviary/examples/external_subsystems/engine_NPSS/table_engine_connected_variables.py index 2450f0ae1..35e534e90 100755 --- a/aviary/examples/external_subsystems/engine_NPSS/table_engine_connected_variables.py +++ b/aviary/examples/external_subsystems/engine_NPSS/table_engine_connected_variables.py @@ -3,19 +3,19 @@ vars_to_connect = { "Fn_train": { "mission_name": [ - Dynamic.Mission.THRUST+"_train", + Dynamic.Vehicle.Propulsion.THRUST + "_train", ], "units": "lbf", }, "Fn_max_train": { "mission_name": [ - Dynamic.Mission.THRUST_MAX+"_train", + Dynamic.Vehicle.Propulsion.THRUST_MAX + "_train", ], "units": "lbf", }, "Wf_inv_train": { "mission_name": [ - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE+"_train", + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE + "_train", ], "units": "lbm/s", }, diff --git a/aviary/examples/level2_shooting_traj.py b/aviary/examples/level2_shooting_traj.py index e51261736..89739c427 100644 --- a/aviary/examples/level2_shooting_traj.py +++ b/aviary/examples/level2_shooting_traj.py @@ -62,7 +62,7 @@ def custom_run_aviary(aircraft_filename, optimizer=None, 'alt_trigger': (10000, 'ft'), 'mach': (0, 'unitless'), 'speed_trigger': (350, 'kn'), - Dynamic.Mission.THROTTLE: (0, 'unitless'), + Dynamic.Vehicle.Propulsion.THROTTLE: (0, 'unitless'), }, 'descent_phase': True, }, @@ -86,18 +86,30 @@ def custom_run_aviary(aircraft_filename, optimizer=None, traj = FlexibleTraj( Phases=phase_info, traj_final_state_output=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, ], traj_initial_state_input=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], traj_event_trigger_input=[ - ('groundroll', Dynamic.Mission.VELOCITY, 0,), - ('climb3', Dynamic.Mission.ALTITUDE, 0,), - ('cruise', Dynamic.Mission.DISTANCE, 0,), + ( + 'groundroll', + Dynamic.Mission.VELOCITY, + 0, + ), + ( + 'climb3', + Dynamic.Mission.ALTITUDE, + 0, + ), + ( + 'cruise', + Dynamic.Mission.DISTANCE, + 0, + ), ], ) prob.traj = prob.model.add_subsystem('traj', traj) diff --git a/aviary/examples/run_detailed_landing_in_level2.py b/aviary/examples/run_detailed_landing_in_level2.py index 82c6fd220..fb611ce78 100644 --- a/aviary/examples/run_detailed_landing_in_level2.py +++ b/aviary/examples/run_detailed_landing_in_level2.py @@ -1,3 +1,5 @@ + + import openmdao.api as om import aviary.api as av @@ -179,7 +181,12 @@ prob.run_aviary_problem(record_filename='detailed_landing.db') - cr = om.CaseReader('detailed_landing.db') + try: + loc = prob.get_outputs_dir() + cr = om.CaseReader(f'{loc}/detailed_landing.db') + except: + cr = om.CaseReader('detailed_landing.db') + cases = cr.get_cases('problem') case = cases[0] diff --git a/aviary/examples/run_detailed_takeoff_in_level2.py b/aviary/examples/run_detailed_takeoff_in_level2.py index 9b1607ea9..4a79899c2 100644 --- a/aviary/examples/run_detailed_takeoff_in_level2.py +++ b/aviary/examples/run_detailed_takeoff_in_level2.py @@ -355,7 +355,12 @@ prob.run_aviary_problem(record_filename='detailed_takeoff.db') - cr = om.CaseReader('detailed_takeoff.db') + try: + loc = prob.get_outputs_dir() + cr = om.CaseReader(f'{loc}/detailed_takeoff.db') + except: + cr = om.CaseReader('detailed_takeoff.db') + cases = cr.get_cases('problem') case = cases[0] diff --git a/aviary/interface/default_phase_info/height_energy_fiti.py b/aviary/interface/default_phase_info/height_energy_fiti.py index d96443ef6..dfb0b5901 100644 --- a/aviary/interface/default_phase_info/height_energy_fiti.py +++ b/aviary/interface/default_phase_info/height_energy_fiti.py @@ -34,13 +34,13 @@ "user_options": { 'mach': (cruise_mach, 'unitless'), 'alt_trigger': (1000, 'ft'), - Dynamic.Mission.THROTTLE: (0, 'unitless'), + Dynamic.Vehicle.Propulsion.THROTTLE: (0, 'unitless'), }, }, "post_mission": { "include_landing": False, "constrain_range": True, - "target_range": (1906., "nmi"), + "target_range": (1906.0, "nmi"), }, } diff --git a/aviary/interface/default_phase_info/two_dof_fiti.py b/aviary/interface/default_phase_info/two_dof_fiti.py index 0c4318f04..e8e66d501 100644 --- a/aviary/interface/default_phase_info/two_dof_fiti.py +++ b/aviary/interface/default_phase_info/two_dof_fiti.py @@ -109,7 +109,7 @@ 'alt_trigger': (10000, 'ft'), 'mach': (cruise_mach, 'unitless'), 'speed_trigger': (350, 'kn'), - Dynamic.Mission.THROTTLE: (0, 'unitless'), + Dynamic.Vehicle.Propulsion.THROTTLE: (0, 'unitless'), }, 'descent_phase': True, }, @@ -124,7 +124,7 @@ 'alt_trigger': (10000, 'ft'), 'EAS': (350, 'kn'), 'speed_trigger': (0, 'kn'), - Dynamic.Mission.THROTTLE: (0, 'unitless'), + Dynamic.Vehicle.Propulsion.THROTTLE: (0, 'unitless'), }, 'descent_phase': True, }, @@ -139,7 +139,7 @@ 'alt_trigger': (1000, 'ft'), 'EAS': (250, 'kn'), 'speed_trigger': (0, 'kn'), - Dynamic.Mission.THROTTLE: (0, 'unitless'), + Dynamic.Vehicle.Propulsion.THROTTLE: (0, 'unitless'), }, 'descent_phase': True, }, diff --git a/aviary/interface/methods_for_level2.py b/aviary/interface/methods_for_level2.py index 01d141f07..1c248b1ba 100644 --- a/aviary/interface/methods_for_level2.py +++ b/aviary/interface/methods_for_level2.py @@ -287,8 +287,8 @@ def load_inputs( if mission_method is TWO_DEGREES_OF_FREEDOM or mass_method is GASP: aviary_inputs = update_GASP_options(aviary_inputs) - initialization_guesses = initialization_guessing(aviary_inputs, initialization_guesses, - engine_builders) + initialization_guesses = initialization_guessing( + aviary_inputs, initialization_guesses, engine_builders) self.aviary_inputs = aviary_inputs self.initialization_guesses = initialization_guesses @@ -308,7 +308,8 @@ def load_inputs( # Access the phase_info variable from the loaded module phase_info = outputted_phase_info.phase_info - # if verbosity level is BRIEF or higher, print that we're using the outputted phase info + # if verbosity level is BRIEF or higher, print that we're using the + # outputted phase info if verbosity is not None and verbosity >= Verbosity.BRIEF: print('Using outputted phase_info from current working directory') @@ -359,10 +360,14 @@ def load_inputs( self.aviary_inputs = aviary_inputs if mission_method is TWO_DEGREES_OF_FREEDOM: - aviary_inputs.set_val(Mission.Summary.CRUISE_MASS_FINAL, - val=self.initialization_guesses['cruise_mass_final'], units='lbm') - aviary_inputs.set_val(Mission.Summary.GROSS_MASS, - val=self.initialization_guesses['actual_takeoff_mass'], units='lbm') + aviary_inputs.set_val( + Mission.Summary.CRUISE_MASS_FINAL, + val=self.initialization_guesses['cruise_mass_final'], + units='lbm') + aviary_inputs.set_val( + Mission.Summary.GROSS_MASS, + val=self.initialization_guesses['actual_takeoff_mass'], + units='lbm') # Commonly referenced values self.cruise_alt = aviary_inputs.get_val( @@ -388,8 +393,10 @@ def load_inputs( elif mission_method is HEIGHT_ENERGY: self.problem_type = aviary_inputs.get_val(Settings.PROBLEM_TYPE) - aviary_inputs.set_val(Mission.Summary.GROSS_MASS, - val=self.initialization_guesses['actual_takeoff_mass'], units='lbm') + aviary_inputs.set_val( + Mission.Summary.GROSS_MASS, + val=self.initialization_guesses['actual_takeoff_mass'], + units='lbm') if 'target_range' in self.post_mission_info: aviary_inputs.set_val(Mission.Summary.RANGE, wrapped_convert_units( phase_info['post_mission']['target_range'], 'NM'), units='NM') @@ -398,7 +405,8 @@ def load_inputs( phase_info['post_mission']['target_range'], 'NM') else: self.require_range_residual = False - # still instantiate target_range because it is used for default guesses for phase comps + # still instantiate target_range because it is used for default guesses + # for phase comps self.target_range = aviary_inputs.get_val( Mission.Design.RANGE, units='NM') @@ -483,13 +491,15 @@ def check_and_preprocess_inputs(self): for idx, phase_name in enumerate(self.phase_info): if 'user_options' in self.phase_info[phase_name]: analytic = False - if (self.analysis_scheme is AnalysisScheme.COLLOCATION) and (self.mission_method is EquationsOfMotion.TWO_DEGREES_OF_FREEDOM): + if (self.analysis_scheme is AnalysisScheme.COLLOCATION) and ( + self.mission_method is EquationsOfMotion.TWO_DEGREES_OF_FREEDOM): try: # if the user provided an option, use it analytic = self.phase_info[phase_name]["user_options"][ 'analytic'] except KeyError: - # if it isn't specified, only the default 2DOF cruise for collocation is analytic + # if it isn't specified, only the default 2DOF cruise for + # collocation is analytic if 'cruise' in phase_name: analytic = self.phase_info[phase_name]["user_options"][ 'analytic'] = True @@ -515,8 +525,9 @@ def check_and_preprocess_inputs(self): self.phase_info[phase_name].update({"initial_guesses": {"time": ( (target_duration[0], target_duration[0]), target_duration[1])}}) # Set Fixed_duration to true: - self.phase_info[phase_name]["user_options"].update({ - "fix_duration": True}) + self.phase_info[phase_name]["user_options"].update( + {"fix_duration": True} + ) if self.analysis_scheme is AnalysisScheme.COLLOCATION: check_phase_info(self.phase_info, self.mission_method) @@ -873,8 +884,8 @@ def _get_phase(self, phase_name, phase_idx): if 'phase_builder' in phase_options: phase_builder = phase_options['phase_builder'] if not issubclass(phase_builder, PhaseBuilderBase): - raise TypeError( - f"phase_builder for the phase called {phase_name} must be a PhaseBuilderBase object.") + raise TypeError(f"phase_builder for the phase called " + "{phase_name} must be a PhaseBuilderBase object.") else: phase_builder = EnergyPhase @@ -894,7 +905,8 @@ def _get_phase(self, phase_name, phase_idx): # TODO: add logic to filter which phases get which controls. # right now all phases get all controls added from every subsystem. - # for example, we might only want ELECTRIC_SHAFT_POWER applied during the climb phase. + # for example, we might only want ELECTRIC_SHAFT_POWER applied during the + # climb phase. all_subsystems = self._get_all_subsystems( phase_options['external_subsystems']) @@ -985,7 +997,8 @@ def _get_phase(self, phase_name, phase_idx): if fix_initial or input_initial: if self.comm.size > 1: - # Phases are disconnected to run in parallel, so initial ref is valid. + # Phases are disconnected to run in parallel, so initial ref is + # valid. initial_ref = user_options.get_val("initial_ref", time_units) else: # Redundant on a fixed input; raises a warning if specified. @@ -1016,8 +1029,11 @@ def _get_phase(self, phase_name, phase_idx): if 'cruise' not in phase_name and self.mission_method is TWO_DEGREES_OF_FREEDOM: phase.add_control( - Dynamic.Mission.THROTTLE, targets=Dynamic.Mission.THROTTLE, - units='unitless', opt=False,) + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, + units='unitless', + opt=False, + ) return phase @@ -1052,11 +1068,11 @@ def add_phases(self, phase_info_parameterization=None): full_traj = FlexibleTraj( Phases=self.phase_info, traj_final_state_output=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, ], traj_initial_state_input=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], @@ -1064,17 +1080,30 @@ def add_phases(self, phase_info_parameterization=None): # specify ODE, output_name, with units that SimuPyProblem expects # assume event function is of form ODE.output_name - value # third key is event_idx associated with input - ('groundroll', Dynamic.Mission.VELOCITY, 0,), - ('climb3', Dynamic.Mission.ALTITUDE, 0,), - ('cruise', Dynamic.Mission.MASS, 0,), + ( + 'groundroll', + Dynamic.Mission.VELOCITY, + 0, + ), + ( + 'climb3', + Dynamic.Mission.ALTITUDE, + 0, + ), + ( + 'cruise', + Dynamic.Vehicle.MASS, + 0, + ), ], traj_intermediate_state_output=[ ('cruise', Dynamic.Mission.DISTANCE), - ('cruise', Dynamic.Mission.MASS), - ] + ('cruise', Dynamic.Vehicle.MASS), + ], ) - traj = self.model.add_subsystem('traj', full_traj, promotes_inputs=[ - ('altitude_initial', Mission.Design.CRUISE_ALTITUDE)]) + traj = self.model.add_subsystem( + 'traj', full_traj, promotes_inputs=[ + ('altitude_initial', Mission.Design.CRUISE_ALTITUDE)]) self.model.add_subsystem( 'actual_descent_fuel', om.ExecComp( @@ -1148,8 +1177,9 @@ def add_subsystem_timeseries_outputs(phase, phase_name): if not self.pre_mission_info['include_takeoff']: first_flight_phase_name = list(phase_info.keys())[0] first_flight_phase = traj._phases[first_flight_phase_name] - first_flight_phase.set_state_options(Dynamic.Mission.MASS, - fix_initial=False) + first_flight_phase.set_state_options( + Dynamic.Vehicle.MASS, fix_initial=False + ) self.traj = traj @@ -1202,7 +1232,7 @@ def add_post_mission_systems(self, include_landing=True): # Check if regular_phases[] is accessible try: self.regular_phases[0] - except: + except BaseException: raise ValueError( f"regular_phases[] dictionary is not accessible." f" For HEIGHT_ENERGY and SOLVED_2DOF missions, check_and_preprocess_inputs()" @@ -1230,7 +1260,8 @@ def add_post_mission_systems(self, include_landing=True): ('initial_mass', Mission.Summary.GROSS_MASS), ]) else: - # timeseries has to be used because Breguet cruise phases don't have states + # timeseries has to be used because Breguet cruise phases don't have + # states self.model.connect(f"traj.{self.regular_phases[0]}.timeseries.mass", "fuel_burned.initial_mass", src_indices=[0]) @@ -1244,8 +1275,9 @@ def add_post_mission_systems(self, include_landing=True): mass_final={'units': 'lbm'}, reserve_fuel_burned={'units': 'lbm'}) - self.post_mission.add_subsystem('reserve_fuel_burned', ecomp, promotes=[ - ('reserve_fuel_burned', Mission.Summary.RESERVE_FUEL_BURNED)]) + self.post_mission.add_subsystem( + 'reserve_fuel_burned', ecomp, promotes=[ + ('reserve_fuel_burned', Mission.Summary.RESERVE_FUEL_BURNED)]) if self.analysis_scheme is AnalysisScheme.SHOOTING: # shooting method currently doesn't have timeseries @@ -1256,7 +1288,8 @@ def add_post_mission_systems(self, include_landing=True): f"traj.{self.reserve_phases[-1]}.states:mass", "reserve_fuel_burned.mass_final", src_indices=[-1]) else: - # timeseries has to be used because Breguet cruise phases don't have states + # timeseries has to be used because Breguet cruise phases don't have + # states self.model.connect( f"traj.{self.reserve_phases[0]}.timeseries.mass", "reserve_fuel_burned.initial_mass", src_indices=[0]) @@ -1268,7 +1301,8 @@ def add_post_mission_systems(self, include_landing=True): # TODO: need to add some sort of check that this value is less than the fuel capacity # TODO: the overall_fuel variable is the burned fuel plus the reserve, but should - # also include the unused fuel, and the hierarchy variable name should be more clear + # also include the unused fuel, and the hierarchy variable name should be + # more clear ecomp = om.ExecComp('overall_fuel = (1 + fuel_margin/100)*fuel_burned + reserve_fuel', overall_fuel={'units': 'lbm', 'shape': 1}, fuel_margin={"units": "unitless", 'val': 0}, @@ -1285,7 +1319,8 @@ def add_post_mission_systems(self, include_landing=True): promotes_outputs=[('overall_fuel', Mission.Summary.TOTAL_FUEL_MASS)]) # If a target distance (or time) has been specified for this phase - # distance (or time) is measured from the start of this phase to the end of this phase + # distance (or time) is measured from the start of this phase to the end + # of this phase for phase_name in self.phase_info: if 'target_distance' in self.phase_info[phase_name]["user_options"]: target_distance = wrapped_convert_units( @@ -1368,10 +1403,9 @@ def add_post_mission_systems(self, include_landing=True): # connect summary mass to the initial guess of mass in the first phase if not self.pre_mission_info['include_takeoff']: first_flight_phase_name = list(self.phase_info.keys())[0] - eq = self.model.add_subsystem(f'link_{first_flight_phase_name}_mass', - om.EQConstraintComp(), - promotes_inputs=[('rhs:mass', - Mission.Summary.GROSS_MASS)]) + eq = self.model.add_subsystem( + f'link_{first_flight_phase_name}_mass', om.EQConstraintComp(), + promotes_inputs=[('rhs:mass', Mission.Summary.GROSS_MASS)]) eq.add_eq_output('mass', eq_units='lbm', normalize=False, ref=100000., add_constraint=True) self.model.connect( @@ -1409,7 +1443,8 @@ def _link_phases_helper_with_options(self, phases, option_name, var, **kwargs): # Loop through each group and determine the phases to link for group in groups_to_link: - # Extend the group to include the phase before the first True option and after the last True option, if applicable + # Extend the group to include the phase before the first True option and + # after the last True option, if applicable if group[0] > 0: group.insert(0, group[0] - 1) if group[-1] < len(phases) - 1: @@ -1475,22 +1510,33 @@ def link_phases(self): if self.mission_method in (HEIGHT_ENERGY, SOLVED_2DOF): # connect regular_phases with each other if you are optimizing alt or mach self._link_phases_helper_with_options( - self.regular_phases, 'optimize_altitude', Dynamic.Mission.ALTITUDE, ref=1.e4) + self.regular_phases, + 'optimize_altitude', + Dynamic.Mission.ALTITUDE, + ref=1.0e4, + ) self._link_phases_helper_with_options( - self.regular_phases, 'optimize_mach', Dynamic.Mission.MACH) + self.regular_phases, 'optimize_mach', Dynamic.Atmosphere.MACH + ) # connect reserve phases with each other if you are optimizing alt or mach self._link_phases_helper_with_options( - self.reserve_phases, 'optimize_altitude', Dynamic.Mission.ALTITUDE, ref=1.e4) + self.reserve_phases, + 'optimize_altitude', + Dynamic.Mission.ALTITUDE, + ref=1.0e4, + ) self._link_phases_helper_with_options( - self.reserve_phases, 'optimize_mach', Dynamic.Mission.MACH) + self.reserve_phases, 'optimize_mach', Dynamic.Atmosphere.MACH + ) if self.mission_method is HEIGHT_ENERGY: - # connect mass and distance between all phases regardless of reserve / non-reserve status + # connect mass and distance between all phases regardless of reserve / + # non-reserve status self.traj.link_phases(phases, ["time"], ref=None if true_unless_mpi else 1e3, connected=true_unless_mpi) - self.traj.link_phases(phases, [Dynamic.Mission.MASS], + self.traj.link_phases(phases, [Dynamic.Vehicle.MASS], ref=None if true_unless_mpi else 1e6, connected=true_unless_mpi) self.traj.link_phases(phases, [Dynamic.Mission.DISTANCE], @@ -1502,7 +1548,7 @@ def link_phases(self): src_indices=[-1], flat_src_indices=True) elif self.mission_method is SOLVED_2DOF: - self.traj.link_phases(phases, [Dynamic.Mission.MASS], connected=True) + self.traj.link_phases(phases, [Dynamic.Vehicle.MASS], connected=True) self.traj.link_phases( phases, [Dynamic.Mission.DISTANCE], units='ft', ref=1.e3, connected=False) @@ -1514,8 +1560,8 @@ def link_phases(self): elif self.mission_method is TWO_DEGREES_OF_FREEDOM: if self.analysis_scheme is AnalysisScheme.COLLOCATION: - for ii in range(len(phases)-1): - phase1, phase2 = phases[ii:ii+2] + for ii in range(len(phases) - 1): + phase1, phase2 = phases[ii:ii + 2] analytic1 = self.phase_info[phase1]['user_options']['analytic'] analytic2 = self.phase_info[phase2]['user_options']['analytic'] @@ -1524,7 +1570,7 @@ def link_phases(self): states_to_link = { 'time': true_unless_mpi, Dynamic.Mission.DISTANCE: true_unless_mpi, - Dynamic.Mission.MASS: False, + Dynamic.Vehicle.MASS: False, } # if both phases are reserve phases or neither is a reserve phase @@ -1548,11 +1594,13 @@ def link_phases(self): states_to_link['alpha'] = False for state, connected in states_to_link.items(): - # in initial guesses, all of the states, other than time use the same name + # in initial guesses, all of the states, other than time use + # the same name initial_guesses1 = self.phase_info[phase1]['initial_guesses'] initial_guesses2 = self.phase_info[phase2]['initial_guesses'] - # if a state is in the initial guesses, get the units of the initial guess + # if a state is in the initial guesses, get the units of the + # initial guess kwargs = {} if not connected: if state in initial_guesses1: @@ -1565,14 +1613,15 @@ def link_phases(self): # if either phase is analytic we have to use a linkage_constraint else: - # analytic phases use the prefix "initial" for time and distance, but not mass + # analytic phases use the prefix "initial" for time and distance, + # but not mass if analytic2: prefix = 'initial_' else: prefix = '' self.traj.add_linkage_constraint( - phase1, phase2, 'time', prefix+'time', connected=True) + phase1, phase2, 'time', prefix + 'time', connected=True) self.traj.add_linkage_constraint( phase1, phase2, 'distance', prefix + 'distance', connected=True) @@ -1782,7 +1831,8 @@ def add_design_variables(self): In all cases, a design variable is added for the final cruise mass of the aircraft, with no upper bound, and a residual mass constraint is added to ensure that the mass balances. """ - # add the engine builder `get_design_vars` dict to a collected dict from the external subsystems + # add the engine builder `get_design_vars` dict to a collected dict from + # the external subsystems # TODO : maybe in the most general case we need to handle DVs in the mission and post-mission as well. # for right now we just handle pre_mission @@ -1802,7 +1852,8 @@ def add_design_variables(self): elif self.mission_method in (HEIGHT_ENERGY, TWO_DEGREES_OF_FREEDOM): # vehicle sizing problem - # size the vehicle (via design GTOW) to meet a target range using all fuel capacity + # size the vehicle (via design GTOW) to meet a target range using all fuel + # capacity if self.problem_type is ProblemType.SIZING: self.model.add_design_var( Mission.Design.GROSS_MASS, @@ -1839,7 +1890,8 @@ def add_design_variables(self): ) # target range problem - # fixed vehicle (design GTOW) but variable actual GTOW for off-design mission range + # fixed vehicle (design GTOW) but variable actual GTOW for off-design + # mission range elif self.problem_type is ProblemType.ALTERNATE: self.model.add_design_var( Mission.Summary.GROSS_MASS, @@ -1945,12 +1997,14 @@ def add_objective(self, objective_type=None, ref=None): if objective_type == 'mass': if self.analysis_scheme is AnalysisScheme.COLLOCATION: self.model.add_objective( - f"traj.{final_phase_name}.timeseries.{Dynamic.Mission.MASS}", - index=-1, ref=ref) + f"traj.{final_phase_name}.timeseries.{Dynamic.Vehicle.MASS}", + index=-1, + ref=ref + ) else: last_phase = self.traj._phases.items()[final_phase_name] last_phase.add_objective( - Dynamic.Mission.MASS, loc='final', ref=ref) + Dynamic.Vehicle.MASS, loc='final', ref=ref) elif objective_type == 'time': self.model.add_objective( f"traj.{final_phase_name}.timeseries.time", index=-1, ref=ref) @@ -1994,7 +2048,8 @@ def _add_bus_variables_and_connect(self): if not isinstance(mission_variable_name, list): mission_variable_name = [mission_variable_name] - # loop over the mission_variable_name list and add each variable to the trajectory + # loop over the mission_variable_name list and add each variable to + # the trajectory for mission_var_name in mission_variable_name: if mission_var_name not in self.meta_data: # base_units = self.model.get_io_metadata(includes=f'pre_mission.{external_subsystem.name}.{bus_variable}')[f'pre_mission.{external_subsystem.name}.{bus_variable}']['units'] @@ -2013,23 +2068,30 @@ def _add_bus_variables_and_connect(self): for phase_name in variable_data['phases']: phase = getattr(self.traj.phases, phase_name) - phase.add_parameter(mission_var_name, opt=False, static_target=True, - units=base_units, shape=shape, targets=targets) + phase.add_parameter( + mission_var_name, opt=False, static_target=True, + units=base_units, shape=shape, targets=targets) - self.model.connect(f'pre_mission.{bus_variable}', - f'traj.{phase_name}.parameters:{mission_var_name}') + self.model.connect( + f'pre_mission.{bus_variable}', + f'traj.{phase_name}.parameters:{mission_var_name}') else: - self.traj.add_parameter(mission_var_name, opt=False, static_target=True, - units=base_units, shape=shape, targets={ - phase_name: [mission_var_name] for phase_name in base_phases}) + self.traj.add_parameter( + mission_var_name, opt=False, static_target=True, + units=base_units, shape=shape, + targets={phase_name: [mission_var_name] + for phase_name in base_phases}) self.model.connect( - f'pre_mission.{bus_variable}', f'traj.parameters:'+mission_var_name) + f'pre_mission.{bus_variable}', + f'traj.parameters:' + mission_var_name) if 'post_mission_name' in variable_data: - self.model.connect(f'pre_mission.{external_subsystem.name}.{bus_variable}', - f'post_mission.{external_subsystem.name}.{variable_data["post_mission_name"]}') + self.model.connect( + f'pre_mission.{external_subsystem.name}.{bus_variable}', + f'post_mission.{external_subsystem.name}.{variable_data["post_mission_name"]}' + ) def setup(self, **kwargs): """ @@ -2067,11 +2129,14 @@ def set_initial_guesses(self, parent_prob=None, parent_prefix=""): # Grab the trajectory object from the model if self.analysis_scheme is AnalysisScheme.SHOOTING: if self.problem_type is ProblemType.SIZING: - setvalprob.set_val(parent_prefix+Mission.Summary.GROSS_MASS, + setvalprob.set_val(parent_prefix + Mission.Summary.GROSS_MASS, self.get_val(Mission.Design.GROSS_MASS)) - setvalprob.set_val(parent_prefix+"traj.SGMClimb_"+Dynamic.Mission.ALTITUDE + - "_trigger", val=self.cruise_alt, units="ft") + setvalprob.set_val(parent_prefix + + "traj.SGMClimb_" + Dynamic.Mission.ALTITUDE + "_trigger", + val=self.cruise_alt, + units="ft", + ) return @@ -2080,7 +2145,8 @@ def set_initial_guesses(self, parent_prob=None, parent_prefix=""): # Determine which phases to loop over, fetching them from the trajectory phase_items = traj._phases.items() - # Loop over each phase and set initial guesses for the state and control variables + # Loop over each phase and set initial guesses for the state and control + # variables for idx, (phase_name, phase) in enumerate(phase_items): if self.mission_method is SOLVED_2DOF: self.phase_objects[idx].apply_initial_guesses(self, 'traj', phase) @@ -2102,13 +2168,20 @@ def set_initial_guesses(self, parent_prob=None, parent_prefix=""): if 'mass' == guess_key: # Set initial and duration mass for the analytic cruise phase. # Note we are integrating over mass, not time for this phase. - setvalprob.set_val(parent_prefix+f'traj.{phase_name}.t_initial', - val[0], units=units) - setvalprob.set_val(parent_prefix+f'traj.{phase_name}.t_duration', - val[1], units=units) + setvalprob.set_val( + parent_prefix + + f'traj.{phase_name}.t_initial', + val[0], + units=units) + setvalprob.set_val( + parent_prefix + + f'traj.{phase_name}.t_duration', + val[1], + units=units) else: - # Otherwise, set the value of the parameter in the trajectory phase + # Otherwise, set the value of the parameter in the trajectory + # phase setvalprob.set_val( parent_prefix + f'traj.{phase_name}.parameters:{guess_key}', val, units=units) @@ -2157,13 +2230,15 @@ def _process_guess_var(self, val, key, phase): # Check if the key indicates a control or state variable if "controls:" in key or "states:" in key: - # If so, strip the first part of the key to match the variable name in phase + # If so, strip the first part of the key to match the variable name + # in phase stripped_key = ":".join(key.split(":")[1:]) # Interpolate the initial guess values across the phase's domain val = phase.interp(stripped_key, xs=xs, ys=val) else: - # If not a control or state variable, interpolate the initial guess values directly + # If not a control or state variable, interpolate the initial guess + # values directly val = phase.interp(key, xs=xs, ys=val) # Return the processed guess value(s) @@ -2208,7 +2283,7 @@ def _add_subsystem_guesses(self, phase_name, phase, setvalprob, parent_prefix): # Set the initial guess in the problem setvalprob.set_val( - parent_prefix+f'traj.{phase_name}.{path_string}:{key}', **val) + parent_prefix + f'traj.{phase_name}.{path_string}:{key}', **val) def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): """ @@ -2227,7 +2302,8 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): guesses : dict A dictionary containing the initial guesses for the phase. """ - # If using the GASP model, set initial guesses for the rotation mass and flight duration + # If using the GASP model, set initial guesses for the rotation mass and + # flight duration if self.mission_method is TWO_DEGREES_OF_FREEDOM: rotation_mass = self.initialization_guesses['rotation_mass'] flight_duration = self.initialization_guesses['flight_duration'] @@ -2237,15 +2313,22 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): state_keys = ["mass", Dynamic.Mission.DISTANCE] else: control_keys = ["velocity_rate", "throttle"] - state_keys = ["altitude", "mass", Dynamic.Mission.DISTANCE, - Dynamic.Mission.VELOCITY, "flight_path_angle", "alpha"] + state_keys = [ + "altitude", + "mass", + Dynamic.Mission.DISTANCE, + Dynamic.Mission.VELOCITY, + "flight_path_angle", + "alpha", + ] if self.mission_method is TWO_DEGREES_OF_FREEDOM and phase_name == 'ascent': # Alpha is a control for ascent. control_keys.append('alpha') prob_keys = ["tau_gear", "tau_flaps"] - # for the simple mission method, use the provided initial and final mach and altitude values from phase_info + # for the simple mission method, use the provided initial and final mach + # and altitude values from phase_info if self.mission_method in (HEIGHT_ENERGY, SOLVED_2DOF): initial_altitude = wrapped_convert_units( self.phase_info[phase_name]['user_options']['initial_altitude'], 'ft') @@ -2258,7 +2341,8 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): guesses["altitude"] = ([initial_altitude, final_altitude], 'ft') if self.mission_method is HEIGHT_ENERGY: - # if time not in initial guesses, set it to the average of the initial_bounds and the duration_bounds + # if time not in initial guesses, set it to the average of the + # initial_bounds and the duration_bounds if 'time' not in guesses: initial_bounds = wrapped_convert_units( self.phase_info[phase_name]['user_options']['initial_bounds'], 's') @@ -2267,16 +2351,19 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): guesses["time"] = ([np.mean(initial_bounds[0]), np.mean( duration_bounds[0])], 's') - # if time not in initial guesses, set it to the average of the initial_bounds and the duration_bounds + # if time not in initial guesses, set it to the average of the + # initial_bounds and the duration_bounds if 'time' not in guesses: initial_bounds = self.phase_info[phase_name]['user_options'][ 'initial_bounds'] duration_bounds = self.phase_info[phase_name]['user_options'][ 'duration_bounds'] - # Add a check for the initial and duration bounds, raise an error if they are not consistent + # Add a check for the initial and duration bounds, raise an error if they + # are not consistent if initial_bounds[1] != duration_bounds[1]: raise ValueError( - f"Initial and duration bounds for {phase_name} are not consistent.") + f"Initial and duration bounds for {phase_name} are not consistent." + ) guesses["time"] = ([np.mean(initial_bounds[0]), np.mean( duration_bounds[0])], initial_bounds[1]) @@ -2285,9 +2372,9 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): # Set initial guess for time variables if 'time' == guess_key and self.mission_method is not SOLVED_2DOF: - setvalprob.set_val(parent_prefix+f'traj.{phase_name}.t_initial', + setvalprob.set_val(parent_prefix + f'traj.{phase_name}.t_initial', val[0], units=units) - setvalprob.set_val(parent_prefix+f'traj.{phase_name}.t_duration', + setvalprob.set_val(parent_prefix + f'traj.{phase_name}.t_duration', val[1], units=units) else: @@ -2325,16 +2412,21 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): _process_guess_var(val, guess_key, phase), units=units) elif guess_key in prob_keys: - setvalprob.set_val(parent_prefix+guess_key, val, units=units) + setvalprob.set_val(parent_prefix + guess_key, val, units=units) elif ":" in guess_key: - setvalprob.set_val(parent_prefix + - f'traj.{phase_name}.{guess_key}', self._process_guess_var( - val, guess_key, phase), - units=units) + setvalprob.set_val( + parent_prefix + + f'traj.{phase_name}.{guess_key}', + self._process_guess_var( + val, + guess_key, + phase), + units=units) else: # raise error if the guess key is not recognized raise ValueError( - f"Initial guess key {guess_key} in {phase_name} is not recognized.") + f"Initial guess key {guess_key} in {phase_name} is not recognized." + ) if self.mission_method is SOLVED_2DOF: return @@ -2360,31 +2452,33 @@ def _add_guesses(self, phase_name, phase, guesses, setvalprob, parent_prefix): mass_guess = self.aviary_inputs.get_val( Mission.Design.GROSS_MASS, units='lbm') # Set the mass guess as the initial value for the mass state variable - setvalprob.set_val(parent_prefix+f'traj.{phase_name}.states:mass', + setvalprob.set_val(parent_prefix + f'traj.{phase_name}.states:mass', mass_guess, units='lbm') if 'time' not in guesses: # Determine initial time and duration guesses depending on the phase name if 'desc1' == base_phase: - t_initial = flight_duration*.9 - t_duration = flight_duration*.04 + t_initial = flight_duration * .9 + t_duration = flight_duration * .04 elif 'desc2' in base_phase: - t_initial = flight_duration*.94 + t_initial = flight_duration * .94 t_duration = 5000 - # Set the time guesses as the initial values for the time-related trajectory variables - setvalprob.set_val(parent_prefix+f"traj.{phase_name}.t_initial", + # Set the time guesses as the initial values for the time-related + # trajectory variables + setvalprob.set_val(parent_prefix + f"traj.{phase_name}.t_initial", t_initial, units='s') - setvalprob.set_val(parent_prefix+f"traj.{phase_name}.t_duration", + setvalprob.set_val(parent_prefix + f"traj.{phase_name}.t_duration", t_duration, units='s') if self.mission_method is TWO_DEGREES_OF_FREEDOM: if 'distance' not in guesses: # Determine initial distance guesses depending on the phase name if 'desc1' == base_phase: - ys = [self.target_range*.97, self.target_range*.99] + ys = [self.target_range * .97, self.target_range * .99] elif 'desc2' in base_phase: - ys = [self.target_range*.99, self.target_range] - # Set the distance guesses as the initial values for the distance state variable + ys = [self.target_range * .99, self.target_range] + # Set the distance guesses as the initial values for the distance state + # variable setvalprob.set_val(parent_prefix + f"traj.{phase_name}.states:distance", phase.interp( Dynamic.Mission.DISTANCE, ys=ys) @@ -2480,8 +2574,13 @@ def alternate_mission(self, run_mission=True, mission_mass = self.get_val(Mission.Design.GROSS_MASS) optimizer = self.driver.options["optimizer"] - prob_alternate = _load_off_design(json_filename, ProblemType.ALTERNATE, - phase_info, payload_mass, design_range, mission_mass) + prob_alternate = _load_off_design( + json_filename, + ProblemType.ALTERNATE, + phase_info, + payload_mass, + design_range, + mission_mass) prob_alternate.check_and_preprocess_inputs() prob_alternate.add_pre_mission_systems() @@ -2571,7 +2670,8 @@ def save_sizing_to_json(self, json_filename='sizing_problem.json'): (name, (value, units)) = data type_value = type(value) - # Get the gross mass value from the sizing problem and add it to input list + # Get the gross mass value from the sizing problem and add it to input + # list if name == Mission.Summary.GROSS_MASS or name == Mission.Design.GROSS_MASS: Mission_Summary_GROSS_MASS_val = self.get_val( Mission.Summary.GROSS_MASS, units=units) @@ -2723,8 +2823,7 @@ def _add_post_mission_takeoff_systems(self): 'optimize_altitude', False): # Similar steps for altitude difference alt_diff_comp = om.ExecComp( - 'altitude_resid_for_connecting_takeoff = final_altitude - initial_altitude', - units='ft') + 'altitude_resid_for_connecting_takeoff = final_altitude - initial_altitude', units='ft') self.model.add_subsystem('alt_diff_comp', alt_diff_comp) self.model.connect(Mission.Takeoff.FINAL_ALTITUDE, @@ -2742,7 +2841,7 @@ def _add_two_dof_landing_systems(self): LandingSegment( **(self.ode_args)), promotes_inputs=['aircraft:*', 'mission:*', - (Dynamic.Mission.MASS, Mission.Landing.TOUCHDOWN_MASS)], + (Dynamic.Vehicle.MASS, Mission.Landing.TOUCHDOWN_MASS)], promotes_outputs=['mission:*'], ) self.model.connect( @@ -2824,11 +2923,15 @@ def _add_fuel_reserve_component(self, post_mission=True, if RESERVE_FUEL_FRACTION != 0: reserve_fuel_frac = om.ExecComp( 'reserve_fuel_frac_mass = reserve_fuel_fraction * (takeoff_mass - final_mass)', - reserve_fuel_frac_mass={"units": "lbm"}, - reserve_fuel_fraction={"units": "unitless", - "val": RESERVE_FUEL_FRACTION}, - final_mass={"units": "lbm"}, - takeoff_mass={"units": "lbm"}) + reserve_fuel_frac_mass={ + "units": "lbm"}, + reserve_fuel_fraction={ + "units": "unitless", + "val": RESERVE_FUEL_FRACTION}, + final_mass={ + "units": "lbm"}, + takeoff_mass={ + "units": "lbm"}) reserve_calc_location.add_subsystem( "reserve_fuel_frac", reserve_fuel_frac, @@ -2840,22 +2943,25 @@ def _add_fuel_reserve_component(self, post_mission=True, RESERVE_FUEL_ADDITIONAL = self.aviary_inputs.get_val( Aircraft.Design.RESERVE_FUEL_ADDITIONAL, units='lbm') - reserve_fuel = om.ExecComp('reserve_fuel = reserve_fuel_frac_mass + reserve_fuel_additional + reserve_fuel_burned', - reserve_fuel={"units": "lbm", 'shape': 1}, - reserve_fuel_frac_mass={"units": "lbm", "val": 0}, - reserve_fuel_additional={ - "units": "lbm", "val": RESERVE_FUEL_ADDITIONAL}, - reserve_fuel_burned={"units": "lbm", "val": 0}) - - reserve_calc_location.add_subsystem("reserve_fuel", reserve_fuel, - promotes_inputs=["reserve_fuel_frac_mass", - ("reserve_fuel_additional", - Aircraft.Design.RESERVE_FUEL_ADDITIONAL), - ("reserve_fuel_burned", - Mission.Summary.RESERVE_FUEL_BURNED)], - promotes_outputs=[ - ("reserve_fuel", reserves_name)] - ) + reserve_fuel = om.ExecComp( + 'reserve_fuel = reserve_fuel_frac_mass + reserve_fuel_additional + reserve_fuel_burned', + reserve_fuel={"units": "lbm", 'shape': 1}, + reserve_fuel_frac_mass={"units": "lbm", "val": 0}, + reserve_fuel_additional={"units": "lbm", "val": RESERVE_FUEL_ADDITIONAL}, + reserve_fuel_burned={"units": "lbm", "val": 0}) + + reserve_calc_location.add_subsystem( + "reserve_fuel", + reserve_fuel, + promotes_inputs=[ + "reserve_fuel_frac_mass", + ("reserve_fuel_additional", + Aircraft.Design.RESERVE_FUEL_ADDITIONAL), + ("reserve_fuel_burned", + Mission.Summary.RESERVE_FUEL_BURNED)], + promotes_outputs=[ + ("reserve_fuel", + reserves_name)]) def _read_sizing_json(aviary_problem, json_filename): @@ -2928,14 +3034,34 @@ def _read_sizing_json(aviary_problem, json_filename): aviary_problem.aviary_inputs = set_value( var_name, var_values, aviary_problem.aviary_inputs, units=var_units, is_array=is_array, meta_data=BaseMetaData) - except: + except BaseException: # Print helpful error - print("FAILURE: list_num = ", counter, "Input String = ", inputs, - "Attempted to set_value(", var_name, ",", var_values, ",", var_units, ")") + print( + "FAILURE: list_num = ", + counter, + "Input String = ", + inputs, + "Attempted to set_value(", + var_name, + ",", + var_values, + ",", + var_units, + ")") else: # Not in the MetaData - print("Name not found in MetaData: list_num =", counter, "Input String =", - inputs, "Attempted set_value(", var_name, ",", var_values, ",", var_units, ")") + print( + "Name not found in MetaData: list_num =", + counter, + "Input String =", + inputs, + "Attempted set_value(", + var_name, + ",", + var_values, + ",", + var_units, + ")") counter = counter + 1 # increment index tracker return aviary_problem diff --git a/aviary/interface/test/test_height_energy_mission.py b/aviary/interface/test/test_height_energy_mission.py index 1c257c23c..d33bfd4cc 100644 --- a/aviary/interface/test/test_height_energy_mission.py +++ b/aviary/interface/test/test_height_energy_mission.py @@ -180,7 +180,7 @@ def test_mission_optimize_altitude_and_mach(self): modified_phase_info[phase]["user_options"]["optimize_altitude"] = True modified_phase_info[phase]["user_options"]["optimize_mach"] = True modified_phase_info['climb']['user_options']['constraints'] = { - Dynamic.Mission.THROTTLE: { + Dynamic.Vehicle.Propulsion.THROTTLE: { 'lower': 0.2, 'upper': 0.9, 'type': 'path', @@ -259,13 +259,13 @@ def test_support_constraint_aliases(self): modified_phase_info = deepcopy(self.phase_info) modified_phase_info['climb']['user_options']['constraints'] = { 'throttle_1': { - 'target': Dynamic.Mission.THROTTLE, + 'target': Dynamic.Vehicle.Propulsion.THROTTLE, 'equals': 0.2, 'loc': 'initial', 'type': 'boundary', }, 'throttle_2': { - 'target': Dynamic.Mission.THROTTLE, + 'target': Dynamic.Vehicle.Propulsion.THROTTLE, 'equals': 0.8, 'loc': 'final', 'type': 'boundary', diff --git a/aviary/mission/flight_phase_builder.py b/aviary/mission/flight_phase_builder.py index 874da3dd0..d744efc20 100644 --- a/aviary/mission/flight_phase_builder.py +++ b/aviary/mission/flight_phase_builder.py @@ -105,8 +105,8 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO ############## # TODO: critically think about how we should handle fix_initial and input_initial defaults. # In keeping with Dymos standards, the default should be False instead of True. - input_initial_mass = get_initial(input_initial, Dynamic.Mission.MASS) - fix_initial_mass = get_initial(fix_initial, Dynamic.Mission.MASS, True) + input_initial_mass = get_initial(input_initial, Dynamic.Vehicle.MASS) + fix_initial_mass = get_initial(fix_initial, Dynamic.Vehicle.MASS, True) # Experiment: use a constraint for mass instead of connected initial. # This is due to some problems in mpi. @@ -118,15 +118,15 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO input_initial_mass = False if phase_type is EquationsOfMotion.HEIGHT_ENERGY: - rate_source = Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL + rate_source = Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL else: rate_source = "dmass_dr" phase.add_state( - Dynamic.Mission.MASS, fix_initial=fix_initial_mass, fix_final=False, + Dynamic.Vehicle.MASS, fix_initial=fix_initial_mass, fix_final=False, lower=0.0, ref=1e4, defect_ref=1e6, units='kg', rate_source=rate_source, - targets=Dynamic.Mission.MASS, + targets=Dynamic.Vehicle.MASS, input_initial=input_initial_mass, ) @@ -149,23 +149,30 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO # Add Controls # ################ if phase_type is EquationsOfMotion.HEIGHT_ENERGY: - rate_targets = [Dynamic.Mission.MACH_RATE] + rate_targets = [Dynamic.Atmosphere.MACH_RATE] else: rate_targets = ['dmach_dr'] if use_polynomial_control: phase.add_polynomial_control( - Dynamic.Mission.MACH, - targets=Dynamic.Mission.MACH, units=mach_bounds[1], - opt=optimize_mach, lower=mach_bounds[0][0], upper=mach_bounds[0][1], + Dynamic.Atmosphere.MACH, + targets=Dynamic.Atmosphere.MACH, + units=mach_bounds[1], + opt=optimize_mach, + lower=mach_bounds[0][0], + upper=mach_bounds[0][1], rate_targets=rate_targets, - order=polynomial_control_order, ref=0.5, + order=polynomial_control_order, + ref=0.5, ) else: phase.add_control( - Dynamic.Mission.MACH, - targets=Dynamic.Mission.MACH, units=mach_bounds[1], - opt=optimize_mach, lower=mach_bounds[0][0], upper=mach_bounds[0][1], + Dynamic.Atmosphere.MACH, + targets=Dynamic.Atmosphere.MACH, + units=mach_bounds[1], + opt=optimize_mach, + lower=mach_bounds[0][0], + upper=mach_bounds[0][1], rate_targets=rate_targets, ref=0.5, ) @@ -211,25 +218,39 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO ground_roll = user_options.get_val('ground_roll') if ground_roll: - phase.add_polynomial_control(Dynamic.Mission.ALTITUDE, - order=1, val=0, opt=False, - fix_initial=fix_initial, - rate_targets=['dh_dr'], rate2_targets=['d2h_dr2']) + phase.add_polynomial_control( + Dynamic.Mission.ALTITUDE, + order=1, + val=0, + opt=False, + fix_initial=fix_initial, + rate_targets=['dh_dr'], + rate2_targets=['d2h_dr2'], + ) else: if use_polynomial_control: phase.add_polynomial_control( Dynamic.Mission.ALTITUDE, - targets=Dynamic.Mission.ALTITUDE, units=altitude_bounds[1], - opt=optimize_altitude, lower=altitude_bounds[0][0], upper=altitude_bounds[0][1], - rate_targets=rate_targets, rate2_targets=rate2_targets, - order=polynomial_control_order, ref=altitude_bounds[0][1], + targets=Dynamic.Mission.ALTITUDE, + units=altitude_bounds[1], + opt=optimize_altitude, + lower=altitude_bounds[0][0], + upper=altitude_bounds[0][1], + rate_targets=rate_targets, + rate2_targets=rate2_targets, + order=polynomial_control_order, + ref=altitude_bounds[0][1], ) else: phase.add_control( Dynamic.Mission.ALTITUDE, - targets=Dynamic.Mission.ALTITUDE, units=altitude_bounds[1], - opt=optimize_altitude, lower=altitude_bounds[0][0], upper=altitude_bounds[0][1], - rate_targets=rate_targets, rate2_targets=rate2_targets, + targets=Dynamic.Mission.ALTITUDE, + units=altitude_bounds[1], + opt=optimize_altitude, + lower=altitude_bounds[0][0], + upper=altitude_bounds[0][1], + rate_targets=rate_targets, + rate2_targets=rate2_targets, ref=altitude_bounds[0][1], ) @@ -237,46 +258,53 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO # Add Timeseries # ################## phase.add_timeseries_output( - Dynamic.Mission.MACH, output_name=Dynamic.Mission.MACH, units='unitless' + Dynamic.Atmosphere.MACH, + output_name=Dynamic.Atmosphere.MACH, + units='unitless', ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, - output_name=Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, units='m/s' + output_name=Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + units='m/s', ) phase.add_timeseries_output( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - output_name=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h' + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + units='lbm/h', ) phase.add_timeseries_output( - Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, - output_name=Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, units='kW' + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, + units='kW', ) phase.add_timeseries_output( Dynamic.Mission.ALTITUDE_RATE, - output_name=Dynamic.Mission.ALTITUDE_RATE, units='ft/s' + output_name=Dynamic.Mission.ALTITUDE_RATE, + units='ft/s', ) phase.add_timeseries_output( - Dynamic.Mission.THROTTLE, - output_name=Dynamic.Mission.THROTTLE, units='unitless' + Dynamic.Vehicle.Propulsion.THROTTLE, + output_name=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless' ) phase.add_timeseries_output( Dynamic.Mission.VELOCITY, - output_name=Dynamic.Mission.VELOCITY, units='m/s' + output_name=Dynamic.Mission.VELOCITY, + units='m/s', ) phase.add_timeseries_output(Dynamic.Mission.ALTITUDE) @@ -293,24 +321,48 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO ################### # Add Constraints # ################### - if optimize_mach and fix_initial and not Dynamic.Mission.MACH in constraints: + if optimize_mach and fix_initial and not Dynamic.Atmosphere.MACH in constraints: phase.add_boundary_constraint( - Dynamic.Mission.MACH, loc='initial', equals=initial_mach, + Dynamic.Atmosphere.MACH, + loc='initial', + equals=initial_mach, ) - if optimize_mach and constrain_final and not Dynamic.Mission.MACH in constraints: + if ( + optimize_mach + and constrain_final + and not Dynamic.Atmosphere.MACH in constraints + ): phase.add_boundary_constraint( - Dynamic.Mission.MACH, loc='final', equals=final_mach, + Dynamic.Atmosphere.MACH, + loc='final', + equals=final_mach, ) - if optimize_altitude and fix_initial and not Dynamic.Mission.ALTITUDE in constraints: + if ( + optimize_altitude + and fix_initial + and not Dynamic.Mission.ALTITUDE in constraints + ): phase.add_boundary_constraint( - Dynamic.Mission.ALTITUDE, loc='initial', equals=initial_altitude, units=altitude_bounds[1], ref=1.e4, + Dynamic.Mission.ALTITUDE, + loc='initial', + equals=initial_altitude, + units=altitude_bounds[1], + ref=1.0e4, ) - if optimize_altitude and constrain_final and not Dynamic.Mission.ALTITUDE in constraints: + if ( + optimize_altitude + and constrain_final + and not Dynamic.Mission.ALTITUDE in constraints + ): phase.add_boundary_constraint( - Dynamic.Mission.ALTITUDE, loc='final', equals=final_altitude, units=altitude_bounds[1], ref=1.e4, + Dynamic.Mission.ALTITUDE, + loc='final', + equals=final_altitude, + units=altitude_bounds[1], + ref=1.0e4, ) if no_descent and not Dynamic.Mission.ALTITUDE_RATE in constraints: @@ -322,23 +374,27 @@ def build_phase(self, aviary_options: AviaryValues = None, phase_type=EquationsO required_available_climb_rate, units = user_options.get_item( 'required_available_climb_rate') - if required_available_climb_rate is not None and not Dynamic.Mission.ALTITUDE_RATE_MAX in constraints: + if ( + required_available_climb_rate is not None + and not Dynamic.Mission.ALTITUDE_RATE_MAX in constraints + ): phase.add_path_constraint( Dynamic.Mission.ALTITUDE_RATE_MAX, - lower=required_available_climb_rate, units=units + lower=required_available_climb_rate, + units=units, ) - if not Dynamic.Mission.THROTTLE in constraints: + if not Dynamic.Vehicle.Propulsion.THROTTLE in constraints: if throttle_enforcement == 'boundary_constraint': phase.add_boundary_constraint( - Dynamic.Mission.THROTTLE, loc='initial', lower=0.0, upper=1.0, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, loc='initial', lower=0.0, upper=1.0, units='unitless', ) phase.add_boundary_constraint( - Dynamic.Mission.THROTTLE, loc='final', lower=0.0, upper=1.0, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, loc='final', lower=0.0, upper=1.0, units='unitless', ) elif throttle_enforcement == 'path_constraint': phase.add_path_constraint( - Dynamic.Mission.THROTTLE, lower=0.0, upper=1.0, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, lower=0.0, upper=1.0, units='unitless', ) self._add_user_defined_constraints(phase, constraints) diff --git a/aviary/mission/flops_based/ode/landing_eom.py b/aviary/mission/flops_based/ode/landing_eom.py index f05f132ea..8da834de7 100644 --- a/aviary/mission/flops_based/ode/landing_eom.py +++ b/aviary/mission/flops_based/ode/landing_eom.py @@ -53,8 +53,13 @@ def setup(self): 'aviary_options': aviary_options} inputs = [ - Dynamic.Mission.MASS, Dynamic.Mission.LIFT, Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.DRAG, - 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE] + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + 'angle_of_attack', + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ] outputs = ['forces_horizontal', 'forces_vertical'] @@ -64,7 +69,7 @@ def setup(self): promotes_inputs=inputs, promotes_outputs=outputs) - inputs = ['forces_horizontal', 'forces_vertical', Dynamic.Mission.MASS] + inputs = ['forces_horizontal', 'forces_vertical', Dynamic.Vehicle.MASS] outputs = ['acceleration_horizontal', 'acceleration_vertical'] self.add_subsystem( @@ -74,10 +79,15 @@ def setup(self): promotes_outputs=outputs) inputs = [ - 'acceleration_horizontal', 'acceleration_vertical', - Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE] + 'acceleration_horizontal', + 'acceleration_vertical', + Dynamic.Mission.DISTANCE_RATE, + Dynamic.Mission.ALTITUDE_RATE, + ] - outputs = [Dynamic.Mission.VELOCITY_RATE,] + outputs = [ + Dynamic.Mission.VELOCITY_RATE, + ] self.add_subsystem( 'velocity_rate', @@ -86,8 +96,11 @@ def setup(self): promotes_outputs=outputs) inputs = [ - Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE, - 'acceleration_horizontal', 'acceleration_vertical'] + Dynamic.Mission.DISTANCE_RATE, + Dynamic.Mission.ALTITUDE_RATE, + 'acceleration_horizontal', + 'acceleration_vertical', + ] outputs = [Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE] @@ -97,8 +110,12 @@ def setup(self): promotes_outputs=outputs) inputs = [ - Dynamic.Mission.MASS, Dynamic.Mission.LIFT, Dynamic.Mission.DRAG, - 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE] + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.DRAG, + 'angle_of_attack', + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ] outputs = ['forces_perpendicular', 'required_thrust'] @@ -144,14 +161,15 @@ def setup(self): nn = options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.MASS, val=np.ones(nn), units='kg') - add_aviary_input(self, Dynamic.Mission.LIFT, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.DRAG, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') + add_aviary_input(self, Dynamic.Vehicle.LIFT, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.DRAG, val=np.ones(nn), units='N') self.add_input('angle_of_attack', val=np.zeros(nn), units='rad') - add_aviary_input(self, Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units='rad') + add_aviary_input( + self, Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units='rad' + ) self.add_output( 'forces_perpendicular', val=np.zeros(nn), units='N', @@ -180,9 +198,9 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') # total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + drag = inputs[Dynamic.Vehicle.DRAG] weight = mass * grav_metric @@ -218,9 +236,9 @@ def compute_partials(self, inputs, J, discrete_inputs=None): t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') # total_num_engines = aviary_options.get_val(Aircraft.Propulsion.TOTAL_NUM_ENGINES) - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + drag = inputs[Dynamic.Vehicle.DRAG] weight = mass * grav_metric @@ -244,20 +262,20 @@ def compute_partials(self, inputs, J, discrete_inputs=None): f_h = -grav_metric * s_gamma / c_angle f_v = grav_metric * c_gamma / s_angle - J[forces_key, Dynamic.Mission.MASS] = f_h - f_v - J[thrust_key, Dynamic.Mission.MASS] = (f_h + f_v) / (2.) + J[forces_key, Dynamic.Vehicle.MASS] = f_h - f_v + J[thrust_key, Dynamic.Vehicle.MASS] = (f_h + f_v) / (2.) f_h = 0. f_v = -1. / s_angle - J[forces_key, Dynamic.Mission.LIFT] = -f_v - J[thrust_key, Dynamic.Mission.LIFT] = f_v / (2.) + J[forces_key, Dynamic.Vehicle.LIFT] = -f_v + J[thrust_key, Dynamic.Vehicle.LIFT] = f_v / (2.) f_h = 1. / c_angle f_v = 0. - J[forces_key, Dynamic.Mission.DRAG] = f_h - J[thrust_key, Dynamic.Mission.DRAG] = f_h / (2.) + J[forces_key, Dynamic.Vehicle.DRAG] = f_h + J[thrust_key, Dynamic.Vehicle.DRAG] = f_h / (2.) # ddx(1 / cos(x)) = sec(x) * tan(x) = tan(x) / cos(x) # ddx(1 / sin(x)) = -csc(x) * cot(x) = -1 / (sin(x) * tan(x)) @@ -272,8 +290,8 @@ def compute_partials(self, inputs, J, discrete_inputs=None): f_h = -weight * c_gamma / c_angle f_v = -weight * s_gamma / s_angle - J[forces_key, Dynamic.Mission.FLIGHT_PATH_ANGLE] = - f_h + f_v - J[thrust_key, Dynamic.Mission.FLIGHT_PATH_ANGLE] = -(f_h + f_v) / (2.) + J[forces_key, Dynamic.Mission.FLIGHT_PATH_ANGLE] = -f_h + f_v + J[thrust_key, Dynamic.Mission.FLIGHT_PATH_ANGLE] = -(f_h + f_v) / (2.0) class FlareSumForces(om.ExplicitComponent): @@ -296,15 +314,17 @@ def setup(self): nn = options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.MASS, val=np.ones(nn), units='kg') - add_aviary_input(self, Dynamic.Mission.LIFT, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.THRUST_TOTAL, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.DRAG, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') + add_aviary_input(self, Dynamic.Vehicle.LIFT, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.DRAG, val=np.ones(nn), units='N') self.add_input('angle_of_attack', val=np.zeros(nn), units='rad') - add_aviary_input(self, Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units='rad') + add_aviary_input( + self, Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units='rad' + ) self.add_output( 'forces_horizontal', val=np.zeros(nn), units='N', @@ -321,15 +341,19 @@ def setup_partials(self): rows_cols = np.arange(nn) - self.declare_partials('forces_horizontal', Dynamic.Mission.MASS, dependent=False) + self.declare_partials('forces_horizontal', Dynamic.Vehicle.MASS, dependent=False) self.declare_partials( - 'forces_vertical', Dynamic.Mission.MASS, val=-grav_metric, rows=rows_cols, + 'forces_vertical', Dynamic.Vehicle.MASS, val=-grav_metric, rows=rows_cols, cols=rows_cols) wrt = [ - Dynamic.Mission.LIFT, Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.DRAG, 'angle_of_attack', - Dynamic.Mission.FLIGHT_PATH_ANGLE] + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + 'angle_of_attack', + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ] self.declare_partials('*', wrt, rows=rows_cols, cols=rows_cols) @@ -341,10 +365,10 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] alpha = inputs['angle_of_attack'] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] @@ -379,10 +403,10 @@ def compute_partials(self, inputs, J, discrete_inputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] alpha = inputs['angle_of_attack'] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] @@ -399,16 +423,16 @@ def compute_partials(self, inputs, J, discrete_inputs=None): s_gamma = np.sin(gamma) f_h_key = 'forces_horizontal' - J[f_h_key, Dynamic.Mission.LIFT] = -s_gamma + J[f_h_key, Dynamic.Vehicle.LIFT] = -s_gamma f_v_key = 'forces_vertical' - J[f_v_key, Dynamic.Mission.LIFT] = c_gamma + J[f_v_key, Dynamic.Vehicle.LIFT] = c_gamma - J[f_h_key, Dynamic.Mission.THRUST_TOTAL] = -c_angle - J[f_v_key, Dynamic.Mission.THRUST_TOTAL] = s_angle + J[f_h_key, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = -c_angle + J[f_v_key, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = s_angle - J[f_h_key, Dynamic.Mission.DRAG] = c_gamma - J[f_v_key, Dynamic.Mission.DRAG] = s_gamma + J[f_h_key, Dynamic.Vehicle.DRAG] = c_gamma + J[f_v_key, Dynamic.Vehicle.DRAG] = s_gamma J[f_h_key, 'angle_of_attack'] = thrust * s_angle J[f_v_key, 'angle_of_attack'] = thrust * c_angle @@ -441,10 +465,11 @@ def setup(self): nn = options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.MASS, val=np.ones(nn), units='kg') - add_aviary_input(self, Dynamic.Mission.LIFT, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.THRUST_TOTAL, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.DRAG, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') + add_aviary_input(self, Dynamic.Vehicle.LIFT, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.DRAG, val=np.ones(nn), units='N') self.add_output( 'forces_horizontal', val=np.zeros(nn), units='N', @@ -462,25 +487,25 @@ def setup_partials(self): rows_cols = np.arange(nn) self.declare_partials( - 'forces_vertical', Dynamic.Mission.MASS, val=-grav_metric, rows=rows_cols, + 'forces_vertical', Dynamic.Vehicle.MASS, val=-grav_metric, rows=rows_cols, cols=rows_cols) self.declare_partials( - 'forces_vertical', Dynamic.Mission.LIFT, val=1., rows=rows_cols, cols=rows_cols) + 'forces_vertical', Dynamic.Vehicle.LIFT, val=1., rows=rows_cols, cols=rows_cols) self.declare_partials( - 'forces_vertical', [Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.DRAG], dependent=False) + 'forces_vertical', [Dynamic.Vehicle.Propulsion.THRUST_TOTAL, Dynamic.Vehicle.DRAG], dependent=False) self.declare_partials( - 'forces_horizontal', [Dynamic.Mission.MASS, Dynamic.Mission.LIFT], rows=rows_cols, + 'forces_horizontal', [Dynamic.Vehicle.MASS, Dynamic.Vehicle.LIFT], rows=rows_cols, cols=rows_cols) self.declare_partials( - 'forces_horizontal', Dynamic.Mission.THRUST_TOTAL, val=-1., rows=rows_cols, + 'forces_horizontal', Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=-1., rows=rows_cols, cols=rows_cols) self.declare_partials( - 'forces_horizontal', Dynamic.Mission.DRAG, val=1., rows=rows_cols, cols=rows_cols) + 'forces_horizontal', Dynamic.Vehicle.DRAG, val=1., rows=rows_cols, cols=rows_cols) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): options = self.options @@ -488,10 +513,10 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): nn = options['num_nodes'] friction_coefficient = options['friction_coefficient'] - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] weight = mass * grav_metric @@ -511,8 +536,8 @@ def compute_partials(self, inputs, J, discrete_inputs=None): nn = options['num_nodes'] friction_coefficient = options['friction_coefficient'] - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] weight = mass * grav_metric @@ -522,8 +547,8 @@ def compute_partials(self, inputs, J, discrete_inputs=None): friction = np.zeros(nn) friction[idx_sup] = friction_coefficient * grav_metric - J['forces_horizontal', Dynamic.Mission.MASS] = friction + J['forces_horizontal', Dynamic.Vehicle.MASS] = friction friction = np.zeros(nn) friction[idx_sup] = -friction_coefficient - J['forces_horizontal', Dynamic.Mission.LIFT] = friction + J['forces_horizontal', Dynamic.Vehicle.LIFT] = friction diff --git a/aviary/mission/flops_based/ode/landing_ode.py b/aviary/mission/flops_based/ode/landing_ode.py index cad16438a..4945a0455 100644 --- a/aviary/mission/flops_based/ode/landing_ode.py +++ b/aviary/mission/flops_based/ode/landing_ode.py @@ -109,7 +109,7 @@ def setup(self): StallSpeed(num_nodes=nn), promotes_inputs=[ "mass", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, ('area', Aircraft.Wing.AREA), ("lift_coefficient_max", Mission.Landing.LIFT_COEFFICIENT_MAX), ], @@ -170,10 +170,10 @@ def setup(self): promotes_inputs=[ Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, 'angle_of_attack', 'angle_of_attack_rate', Mission.Landing.FLARE_RATE, diff --git a/aviary/mission/flops_based/ode/mission_EOM.py b/aviary/mission/flops_based/ode/mission_EOM.py index 1bb2bf10b..04b7706e2 100644 --- a/aviary/mission/flops_based/ode/mission_EOM.py +++ b/aviary/mission/flops_based/ode/mission_EOM.py @@ -20,37 +20,57 @@ def setup(self): self.add_subsystem( name='required_thrust', subsys=RequiredThrust(num_nodes=nn), - promotes_inputs=[Dynamic.Mission.DRAG, - Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY, - Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.MASS], - promotes_outputs=['thrust_required']) + promotes_inputs=[ + Dynamic.Vehicle.DRAG, + Dynamic.Mission.ALTITUDE_RATE, + Dynamic.Mission.VELOCITY, + Dynamic.Mission.VELOCITY_RATE, + Dynamic.Vehicle.MASS, + ], + promotes_outputs=['thrust_required'], + ) self.add_subsystem( name='groundspeed', subsys=RangeRate(num_nodes=nn), promotes_inputs=[ Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY], - promotes_outputs=[Dynamic.Mission.DISTANCE_RATE]) + Dynamic.Mission.VELOCITY, + ], + promotes_outputs=[Dynamic.Mission.DISTANCE_RATE], + ) self.add_subsystem( name='excess_specific_power', subsys=SpecificEnergyRate(num_nodes=nn), promotes_inputs=[ - (Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.THRUST_MAX_TOTAL), + ( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + ), Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, Dynamic.Mission.DRAG], - promotes_outputs=[(Dynamic.Mission.SPECIFIC_ENERGY_RATE, Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS)]) + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.DRAG, + ], + promotes_outputs=[ + ( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + ) + ], + ) self.add_subsystem( name=Dynamic.Mission.ALTITUDE_RATE_MAX, - subsys=AltitudeRate( - num_nodes=nn), + subsys=AltitudeRate(num_nodes=nn), promotes_inputs=[ - (Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS), + ( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + ), Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.VELOCITY], + Dynamic.Mission.VELOCITY, + ], promotes_outputs=[ - (Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.ALTITUDE_RATE_MAX)]) + (Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.ALTITUDE_RATE_MAX) + ], + ) diff --git a/aviary/mission/flops_based/ode/mission_ODE.py b/aviary/mission/flops_based/ode/mission_ODE.py index 4eb8fe858..bc1c4832e 100644 --- a/aviary/mission/flops_based/ode/mission_ODE.py +++ b/aviary/mission/flops_based/ode/mission_ODE.py @@ -114,8 +114,8 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('mach_rate', Dynamic.Mission.MACH_RATE), - ('sos', Dynamic.Mission.SPEED_OF_SOUND), + ('mach_rate', Dynamic.Atmosphere.MACH_RATE), + ('sos', Dynamic.Atmosphere.SPEED_OF_SOUND), ], promotes_outputs=[('velocity_rate', Dynamic.Mission.VELOCITY_RATE)], ) @@ -190,9 +190,9 @@ def setup(self): subsys=MissionEOM(num_nodes=nn), promotes_inputs=[ Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.THRUST_MAX_TOTAL, - Dynamic.Mission.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + Dynamic.Vehicle.DRAG, Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY_RATE, ], @@ -217,7 +217,7 @@ def setup(self): units="unitless", val=np.ones((nn,)), lhs_name='thrust_required', - rhs_name=Dynamic.Mission.THRUST_TOTAL, + rhs_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, eq_units="lbf", normalize=False, res_ref=1.0e6, @@ -245,11 +245,11 @@ def setup(self): sub1.add_subsystem( name='throttle_balance', subsys=om.BalanceComp( - name=Dynamic.Mission.THROTTLE, + name=Dynamic.Vehicle.Propulsion.THROTTLE, units="unitless", val=np.ones((nn,)), lhs_name='thrust_required', - rhs_name=Dynamic.Mission.THRUST_TOTAL, + rhs_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, eq_units="lbf", normalize=False, lower=0.0 if options['throttle_enforcement'] == 'bounded' else None, @@ -260,10 +260,14 @@ def setup(self): promotes_outputs=['*'], ) - self.set_input_defaults(Dynamic.Mission.THROTTLE, val=1.0, units='unitless') + self.set_input_defaults( + Dynamic.Vehicle.Propulsion.THROTTLE, val=1.0, units='unitless' + ) - self.set_input_defaults(Dynamic.Mission.MACH, val=np.ones(nn), units='unitless') - self.set_input_defaults(Dynamic.Mission.MASS, val=np.ones(nn), units='kg') + self.set_input_defaults( + Dynamic.Atmosphere.MACH, val=np.ones(nn), units='unitless' + ) + self.set_input_defaults(Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') self.set_input_defaults(Dynamic.Mission.VELOCITY, val=np.ones(nn), units='m/s') self.set_input_defaults(Dynamic.Mission.ALTITUDE, val=np.ones(nn), units='m') self.set_input_defaults( @@ -290,7 +294,7 @@ def setup(self): initial_mass_residual_constraint, promotes_inputs=[ ('initial_mass', initial_mass_string), - ('mass', Dynamic.Mission.MASS), + ('mass', Dynamic.Vehicle.MASS), ], promotes_outputs=['initial_mass_residual'], ) diff --git a/aviary/mission/flops_based/ode/range_rate.py b/aviary/mission/flops_based/ode/range_rate.py index 12f4fcc0f..c1602c514 100644 --- a/aviary/mission/flops_based/ode/range_rate.py +++ b/aviary/mission/flops_based/ode/range_rate.py @@ -20,12 +20,14 @@ def setup(self): Dynamic.Mission.ALTITUDE_RATE, val=np.ones(nn), desc='climb rate', - units='m/s') + units='m/s', + ) self.add_input( Dynamic.Mission.VELOCITY, val=np.ones(nn), desc='current velocity', - units='m/s') + units='m/s', + ) self.add_output( Dynamic.Mission.DISTANCE_RATE, val=np.ones(nn), @@ -45,14 +47,19 @@ def compute(self, inputs, outputs): def setup_partials(self): arange = np.arange(self.options['num_nodes']) self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, [ - Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY], rows=arange, cols=arange) + Dynamic.Mission.DISTANCE_RATE, + [Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY], + rows=arange, + cols=arange, + ) def compute_partials(self, inputs, J): climb_rate = inputs[Dynamic.Mission.ALTITUDE_RATE] velocity = inputs[Dynamic.Mission.VELOCITY] - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE] = -climb_rate / \ - (velocity**2 - climb_rate**2)**0.5 - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = velocity / \ - (velocity**2 - climb_rate**2)**0.5 + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE] = ( + -climb_rate / (velocity**2 - climb_rate**2) ** 0.5 + ) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = ( + velocity / (velocity**2 - climb_rate**2) ** 0.5 + ) diff --git a/aviary/mission/flops_based/ode/required_thrust.py b/aviary/mission/flops_based/ode/required_thrust.py index af3c5ed62..440636c22 100644 --- a/aviary/mission/flops_based/ode/required_thrust.py +++ b/aviary/mission/flops_based/ode/required_thrust.py @@ -16,35 +16,50 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] - self.add_input(Dynamic.Mission.DRAG, val=np.zeros(nn), + self.add_input(Dynamic.Vehicle.DRAG, val=np.zeros(nn), units='N', desc='drag force') - self.add_input(Dynamic.Mission.ALTITUDE_RATE, val=np.zeros(nn), - units='m/s', desc='rate of change of altitude') - self.add_input(Dynamic.Mission.VELOCITY, val=np.zeros(nn), - units='m/s', desc=Dynamic.Mission.VELOCITY) - self.add_input(Dynamic.Mission.VELOCITY_RATE, val=np.zeros( - nn), units='m/s**2', desc='rate of change of velocity') - self.add_input(Dynamic.Mission.MASS, val=np.zeros( + self.add_input( + Dynamic.Mission.ALTITUDE_RATE, + val=np.zeros(nn), + units='m/s', + desc='rate of change of altitude', + ) + self.add_input( + Dynamic.Mission.VELOCITY, + val=np.zeros(nn), + units='m/s', + desc=Dynamic.Mission.VELOCITY, + ) + self.add_input( + Dynamic.Mission.VELOCITY_RATE, + val=np.zeros(nn), + units='m/s**2', + desc='rate of change of velocity', + ) + self.add_input(Dynamic.Vehicle.MASS, val=np.zeros( nn), units='kg', desc='mass of the aircraft') self.add_output('thrust_required', val=np.zeros( nn), units='N', desc='required thrust') ar = np.arange(nn) - self.declare_partials('thrust_required', Dynamic.Mission.DRAG, rows=ar, cols=ar) + self.declare_partials('thrust_required', Dynamic.Vehicle.DRAG, rows=ar, cols=ar) self.declare_partials( - 'thrust_required', Dynamic.Mission.ALTITUDE_RATE, rows=ar, cols=ar) + 'thrust_required', Dynamic.Mission.ALTITUDE_RATE, rows=ar, cols=ar + ) self.declare_partials( - 'thrust_required', Dynamic.Mission.VELOCITY, rows=ar, cols=ar) + 'thrust_required', Dynamic.Mission.VELOCITY, rows=ar, cols=ar + ) self.declare_partials( - 'thrust_required', Dynamic.Mission.VELOCITY_RATE, rows=ar, cols=ar) - self.declare_partials('thrust_required', Dynamic.Mission.MASS, rows=ar, cols=ar) + 'thrust_required', Dynamic.Mission.VELOCITY_RATE, rows=ar, cols=ar + ) + self.declare_partials('thrust_required', Dynamic.Vehicle.MASS, rows=ar, cols=ar) def compute(self, inputs, outputs): - drag = inputs[Dynamic.Mission.DRAG] + drag = inputs[Dynamic.Vehicle.DRAG] altitude_rate = inputs[Dynamic.Mission.ALTITUDE_RATE] velocity = inputs[Dynamic.Mission.VELOCITY] velocity_rate = inputs[Dynamic.Mission.VELOCITY_RATE] - mass = inputs[Dynamic.Mission.MASS] + mass = inputs[Dynamic.Vehicle.MASS] thrust_required = drag + (altitude_rate*gravity/velocity + velocity_rate) * mass @@ -54,12 +69,15 @@ def compute_partials(self, inputs, partials): altitude_rate = inputs[Dynamic.Mission.ALTITUDE_RATE] velocity = inputs[Dynamic.Mission.VELOCITY] velocity_rate = inputs[Dynamic.Mission.VELOCITY_RATE] - mass = inputs[Dynamic.Mission.MASS] + mass = inputs[Dynamic.Vehicle.MASS] - partials['thrust_required', Dynamic.Mission.DRAG] = 1.0 - partials['thrust_required', Dynamic.Mission.ALTITUDE_RATE] = gravity/velocity * mass - partials['thrust_required', Dynamic.Mission.VELOCITY] = - \ - altitude_rate*gravity/velocity**2 * mass + partials['thrust_required', Dynamic.Vehicle.DRAG] = 1.0 + partials['thrust_required', Dynamic.Mission.ALTITUDE_RATE] = ( + gravity / velocity * mass + ) + partials['thrust_required', Dynamic.Mission.VELOCITY] = ( + -altitude_rate * gravity / velocity**2 * mass + ) partials['thrust_required', Dynamic.Mission.VELOCITY_RATE] = mass - partials['thrust_required', Dynamic.Mission.MASS] = altitude_rate * \ + partials['thrust_required', Dynamic.Vehicle.MASS] = altitude_rate * \ gravity/velocity + velocity_rate diff --git a/aviary/mission/flops_based/ode/takeoff_eom.py b/aviary/mission/flops_based/ode/takeoff_eom.py index d0d1ab4d0..3ab97bd1d 100644 --- a/aviary/mission/flops_based/ode/takeoff_eom.py +++ b/aviary/mission/flops_based/ode/takeoff_eom.py @@ -32,7 +32,7 @@ def setup(self): add_aviary_input( self, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=np.ones(nn), units='kg/m**3', desc='current atmospheric density', @@ -57,7 +57,7 @@ def setup_partials(self): self.declare_partials( 'stall_speed', - ['mass', Dynamic.Mission.DENSITY], + ['mass', Dynamic.Atmosphere.DENSITY], rows=rows_cols, cols=rows_cols, ) @@ -66,7 +66,7 @@ def setup_partials(self): def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): mass = inputs['mass'] - density = inputs[Dynamic.Mission.DENSITY] + density = inputs[Dynamic.Atmosphere.DENSITY] area = inputs['area'] lift_coefficient_max = inputs['lift_coefficient_max'] @@ -77,7 +77,7 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): def compute_partials(self, inputs, J, discrete_inputs=None): mass = inputs['mass'] - density = inputs[Dynamic.Mission.DENSITY] + density = inputs[Dynamic.Atmosphere.DENSITY] area = inputs['area'] lift_coefficient_max = inputs['lift_coefficient_max'] @@ -88,7 +88,7 @@ def compute_partials(self, inputs, J, discrete_inputs=None): J['stall_speed', 'mass'] = \ grav_metric / (stall_speed * density * area * lift_coefficient_max) - J['stall_speed', Dynamic.Mission.DENSITY] = -weight / ( + J['stall_speed', Dynamic.Atmosphere.DENSITY] = -weight / ( stall_speed * density**2 * area * lift_coefficient_max ) @@ -203,14 +203,16 @@ def setup(self): nn = options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units='rad') + add_aviary_input( + self, Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units='rad' + ) add_aviary_input(self, Dynamic.Mission.VELOCITY, val=np.zeros(nn), units='m/s') add_aviary_output(self, Dynamic.Mission.DISTANCE_RATE, val=np.zeros(nn), units='m/s') - add_aviary_output(self, Dynamic.Mission.ALTITUDE_RATE, - val=np.zeros(nn), units='m/s') + add_aviary_output( + self, Dynamic.Mission.ALTITUDE_RATE, val=np.zeros(nn), units='m/s' + ) def setup_partials(self): options = self.options @@ -224,10 +226,16 @@ def setup_partials(self): else: self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE, dependent=False) + Dynamic.Mission.DISTANCE_RATE, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + dependent=False, + ) self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY, val=np.identity(nn)) + Dynamic.Mission.DISTANCE_RATE, + Dynamic.Mission.VELOCITY, + val=np.identity(nn), + ) self.declare_partials(Dynamic.Mission.ALTITUDE_RATE, '*', dependent=False) @@ -258,10 +266,14 @@ def compute_partials(self, inputs, J, discrete_inputs=None): cgam = np.cos(flight_path_angle) sgam = np.sin(flight_path_angle) - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = -sgam * velocity + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -sgam * velocity + ) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = cgam - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = cgam * velocity + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + cgam * velocity + ) J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = sgam @@ -278,7 +290,7 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.MASS, val=np.ones(nn), units='kg') + add_aviary_input(self, Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') self.add_input( 'forces_horizontal', val=np.zeros(nn), units='N', @@ -302,10 +314,18 @@ def setup_partials(self): rows_cols = np.arange(nn) self.declare_partials( - 'acceleration_horizontal', Dynamic.Mission.MASS, rows=rows_cols, cols=rows_cols) + 'acceleration_horizontal', + Dynamic.Vehicle.MASS, + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( - 'acceleration_vertical', Dynamic.Mission.MASS, rows=rows_cols, cols=rows_cols) + 'acceleration_vertical', + Dynamic.Vehicle.MASS, + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( 'acceleration_horizontal', 'forces_horizontal', rows=rows_cols, @@ -321,7 +341,7 @@ def setup_partials(self): 'acceleration_vertical', 'forces_vertical', rows=rows_cols, cols=rows_cols) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): - mass = inputs[Dynamic.Mission.MASS] + mass = inputs[Dynamic.Vehicle.MASS] f_h = inputs['forces_horizontal'] f_v = inputs['forces_vertical'] @@ -332,14 +352,14 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): outputs['acceleration_vertical'] = a_v def compute_partials(self, inputs, J, discrete_inputs=None): - mass = inputs[Dynamic.Mission.MASS] + mass = inputs[Dynamic.Vehicle.MASS] f_h = inputs['forces_horizontal'] f_v = inputs['forces_vertical'] m2 = mass * mass - J['acceleration_horizontal', Dynamic.Mission.MASS] = -f_h / m2 - J['acceleration_vertical', Dynamic.Mission.MASS] = -f_v / m2 + J['acceleration_horizontal', Dynamic.Vehicle.MASS] = -f_h / m2 + J['acceleration_vertical', Dynamic.Vehicle.MASS] = -f_v / m2 J['acceleration_horizontal', 'forces_horizontal'] = 1. / mass @@ -369,11 +389,13 @@ def setup(self): add_aviary_input(self, Dynamic.Mission.DISTANCE_RATE, val=np.zeros(nn), units='m/s') - add_aviary_input(self, Dynamic.Mission.ALTITUDE_RATE, - val=np.zeros(nn), units='m/s') + add_aviary_input( + self, Dynamic.Mission.ALTITUDE_RATE, val=np.zeros(nn), units='m/s' + ) - add_aviary_output(self, Dynamic.Mission.VELOCITY_RATE, - val=np.ones(nn), units='m/s**2') + add_aviary_output( + self, Dynamic.Mission.VELOCITY_RATE, val=np.ones(nn), units='m/s**2' + ) rows_cols = np.arange(nn) @@ -401,11 +423,13 @@ def compute_partials(self, inputs, J, discrete_inputs=None): J[Dynamic.Mission.VELOCITY_RATE, 'acceleration_horizontal'] = v_h / den J[Dynamic.Mission.VELOCITY_RATE, 'acceleration_vertical'] = v_v / den - J[Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.DISTANCE_RATE] = a_h / den - 0.5 * num / fact**(3/2) * 2.0 * v_h + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.DISTANCE_RATE] = ( + a_h / den - 0.5 * num / fact ** (3 / 2) * 2.0 * v_h + ) - J[Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.ALTITUDE_RATE] = a_v / den - 0.5 * num / fact**(3/2) * 2.0 * v_v + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.ALTITUDE_RATE] = ( + a_v / den - 0.5 * num / fact ** (3 / 2) * 2.0 * v_v + ) class FlightPathAngleRate(om.ExplicitComponent): @@ -423,8 +447,9 @@ def setup(self): add_aviary_input(self, Dynamic.Mission.DISTANCE_RATE, val=np.zeros(nn), units='m/s') - add_aviary_input(self, Dynamic.Mission.ALTITUDE_RATE, - val=np.zeros(nn), units='m/s') + add_aviary_input( + self, Dynamic.Mission.ALTITUDE_RATE, val=np.zeros(nn), units='m/s' + ) self.add_input( 'acceleration_horizontal', val=np.zeros(nn), @@ -439,7 +464,11 @@ def setup(self): ) add_aviary_output( - self, Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, val=np.zeros(nn), units='rad/s') + self, + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + val=np.zeros(nn), + units='rad/s', + ) rows_cols = np.arange(nn) @@ -472,8 +501,12 @@ def compute_partials(self, inputs, J, discrete_inputs=None): df_dav = v_h / den - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.DISTANCE_RATE] = df_dvh - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.ALTITUDE_RATE] = df_dvv + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.DISTANCE_RATE] = ( + df_dvh + ) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.ALTITUDE_RATE] = ( + df_dvv + ) J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, 'acceleration_horizontal'] = df_dah J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, 'acceleration_vertical'] = df_dav @@ -508,15 +541,17 @@ def setup(self): nn = options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.MASS, val=np.ones(nn), units='kg') - add_aviary_input(self, Dynamic.Mission.LIFT, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.THRUST_TOTAL, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.DRAG, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') + add_aviary_input(self, Dynamic.Vehicle.LIFT, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.DRAG, val=np.ones(nn), units='N') self.add_input('angle_of_attack', val=np.zeros(nn), units='rad') - add_aviary_input(self, Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units='rad') + add_aviary_input( + self, Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units='rad' + ) self.add_output( 'forces_horizontal', val=np.zeros(nn), units='N', @@ -535,16 +570,25 @@ def setup_partials(self): rows_cols = np.arange(nn) if climbing: - self.declare_partials('forces_horizontal', - Dynamic.Mission.MASS, dependent=False) + self.declare_partials( + 'forces_horizontal', Dynamic.Vehicle.MASS, dependent=False + ) self.declare_partials( - 'forces_vertical', Dynamic.Mission.MASS, val=-grav_metric, rows=rows_cols, - cols=rows_cols) + 'forces_vertical', + Dynamic.Vehicle.MASS, + val=-grav_metric, + rows=rows_cols, + cols=rows_cols, + ) wrt = [ - Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.LIFT, Dynamic.Mission.DRAG, 'angle_of_attack', - Dynamic.Mission.FLIGHT_PATH_ANGLE] + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.DRAG, + 'angle_of_attack', + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ] self.declare_partials('*', wrt, rows=rows_cols, cols=rows_cols) @@ -555,28 +599,45 @@ def setup_partials(self): val = -grav_metric * mu self.declare_partials( - 'forces_horizontal', Dynamic.Mission.MASS, val=val, rows=rows_cols, - cols=rows_cols) + 'forces_horizontal', + Dynamic.Vehicle.MASS, + val=val, + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( - 'forces_horizontal', Dynamic.Mission.LIFT, val=mu, rows=rows_cols, - cols=rows_cols) + 'forces_horizontal', + Dynamic.Vehicle.LIFT, + val=mu, + rows=rows_cols, + cols=rows_cols, + ) t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') val = np.cos(t_inc) + np.sin(t_inc) * mu self.declare_partials( - 'forces_horizontal', Dynamic.Mission.THRUST_TOTAL, val=val, rows=rows_cols, - cols=rows_cols) + 'forces_horizontal', + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=val, + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( - 'forces_horizontal', Dynamic.Mission.DRAG, val=-1., rows=rows_cols, - cols=rows_cols) + 'forces_horizontal', + Dynamic.Vehicle.DRAG, + val=-1.0, + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( - 'forces_horizontal', ['angle_of_attack', - Dynamic.Mission.FLIGHT_PATH_ANGLE], - dependent=False) + 'forces_horizontal', + ['angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE], + dependent=False, + ) self.declare_partials('forces_vertical', ['*'], dependent=False) @@ -588,10 +649,10 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] weight = mass * grav_metric @@ -648,9 +709,9 @@ def compute_partials(self, inputs, J, discrete_inputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] alpha = inputs['angle_of_attack'] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] @@ -663,23 +724,25 @@ def compute_partials(self, inputs, J, discrete_inputs=None): c_gamma = np.cos(gamma) s_gamma = np.sin(gamma) - J['forces_horizontal', Dynamic.Mission.THRUST_TOTAL] = c_angle - J['forces_vertical', Dynamic.Mission.THRUST_TOTAL] = s_angle + J['forces_horizontal', Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = c_angle + J['forces_vertical', Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = s_angle - J['forces_horizontal', Dynamic.Mission.LIFT] = -s_gamma - J['forces_vertical', Dynamic.Mission.LIFT] = c_gamma + J['forces_horizontal', Dynamic.Vehicle.LIFT] = -s_gamma + J['forces_vertical', Dynamic.Vehicle.LIFT] = c_gamma - J['forces_horizontal', Dynamic.Mission.DRAG] = -c_gamma - J['forces_vertical', Dynamic.Mission.DRAG] = -s_gamma + J['forces_horizontal', Dynamic.Vehicle.DRAG] = -c_gamma + J['forces_vertical', Dynamic.Vehicle.DRAG] = -s_gamma J['forces_horizontal', 'angle_of_attack'] = -thrust * s_angle J['forces_vertical', 'angle_of_attack'] = thrust * c_angle - J['forces_horizontal', Dynamic.Mission.FLIGHT_PATH_ANGLE] = \ + J['forces_horizontal', Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( -thrust * s_angle + drag * s_gamma - lift * c_gamma + ) - J['forces_vertical', Dynamic.Mission.FLIGHT_PATH_ANGLE] = \ + J['forces_vertical', Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( thrust * c_angle - drag * c_gamma - lift * s_gamma + ) class ClimbGradientForces(om.ExplicitComponent): @@ -702,15 +765,18 @@ def setup(self): nn = options['num_nodes'] - add_aviary_input(self, Dynamic.Mission.MASS, val=np.ones(nn), units='kg') - add_aviary_input(self, Dynamic.Mission.LIFT, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.THRUST_TOTAL, val=np.ones(nn), units='N') - add_aviary_input(self, Dynamic.Mission.DRAG, val=np.ones(nn), units='N') + add_aviary_input(self, Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg') + add_aviary_input(self, Dynamic.Vehicle.LIFT, val=np.ones(nn), units='N') + add_aviary_input( + self, Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.ones(nn), units='N' + ) + add_aviary_input(self, Dynamic.Vehicle.DRAG, val=np.ones(nn), units='N') self.add_input('angle_of_attack', val=np.zeros(nn), units='rad') - add_aviary_input(self, Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units='rad') + add_aviary_input( + self, Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units='rad' + ) self.add_output( 'climb_gradient_forces_horizontal', val=np.zeros(nn), units='N', @@ -732,23 +798,38 @@ def setup_partials(self): self.declare_partials( '*', [ - Dynamic.Mission.MASS, Dynamic.Mission.THRUST_TOTAL, 'angle_of_attack', - Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=rows_cols, cols=rows_cols) + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + 'angle_of_attack', + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ], + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( - 'climb_gradient_forces_horizontal', Dynamic.Mission.DRAG, val=-1., - rows=rows_cols, cols=rows_cols) + 'climb_gradient_forces_horizontal', + Dynamic.Vehicle.DRAG, + val=-1.0, + rows=rows_cols, + cols=rows_cols, + ) self.declare_partials( - 'climb_gradient_forces_vertical', Dynamic.Mission.DRAG, dependent=False) + 'climb_gradient_forces_vertical', Dynamic.Vehicle.DRAG, dependent=False + ) self.declare_partials( - 'climb_gradient_forces_horizontal', Dynamic.Mission.LIFT, dependent=False) + 'climb_gradient_forces_horizontal', Dynamic.Vehicle.LIFT, dependent=False + ) self.declare_partials( - 'climb_gradient_forces_vertical', Dynamic.Mission.LIFT, val=1., - rows=rows_cols, cols=rows_cols) + 'climb_gradient_forces_vertical', + Dynamic.Vehicle.LIFT, + val=1.0, + rows=rows_cols, + cols=rows_cols, + ) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): options = self.options @@ -758,10 +839,10 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] weight = mass * grav_metric @@ -792,10 +873,10 @@ def compute_partials(self, inputs, J, discrete_inputs=None): alpha0 = aviary_options.get_val(Mission.Takeoff.ANGLE_OF_ATTACK_RUNWAY, 'rad') t_inc = aviary_options.get_val(Mission.Takeoff.THRUST_INCIDENCE, 'rad') - mass = inputs[Dynamic.Mission.MASS] - lift = inputs[Dynamic.Mission.LIFT] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] + mass = inputs[Dynamic.Vehicle.MASS] + lift = inputs[Dynamic.Vehicle.LIFT] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] weight = mass * grav_metric @@ -813,11 +894,11 @@ def compute_partials(self, inputs, J, discrete_inputs=None): f_h_key = 'climb_gradient_forces_horizontal' f_v_key = 'climb_gradient_forces_vertical' - J[f_h_key, Dynamic.Mission.MASS] = -grav_metric * s_gamma - J[f_v_key, Dynamic.Mission.MASS] = -grav_metric * c_gamma + J[f_h_key, Dynamic.Vehicle.MASS] = -grav_metric * s_gamma + J[f_v_key, Dynamic.Vehicle.MASS] = -grav_metric * c_gamma - J[f_h_key, Dynamic.Mission.THRUST_TOTAL] = c_angle - J[f_v_key, Dynamic.Mission.THRUST_TOTAL] = s_angle + J[f_h_key, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = c_angle + J[f_v_key, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = s_angle J[f_h_key, 'angle_of_attack'] = -thrust * s_angle J[f_v_key, 'angle_of_attack'] = thrust * c_angle diff --git a/aviary/mission/flops_based/ode/takeoff_ode.py b/aviary/mission/flops_based/ode/takeoff_ode.py index 57278f53f..1cb0354e0 100644 --- a/aviary/mission/flops_based/ode/takeoff_ode.py +++ b/aviary/mission/flops_based/ode/takeoff_ode.py @@ -110,7 +110,7 @@ def setup(self): StallSpeed(num_nodes=nn), promotes_inputs=[ "mass", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, ('area', Aircraft.Wing.AREA), ("lift_coefficient_max", self.stall_speed_lift_coefficient_name), ], @@ -176,10 +176,10 @@ def setup(self): promotes_inputs=[ Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, 'angle_of_attack', ], promotes_outputs=[ diff --git a/aviary/mission/flops_based/ode/test/test_landing_eom.py b/aviary/mission/flops_based/ode/test/test_landing_eom.py index 220effc62..ca92b53bf 100644 --- a/aviary/mission/flops_based/ode/test/test_landing_eom.py +++ b/aviary/mission/flops_based/ode/test/test_landing_eom.py @@ -49,14 +49,19 @@ def test_case(self): 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], output_keys=[ Dynamic.Mission.DISTANCE_RATE, - Dynamic.Mission.ALTITUDE_RATE], - tol=1e-2, atol=1e-8, rtol=5e-10) + Dynamic.Mission.ALTITUDE_RATE, + ], + tol=1e-2, + atol=1e-8, + rtol=5e-10, + ) def test_IO(self): exclude_inputs = { @@ -91,13 +96,15 @@ def test_GlideSlopeForces(self): "glide", GlideSlopeForces(num_nodes=2, aviary_options=aviary_options), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, np.array([482117.47027692, 568511.57097785]), units="N" + Dynamic.Vehicle.LIFT, + np.array([482117.47027692, 568511.57097785]), + units="N", ) prob.model.set_input_defaults( "angle_of_attack", np.array([5.086, 6.834]), units="deg" @@ -132,22 +139,24 @@ def test_FlareSumForces(self): # use data from detailed_landing_flare in models/N3CC/N3CC_data.py prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, np.array([482117.47027692, 568511.57097785]), units="N" + Dynamic.Vehicle.LIFT, + np.array([482117.47027692, 568511.57097785]), + units="N", ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" ) prob.model.set_input_defaults( "angle_of_attack", np.array([5.086, 6.834]), units="deg" ) prob.model.set_input_defaults( - Dynamic.Mission.FLIGHT_PATH_ANGLE, np.array([-3., -2.47]), units="deg" + Dynamic.Mission.FLIGHT_PATH_ANGLE, np.array([-3.0, -2.47]), units="deg" ) prob.setup(check=False, force_alloc_complex=True) prob.run_model() @@ -175,16 +184,18 @@ def test_GroundSumForces(self): # use data from detailed_landing_flare in models/N3CC/N3CC_data.py prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, np.array([482117.47027692, 568511.57097785]), units="N" + Dynamic.Vehicle.LIFT, + np.array([482117.47027692, 568511.57097785]), + units="N", ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" ) prob.setup(check=False, force_alloc_complex=True) prob.run_model() diff --git a/aviary/mission/flops_based/ode/test/test_landing_ode.py b/aviary/mission/flops_based/ode/test/test_landing_ode.py index 00310a904..454bf0e32 100644 --- a/aviary/mission/flops_based/ode/test/test_landing_ode.py +++ b/aviary/mission/flops_based/ode/test/test_landing_ode.py @@ -57,15 +57,21 @@ def test_case(self): 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], output_keys=[ Dynamic.Mission.DISTANCE_RATE, - Dynamic.Mission.ALTITUDE_RATE], - tol=1e-2, atol=5e-9, rtol=5e-9, - check_values=False, check_partials=True) + Dynamic.Mission.ALTITUDE_RATE, + ], + tol=1e-2, + atol=5e-9, + rtol=5e-9, + check_values=False, + check_partials=True, + ) if __name__ == "__main__": diff --git a/aviary/mission/flops_based/ode/test/test_mission_eom.py b/aviary/mission/flops_based/ode/test/test_mission_eom.py index 648c3a111..8c2a7bd05 100644 --- a/aviary/mission/flops_based/ode/test/test_mission_eom.py +++ b/aviary/mission/flops_based/ode/test/test_mission_eom.py @@ -21,22 +21,34 @@ def setUp(self): "mission", MissionEOM(num_nodes=3), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([81796.1389890711, 74616.9849763798, 65193.7423491884]), units="kg" + Dynamic.Vehicle.MASS, + np.array([81796.1389890711, 74616.9849763798, 65193.7423491884]), + units="kg", ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([9978.32211087097, 8769.90342254821, 7235.03338269778]), units="lbf" + Dynamic.Vehicle.DRAG, + np.array([9978.32211087097, 8769.90342254821, 7235.03338269778]), + units="lbf", ) prob.model.set_input_defaults( - Dynamic.Mission.ALTITUDE_RATE, np.array([29.8463233754212, -5.69941245767868E-09, -4.32644785970493]), units="ft/s" + Dynamic.Mission.ALTITUDE_RATE, + np.array([29.8463233754212, -5.69941245767868e-09, -4.32644785970493]), + units="ft/s", ) prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY_RATE, np.array([0.558739800813549, 3.33665416459715E-17, -0.38372209277242]), units="m/s**2" + Dynamic.Mission.VELOCITY_RATE, + np.array([0.558739800813549, 3.33665416459715e-17, -0.38372209277242]), + units="m/s**2", ) prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, np.array([164.029012458452, 232.775306059091, 117.638805929526]), units="m/s" + Dynamic.Mission.VELOCITY, + np.array([164.029012458452, 232.775306059091, 117.638805929526]), + units="m/s", ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_MAX_TOTAL, np.array([40799.6009633346, 11500.32, 42308.2709683461]), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + np.array([40799.6009633346, 11500.32, 42308.2709683461]), + units="lbf", ) prob.setup(check=False, force_alloc_complex=True) @@ -48,8 +60,11 @@ def test_case(self): tol = 1e-6 self.prob.run_model() - assert_near_equal(self.prob.get_val(Dynamic.Mission.ALTITUDE_RATE_MAX, units='ft/min'), - np.array([3679.0525544843, 760.55416759, 6557.07891846677]), tol) + assert_near_equal( + self.prob.get_val(Dynamic.Mission.ALTITUDE_RATE_MAX, units='ft/min'), + np.array([3679.0525544843, 760.55416759, 6557.07891846677]), + tol, + ) partial_data = self.prob.check_partials(out_stream=None, method="cs") assert_check_partials(partial_data, atol=1e-8, rtol=1e-12) diff --git a/aviary/mission/flops_based/ode/test/test_range_rate.py b/aviary/mission/flops_based/ode/test/test_range_rate.py index 3d6d3ab2a..f9ea57dfc 100644 --- a/aviary/mission/flops_based/ode/test/test_range_rate.py +++ b/aviary/mission/flops_based/ode/test/test_range_rate.py @@ -31,14 +31,15 @@ def setUp(self): def test_case1(self): - do_validation_test(self.prob, - 'full_mission_test_data', - input_validation_data=data, - output_validation_data=data, - input_keys=[Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY], - output_keys=Dynamic.Mission.DISTANCE_RATE, - tol=1e-12) + do_validation_test( + self.prob, + 'full_mission_test_data', + input_validation_data=data, + output_validation_data=data, + input_keys=[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY], + output_keys=Dynamic.Mission.DISTANCE_RATE, + tol=1e-12, + ) def test_IO(self): assert_match_varnames(self.prob.model) diff --git a/aviary/mission/flops_based/ode/test/test_required_thrust.py b/aviary/mission/flops_based/ode/test/test_required_thrust.py index 4e55b5b7a..5a7cdd826 100644 --- a/aviary/mission/flops_based/ode/test/test_required_thrust.py +++ b/aviary/mission/flops_based/ode/test/test_required_thrust.py @@ -21,10 +21,10 @@ def setUp(self): "req_thrust", RequiredThrust(num_nodes=2), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( Dynamic.Mission.ALTITUDE_RATE, np.array([1.72, 11.91]), units="m/s" diff --git a/aviary/mission/flops_based/ode/test/test_takeoff_eom.py b/aviary/mission/flops_based/ode/test/test_takeoff_eom.py index e3e35fc21..3718ebd5b 100644 --- a/aviary/mission/flops_based/ode/test/test_takeoff_eom.py +++ b/aviary/mission/flops_based/ode/test/test_takeoff_eom.py @@ -32,15 +32,18 @@ def test_case_ground(self): 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], output_keys=[ Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY_RATE], - tol=1e-2) + Dynamic.Mission.VELOCITY_RATE, + ], + tol=1e-2, + ) def test_case_climbing(self): prob = self._make_prob(climbing=True) @@ -54,15 +57,20 @@ def test_case_climbing(self): 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], output_keys=[ Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY_RATE], - tol=1e-2, atol=1e-9, rtol=1e-11) + Dynamic.Mission.VELOCITY_RATE, + ], + tol=1e-2, + atol=1e-9, + rtol=1e-11, + ) @staticmethod def _make_prob(climbing): @@ -106,7 +114,7 @@ def test_StallSpeed(self): "stall_speed", StallSpeed(num_nodes=2), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, np.array([1, 2]), units="kg/m**3" + Dynamic.Atmosphere.DENSITY, np.array([1, 2]), units="kg/m**3" ) prob.model.set_input_defaults( "area", 10, units="m**2" @@ -151,8 +159,9 @@ def test_DistanceRates_1(self): [4.280758, -1.56085]), tol ) assert_near_equal( - prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [3.004664, -2.203122]), tol + prob[Dynamic.Mission.ALTITUDE_RATE], + np.array([3.004664, -2.203122]), + tol, ) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -238,8 +247,9 @@ def test_VelocityRate(self): prob.run_model() assert_near_equal( - prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [100.5284, 206.6343]), tol + prob[Dynamic.Mission.VELOCITY_RATE], + np.array([100.5284, 206.6343]), + tol, ) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -268,8 +278,9 @@ def test_FlightPathAngleRate(self): prob.run_model() assert_near_equal( - prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [0.3039257, 0.51269018]), tol + prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], + np.array([0.3039257, 0.51269018]), + tol, ) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -287,16 +298,18 @@ def test_SumForcese_1(self): "sum1", SumForces(num_nodes=2, climbing=True, aviary_options=aviary_options), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, np.array([482117.47027692, 568511.57097785]), units="N" + Dynamic.Vehicle.LIFT, + np.array([482117.47027692, 568511.57097785]), + units="N", ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" ) prob.setup(check=False, force_alloc_complex=True) @@ -326,16 +339,18 @@ def test_SumForcese_2(self): "sum2", SumForces(num_nodes=2, climbing=False, aviary_options=aviary_options), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, np.array([482117.47027692, 568511.57097785]), units="N" + Dynamic.Vehicle.LIFT, + np.array([482117.47027692, 568511.57097785]), + units="N", ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" ) prob.setup(check=False, force_alloc_complex=True) @@ -363,16 +378,18 @@ def test_ClimbGradientForces(self): "climb_grad", ClimbGradientForces(num_nodes=2, aviary_options=aviary_options), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([106292, 106292]), units="lbm" + Dynamic.Vehicle.MASS, np.array([106292, 106292]), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" + Dynamic.Vehicle.DRAG, np.array([47447.13138523, 44343.01567596]), units="N" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, np.array([482117.47027692, 568511.57097785]), units="N" + Dynamic.Vehicle.LIFT, + np.array([482117.47027692, 568511.57097785]), + units="N", ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([4980.3, 4102]), units="N" ) prob.model.set_input_defaults( Dynamic.Mission.FLIGHT_PATH_ANGLE, np.array([0.612, 4.096]), units="rad" diff --git a/aviary/mission/flops_based/ode/test/test_takeoff_ode.py b/aviary/mission/flops_based/ode/test/test_takeoff_ode.py index 460680614..453422c7b 100644 --- a/aviary/mission/flops_based/ode/test/test_takeoff_ode.py +++ b/aviary/mission/flops_based/ode/test/test_takeoff_ode.py @@ -34,16 +34,22 @@ def test_case_ground(self): Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], output_keys=[ Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY_RATE], - tol=1e-2, atol=1e-9, rtol=1e-11, - check_values=False, check_partials=True) + Dynamic.Mission.VELOCITY_RATE, + ], + tol=1e-2, + atol=1e-9, + rtol=1e-11, + check_values=False, + check_partials=True, + ) def test_case_climbing(self): prob = self._make_prob(climbing=True) @@ -58,16 +64,22 @@ def test_case_climbing(self): Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], output_keys=[ Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.VELOCITY_RATE], - tol=1e-2, atol=1e-9, rtol=1e-11, - check_values=False, check_partials=True) + Dynamic.Mission.VELOCITY_RATE, + ], + tol=1e-2, + atol=1e-9, + rtol=1e-11, + check_values=False, + check_partials=True, + ) @staticmethod def _make_prob(climbing): diff --git a/aviary/mission/flops_based/phases/build_takeoff.py b/aviary/mission/flops_based/phases/build_takeoff.py index ff99291bd..eff33f9a1 100644 --- a/aviary/mission/flops_based/phases/build_takeoff.py +++ b/aviary/mission/flops_based/phases/build_takeoff.py @@ -64,8 +64,7 @@ def build_phase(self, use_detailed=False): takeoff = TakeoffGroup(num_engines=self.num_engines) takeoff.set_input_defaults( - Dynamic.Mission.ALTITUDE, - val=self.airport_altitude, - units="ft") + Dynamic.Mission.ALTITUDE, val=self.airport_altitude, units="ft" + ) return takeoff diff --git a/aviary/mission/flops_based/phases/detailed_landing_phases.py b/aviary/mission/flops_based/phases/detailed_landing_phases.py index 4dffa24e7..adccdb346 100644 --- a/aviary/mission/flops_based/phases/detailed_landing_phases.py +++ b/aviary/mission/flops_based/phases/detailed_landing_phases.py @@ -155,31 +155,47 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, fix_final=False, + Dynamic.Mission.ALTITUDE, + fix_initial=False, + fix_final=False, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, fix_final=False, - lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + fix_final=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) - phase.add_control(Dynamic.Mission.FLIGHT_PATH_ANGLE, opt=False, fix_initial=True) + phase.add_control( + Dynamic.Mission.FLIGHT_PATH_ANGLE, opt=False, fix_initial=True + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=True, fix_final=False, - lower=0.0, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=True, + fix_final=False, + lower=0.0, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -195,12 +211,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) initial_height, units = user_options.get_item('initial_height') @@ -211,7 +227,13 @@ def build_phase(self, aviary_options: AviaryValues = None): h = initial_height + airport_altitude phase.add_boundary_constraint( - Dynamic.Mission.ALTITUDE, loc='initial', equals=h, ref=h, units=units, linear=True) + Dynamic.Mission.ALTITUDE, + loc='initial', + equals=h, + ref=h, + units=units, + linear=True, + ) return phase @@ -258,7 +280,8 @@ def _extra_ode_init_kwargs(self): LandingApproachToMicP3._add_initial_guess_meta_data(InitialGuessState('altitude')) LandingApproachToMicP3._add_initial_guess_meta_data( - InitialGuessControl(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessControl(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) # @_init_initial_guess_meta_data # <--- inherited from base class @@ -355,7 +378,7 @@ def build_phase(self, aviary_options: AviaryValues = None): # this class and phases of its base class phase.set_state_options(Dynamic.Mission.DISTANCE, fix_final=True) phase.set_state_options(Dynamic.Mission.VELOCITY, fix_final=True) - phase.set_state_options(Dynamic.Mission.MASS, fix_initial=False) + phase.set_state_options(Dynamic.Vehicle.MASS, fix_initial=False) return phase @@ -464,42 +487,58 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=True, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=True, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) - phase.add_control(Dynamic.Mission.FLIGHT_PATH_ANGLE, - opt=False, fix_initial=False) + phase.add_control( + Dynamic.Mission.FLIGHT_PATH_ANGLE, opt=False, fix_initial=False + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) phase.add_control('angle_of_attack', opt=False, units='deg') phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) obstacle_height, units = aviary_options.get_item( @@ -515,7 +554,13 @@ def build_phase(self, aviary_options: AviaryValues = None): h = obstacle_height + airport_altitude phase.add_boundary_constraint( - Dynamic.Mission.ALTITUDE, loc='initial', equals=h, ref=h, units=units, linear=True) + Dynamic.Mission.ALTITUDE, + loc='initial', + equals=h, + ref=h, + units=units, + linear=True, + ) return phase @@ -550,7 +595,8 @@ def _extra_ode_init_kwargs(self): LandingObstacleToFlare._add_initial_guess_meta_data(InitialGuessState('altitude')) LandingObstacleToFlare._add_initial_guess_meta_data( - InitialGuessControl(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessControl(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -664,33 +710,49 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, fix_final=True, - lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + fix_final=True, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) - phase.add_control(Dynamic.Mission.FLIGHT_PATH_ANGLE, - fix_initial=False, opt=False) + phase.add_control( + Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=False, opt=False + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) # TODO: Upper limit is a bit of a hack. It hopefully won't be needed if we # can get some other constraints working. phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', lower=0.0, upper=0.2, opt=True ) @@ -708,12 +770,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_timeseries_output( @@ -772,7 +834,8 @@ def _extra_ode_init_kwargs(self): LandingFlareToTouchdown._add_initial_guess_meta_data(InitialGuessState('altitude')) LandingFlareToTouchdown._add_initial_guess_meta_data( - InitialGuessControl(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessControl(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -880,20 +943,30 @@ def build_phase(self, aviary_options=None): max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -906,12 +979,12 @@ def build_phase(self, aviary_options=None): fix_initial=False, ref=max_angle_of_attack) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) return phase @@ -1053,34 +1126,44 @@ def build_phase(self, aviary_options=None): max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, fix_final=True, - lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + fix_final=True, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) # TODO: Energy phase places this under an if num_engines > 0. phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) phase.add_parameter('angle_of_attack', val=0.0, opt=False, units='deg') phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) return phase diff --git a/aviary/mission/flops_based/phases/detailed_takeoff_phases.py b/aviary/mission/flops_based/phases/detailed_takeoff_phases.py index 5c5d716c9..38e6f2ac9 100644 --- a/aviary/mission/flops_based/phases/detailed_takeoff_phases.py +++ b/aviary/mission/flops_based/phases/detailed_takeoff_phases.py @@ -188,33 +188,39 @@ def build_phase(self, aviary_options=None): max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=True, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=True, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=True, fix_final=False, + Dynamic.Vehicle.MASS, fix_initial=True, fix_final=False, lower=0.0, upper=1e9, ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) # TODO: Energy phase places this under an if num_engines > 0. phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) phase.add_parameter('angle_of_attack', val=0.0, opt=False, units='deg') phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) return phase @@ -355,21 +361,33 @@ def build_phase(self, aviary_options=None): max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) # TODO: Energy phase places this under an if num_engines > 0. phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -378,12 +396,12 @@ def build_phase(self, aviary_options=None): phase.add_parameter('angle_of_attack', val=0.0, opt=False, units='deg') phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( @@ -630,22 +648,34 @@ def build_phase(self, aviary_options=None): max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) max_angle_of_attack, units = user_options.get_item('max_angle_of_attack') phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -655,12 +685,12 @@ def build_phase(self, aviary_options=None): ref=max_angle_of_attack) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_timeseries_output( @@ -815,35 +845,58 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=True, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, upper=altitude_ref, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=True, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + upper=altitude_ref, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) flight_path_angle_ref, units = user_options.get_item('flight_path_angle_ref') phase.add_state( - Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=True, lower=0, - ref=flight_path_angle_ref, upper=flight_path_angle_ref, - defect_ref=flight_path_angle_ref, units=units, - rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE) + Dynamic.Mission.FLIGHT_PATH_ANGLE, + fix_initial=True, + lower=0, + ref=flight_path_angle_ref, + upper=flight_path_angle_ref, + defect_ref=flight_path_angle_ref, + units=units, + rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -857,12 +910,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ref=angle_of_attack_ref) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) obstacle_height, units = aviary_options.get_item( @@ -878,7 +931,13 @@ def build_phase(self, aviary_options: AviaryValues = None): h = obstacle_height + airport_altitude phase.add_boundary_constraint( - Dynamic.Mission.ALTITUDE, loc='final', equals=h, ref=h, units=units, linear=True) + Dynamic.Mission.ALTITUDE, + loc='final', + equals=h, + ref=h, + units=units, + linear=True, + ) phase.add_path_constraint( 'v_over_v_stall', lower=1.25, ref=2.0) @@ -931,7 +990,8 @@ def _extra_ode_init_kwargs(self): TakeoffLiftoffToObstacle._add_initial_guess_meta_data(InitialGuessState('altitude')) TakeoffLiftoffToObstacle._add_initial_guess_meta_data( - InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -1048,35 +1108,56 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) flight_path_angle_ref, units = user_options.get_item('flight_path_angle_ref') phase.add_state( - Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=False, lower=0, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + fix_initial=False, + lower=0, ref=flight_path_angle_ref, - defect_ref=flight_path_angle_ref, units=units, - rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE) + defect_ref=flight_path_angle_ref, + units=units, + rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -1090,12 +1171,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ref=angle_of_attack_ref) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) final_altitude, units = user_options.get_item('mic_altitude') @@ -1106,7 +1187,13 @@ def build_phase(self, aviary_options: AviaryValues = None): h = final_altitude + airport_altitude phase.add_boundary_constraint( - Dynamic.Mission.ALTITUDE, loc='final', equals=h, ref=h, units=units, linear=True) + Dynamic.Mission.ALTITUDE, + loc='final', + equals=h, + ref=h, + units=units, + linear=True, + ) phase.add_boundary_constraint( 'v_over_v_stall', loc='final', lower=1.25, ref=1.25) @@ -1160,7 +1247,8 @@ def _extra_ode_init_kwargs(self): TakeoffObstacleToMicP2._add_initial_guess_meta_data(InitialGuessState('altitude')) TakeoffObstacleToMicP2._add_initial_guess_meta_data( - InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -1277,35 +1365,56 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) flight_path_angle_ref, units = user_options.get_item('flight_path_angle_ref') phase.add_state( - Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=False, lower=0, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + fix_initial=False, + lower=0, ref=flight_path_angle_ref, - defect_ref=flight_path_angle_ref, units=units, - rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE) + defect_ref=flight_path_angle_ref, + units=units, + rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -1319,12 +1428,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ref=angle_of_attack_ref) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) # start engine cutback phase at this range, where this phase ends @@ -1390,7 +1499,8 @@ def _extra_ode_init_kwargs(self): TakeoffMicP2ToEngineCutback._add_initial_guess_meta_data(InitialGuessState('altitude')) TakeoffMicP2ToEngineCutback._add_initial_guess_meta_data( - InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -1502,35 +1612,56 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) flight_path_angle_ref, units = user_options.get_item('flight_path_angle_ref') phase.add_state( - Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=False, lower=0, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + fix_initial=False, + lower=0, ref=flight_path_angle_ref, - defect_ref=flight_path_angle_ref, units=units, - rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE) + defect_ref=flight_path_angle_ref, + units=units, + rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -1544,12 +1675,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ref=angle_of_attack_ref) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) phase.add_boundary_constraint( @@ -1598,7 +1729,8 @@ def _extra_ode_init_kwargs(self): TakeoffEngineCutback._add_initial_guess_meta_data(InitialGuessState('altitude')) TakeoffEngineCutback._add_initial_guess_meta_data( - InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -1715,35 +1847,56 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) flight_path_angle_ref, units = user_options.get_item('flight_path_angle_ref') phase.add_state( - Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=False, lower=0, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + fix_initial=False, + lower=0, ref=flight_path_angle_ref, - defect_ref=flight_path_angle_ref, units=units, - rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE) + defect_ref=flight_path_angle_ref, + units=units, + rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -1757,12 +1910,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ref=angle_of_attack_ref) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) mic_range, units = user_options.get_item('mic_range') @@ -1824,7 +1977,8 @@ def _extra_ode_init_kwargs(self): TakeoffEngineCutbackToMicP1._add_initial_guess_meta_data(InitialGuessState('altitude')) TakeoffEngineCutbackToMicP1._add_initial_guess_meta_data( - InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -1941,35 +2095,56 @@ def build_phase(self, aviary_options: AviaryValues = None): altitude_ref, units = user_options.get_item('altitude_ref') phase.add_state( - Dynamic.Mission.ALTITUDE, fix_initial=False, lower=0, ref=altitude_ref, - defect_ref=altitude_ref, units=units, - rate_source=Dynamic.Mission.ALTITUDE_RATE) + Dynamic.Mission.ALTITUDE, + fix_initial=False, + lower=0, + ref=altitude_ref, + defect_ref=altitude_ref, + units=units, + rate_source=Dynamic.Mission.ALTITUDE_RATE, + ) max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, lower=0, ref=max_velocity, - defect_ref=max_velocity, units=units, upper=max_velocity, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + lower=0, + ref=max_velocity, + defect_ref=max_velocity, + units=units, + upper=max_velocity, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) flight_path_angle_ref, units = user_options.get_item('flight_path_angle_ref') phase.add_state( - Dynamic.Mission.FLIGHT_PATH_ANGLE, fix_initial=False, lower=0, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + fix_initial=False, + lower=0, ref=flight_path_angle_ref, - defect_ref=flight_path_angle_ref, units=units, - rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE) + defect_ref=flight_path_angle_ref, + units=units, + rate_source=Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) @@ -1983,12 +2158,12 @@ def build_phase(self, aviary_options: AviaryValues = None): ref=angle_of_attack_ref) phase.add_timeseries_output( - Dynamic.Mission.DRAG, output_name=Dynamic.Mission.DRAG, units='lbf' + Dynamic.Vehicle.DRAG, output_name=Dynamic.Vehicle.DRAG, units='lbf' ) phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, - output_name=Dynamic.Mission.THRUST_TOTAL, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf' ) mic_range, units = user_options.get_item('mic_range') @@ -2049,7 +2224,8 @@ def _extra_ode_init_kwargs(self): TakeoffMicP1ToClimb._add_initial_guess_meta_data(InitialGuessState('altitude')) TakeoffMicP1ToClimb._add_initial_guess_meta_data( - InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE)) + InitialGuessState(Dynamic.Mission.FLIGHT_PATH_ANGLE) +) @_init_initial_guess_meta_data @@ -2158,21 +2334,33 @@ def build_phase(self, aviary_options=None): max_velocity, units = user_options.get_item('max_velocity') phase.add_state( - Dynamic.Mission.VELOCITY, fix_initial=False, fix_final=True, - lower=0, ref=max_velocity, upper=max_velocity, - defect_ref=max_velocity, units=units, - rate_source=Dynamic.Mission.VELOCITY_RATE) + Dynamic.Mission.VELOCITY, + fix_initial=False, + fix_final=True, + lower=0, + ref=max_velocity, + upper=max_velocity, + defect_ref=max_velocity, + units=units, + rate_source=Dynamic.Mission.VELOCITY_RATE, + ) phase.add_state( - Dynamic.Mission.MASS, fix_initial=False, fix_final=False, - lower=0.0, upper=1e9, ref=5e4, defect_ref=5e4, units='kg', - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, + fix_initial=False, + fix_final=False, + lower=0.0, + upper=1e9, + ref=5e4, + defect_ref=5e4, + units='kg', + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ) phase.add_control( - Dynamic.Mission.THROTTLE, - targets=Dynamic.Mission.THROTTLE, units='unitless', + Dynamic.Vehicle.Propulsion.THROTTLE, + targets=Dynamic.Vehicle.Propulsion.THROTTLE, units='unitless', opt=False ) diff --git a/aviary/mission/flops_based/phases/groundroll_phase.py b/aviary/mission/flops_based/phases/groundroll_phase.py index f779ab9a5..99ddfdf8a 100644 --- a/aviary/mission/flops_based/phases/groundroll_phase.py +++ b/aviary/mission/flops_based/phases/groundroll_phase.py @@ -78,9 +78,14 @@ def build_phase(self, aviary_options: AviaryValues = None): duration_ref = user_options.get_val('duration_ref', units='kn') constraints = user_options.get_val('constraints') - phase.set_time_options(fix_initial=True, fix_duration=False, - units="kn", name=Dynamic.Mission.VELOCITY, - duration_bounds=duration_bounds, duration_ref=duration_ref) + phase.set_time_options( + fix_initial=True, + fix_duration=False, + units="kn", + name=Dynamic.Mission.VELOCITY, + duration_bounds=duration_bounds, + duration_ref=duration_ref, + ) phase.set_state_options("time", rate_source="dt_dv", units="s", fix_initial=True, fix_final=False, ref=1., defect_ref=1., solve_segments='forward') @@ -100,20 +105,20 @@ def build_phase(self, aviary_options: AviaryValues = None): self._add_user_defined_constraints(phase, constraints) - phase.add_timeseries_output(Dynamic.Mission.THRUST_TOTAL, units="lbf") + phase.add_timeseries_output(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units="lbf") phase.add_timeseries_output("thrust_req", units="lbf") phase.add_timeseries_output("normal_force") - phase.add_timeseries_output(Dynamic.Mission.MACH) + phase.add_timeseries_output(Dynamic.Atmosphere.MACH) phase.add_timeseries_output("EAS", units="kn") phase.add_timeseries_output(Dynamic.Mission.VELOCITY, units="kn") - phase.add_timeseries_output(Dynamic.Mission.LIFT) - phase.add_timeseries_output(Dynamic.Mission.DRAG) + phase.add_timeseries_output(Dynamic.Vehicle.LIFT) + phase.add_timeseries_output(Dynamic.Vehicle.DRAG) phase.add_timeseries_output("time") phase.add_timeseries_output("mass") phase.add_timeseries_output(Dynamic.Mission.ALTITUDE) phase.add_timeseries_output("alpha") phase.add_timeseries_output(Dynamic.Mission.FLIGHT_PATH_ANGLE) - phase.add_timeseries_output(Dynamic.Mission.THROTTLE) + phase.add_timeseries_output(Dynamic.Vehicle.Propulsion.THROTTLE) return phase diff --git a/aviary/mission/flops_based/phases/simplified_landing.py b/aviary/mission/flops_based/phases/simplified_landing.py index 2fc6dddcb..1c19060d0 100644 --- a/aviary/mission/flops_based/phases/simplified_landing.py +++ b/aviary/mission/flops_based/phases/simplified_landing.py @@ -17,7 +17,7 @@ def setup(self): add_aviary_input( self, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=1.225, units="kg/m**3", desc="atmospheric density", @@ -40,7 +40,7 @@ def compute(self, inputs, outputs): rho_SL = RHO_SEA_LEVEL_METRIC landing_weight = inputs[Mission.Landing.TOUCHDOWN_MASS] * \ GRAV_ENGLISH_LBM - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] planform_area = inputs[Aircraft.Wing.AREA] Cl_ldg_max = inputs[Mission.Landing.LIFT_COEFFICIENT_MAX] @@ -63,7 +63,7 @@ def compute_partials(self, inputs, J): rho_SL = RHO_SEA_LEVEL_METRIC landing_weight = inputs[Mission.Landing.TOUCHDOWN_MASS] * \ GRAV_ENGLISH_LBM - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] planform_area = inputs[Aircraft.Wing.AREA] Cl_ldg_max = inputs[Mission.Landing.LIFT_COEFFICIENT_MAX] @@ -106,7 +106,7 @@ def compute_partials(self, inputs, J): / (planform_area * rho_ratio * Cl_app ** 2 * 1.69) / 1.3 ** 2 ) - J[Mission.Landing.GROUND_DISTANCE, Dynamic.Mission.DENSITY] = ( + J[Mission.Landing.GROUND_DISTANCE, Dynamic.Atmosphere.DENSITY] = ( -105 * landing_weight / (planform_area * rho_ratio**2 * Cl_app * 1.69) @@ -136,7 +136,7 @@ def setup(self): LandingCalc(), promotes_inputs=[ Mission.Landing.TOUCHDOWN_MASS, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Aircraft.Wing.AREA, Mission.Landing.LIFT_COEFFICIENT_MAX, ], diff --git a/aviary/mission/flops_based/phases/simplified_takeoff.py b/aviary/mission/flops_based/phases/simplified_takeoff.py index 3f7ef9d31..6969d6a80 100644 --- a/aviary/mission/flops_based/phases/simplified_takeoff.py +++ b/aviary/mission/flops_based/phases/simplified_takeoff.py @@ -25,7 +25,7 @@ def setup(self): ) self.add_input( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=1.225, units="kg/m**3", desc="atmospheric density", @@ -56,7 +56,7 @@ def compute(self, inputs, outputs): # This is only necessary because the equation expects newtons, # but the mission expects pounds mass instead of pounds force. weight = weight*4.44822 - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] S = inputs["planform_area"] Cl_max = inputs["Cl_max"] @@ -67,7 +67,7 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): weight = inputs["mass"] * GRAV_ENGLISH_LBM - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] S = inputs["planform_area"] Cl_max = inputs["Cl_max"] @@ -75,7 +75,7 @@ def compute_partials(self, inputs, J): J["v_stall", "mass"] = 0.5 * 4.44822**.5 * \ rad ** (-0.5) * 2 * GRAV_ENGLISH_LBM / (rho * S * Cl_max) - J["v_stall", Dynamic.Mission.DENSITY] = ( + J["v_stall", Dynamic.Atmosphere.DENSITY] = ( 0.5 * 4.44822**0.5 * rad ** (-0.5) * (-2 * weight) / (rho**2 * S * Cl_max) ) J["v_stall", "planform_area"] = ( @@ -109,7 +109,7 @@ def setup(self): add_aviary_input(self, Mission.Takeoff.FUEL_SIMPLE, val=10.e3) self.add_input( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=1.225, units="kg/m**3", desc="atmospheric density", @@ -143,7 +143,7 @@ def setup_partials(self): Mission.Takeoff.GROUND_DISTANCE, [ Mission.Summary.GROSS_MASS, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Aircraft.Wing.AREA, Mission.Takeoff.LIFT_COEFFICIENT_MAX, Mission.Design.THRUST_TAKEOFF_PER_ENG, @@ -168,7 +168,7 @@ def compute(self, inputs, outputs): v_stall = inputs["v_stall"] gross_mass = inputs[Mission.Summary.GROSS_MASS] ramp_weight = gross_mass * GRAV_ENGLISH_LBM - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] S = inputs[Aircraft.Wing.AREA] Cl_max = inputs[Mission.Takeoff.LIFT_COEFFICIENT_MAX] thrust = inputs[Mission.Design.THRUST_TAKEOFF_PER_ENG] @@ -220,7 +220,7 @@ def compute_partials(self, inputs, J): rho_SL = RHO_SEA_LEVEL_METRIC ramp_weight = inputs[Mission.Summary.GROSS_MASS] * GRAV_ENGLISH_LBM - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] S = inputs[Aircraft.Wing.AREA] Cl_max = inputs[Mission.Takeoff.LIFT_COEFFICIENT_MAX] thrust = inputs[Mission.Design.THRUST_TAKEOFF_PER_ENG] @@ -362,7 +362,7 @@ def compute_partials(self, inputs, J): J[Mission.Takeoff.GROUND_DISTANCE, Mission.Summary.GROSS_MASS] = dRD_dM + dRot_dM + dCout_dM - J[Mission.Takeoff.GROUND_DISTANCE, Dynamic.Mission.DENSITY] = ( + J[Mission.Takeoff.GROUND_DISTANCE, Dynamic.Atmosphere.DENSITY] = ( dRD_dRho + dRot_dRho + dCout_dRho ) J[Mission.Takeoff.GROUND_DISTANCE, @@ -402,7 +402,7 @@ def setup(self): ], promotes_inputs=[ ("mass", Mission.Summary.GROSS_MASS), - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, ('planform_area', Aircraft.Wing.AREA), ("Cl_max", Mission.Takeoff.LIFT_COEFFICIENT_MAX), ], @@ -414,7 +414,7 @@ def setup(self): promotes_inputs=[ "v_stall", Mission.Summary.GROSS_MASS, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Aircraft.Wing.AREA, Mission.Takeoff.FUEL_SIMPLE, Mission.Takeoff.LIFT_COEFFICIENT_MAX, diff --git a/aviary/mission/flops_based/phases/test/test_simplified_landing.py b/aviary/mission/flops_based/phases/test/test_simplified_landing.py index 1d011a8f7..818047cad 100644 --- a/aviary/mission/flops_based/phases/test/test_simplified_landing.py +++ b/aviary/mission/flops_based/phases/test/test_simplified_landing.py @@ -28,7 +28,9 @@ def setUp(self): Mission.Landing.TOUCHDOWN_MASS, val=152800.0, units="lbm" ) # check (this is the design landing mass) self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, val=constants.RHO_SEA_LEVEL_METRIC, units="kg/m**3" + Dynamic.Atmosphere.DENSITY, + val=constants.RHO_SEA_LEVEL_METRIC, + units="kg/m**3", ) # not exact value but should be close enough self.prob.model.set_input_defaults( Aircraft.Wing.AREA, val=1370.0, units="ft**2" diff --git a/aviary/mission/flops_based/phases/test/test_simplified_takeoff.py b/aviary/mission/flops_based/phases/test/test_simplified_takeoff.py index 588e5bc03..0496b4d91 100644 --- a/aviary/mission/flops_based/phases/test/test_simplified_takeoff.py +++ b/aviary/mission/flops_based/phases/test/test_simplified_takeoff.py @@ -32,7 +32,7 @@ def setUp(self): self.prob.model.set_input_defaults("mass", val=181200.0, units="lbm") # check self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, val=constants.RHO_SEA_LEVEL_METRIC, units="kg/m**3" + Dynamic.Atmosphere.DENSITY, val=constants.RHO_SEA_LEVEL_METRIC, units="kg/m**3" ) # check self.prob.model.set_input_defaults( "planform_area", val=1370.0, units="ft**2" @@ -104,7 +104,7 @@ def setUp(self): Mission.Takeoff.FUEL_SIMPLE, val=577, units="lbm" ) # check self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=constants.RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3", ) # check @@ -197,7 +197,8 @@ def setUp(self): self.prob.model.set_input_defaults( Mission.Takeoff.LIFT_OVER_DRAG, val=17.354, units='unitless') # check self.prob.model.set_input_defaults( - Dynamic.Mission.ALTITUDE, val=0, units="ft") # check + Dynamic.Mission.ALTITUDE, val=0, units="ft" + ) # check self.prob.setup(check=False, force_alloc_complex=True) 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 790969a39..788fe0823 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 @@ -31,7 +31,8 @@ def setUp(self): aviary_inputs, initialization_guesses = create_vehicle( 'models/test_aircraft/aircraft_for_bench_FwFm.csv') aviary_inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, val=28690, units="lbf") - aviary_inputs.set_val(Dynamic.Mission.THROTTLE, val=0, units="unitless") + aviary_inputs.set_val(Dynamic.Vehicle.Propulsion.THROTTLE, + val=0, units="unitless") aviary_inputs.set_val(Mission.Takeoff.ROLLING_FRICTION_COEFFICIENT, val=0.0175, units="unitless") aviary_inputs.set_val(Mission.Takeoff.BRAKING_FRICTION_COEFFICIENT, @@ -69,11 +70,13 @@ def setup_prob(self, phases) -> om.Problem: traj = FlexibleTraj( Phases=phases, promote_all_auto_ivc=True, - traj_final_state_output=[Dynamic.Mission.MASS, - Dynamic.Mission.DISTANCE, - Dynamic.Mission.ALTITUDE], + traj_final_state_output=[ + Dynamic.Vehicle.MASS, + Dynamic.Mission.DISTANCE, + Dynamic.Mission.ALTITUDE, + ], traj_initial_state_input=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], diff --git a/aviary/mission/flops_based/phases/time_integration_phases.py b/aviary/mission/flops_based/phases/time_integration_phases.py index 6f8f1c752..1405cfb6a 100644 --- a/aviary/mission/flops_based/phases/time_integration_phases.py +++ b/aviary/mission/flops_based/phases/time_integration_phases.py @@ -20,24 +20,25 @@ def __init__( simupy_args={}, mass_trigger=(150000, 'lbm') ): - super().__init__(MissionODE( - analysis_scheme=AnalysisScheme.SHOOTING, - **ode_args), + super().__init__( + MissionODE(analysis_scheme=AnalysisScheme.SHOOTING, **ode_args), problem_name=phase_name, outputs=[], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, - ], + ], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, aviary_options=ode_args['aviary_options'], - **simupy_args) + **simupy_args + ) self.phase_name = phase_name self.mass_trigger = mass_trigger - self.add_trigger(Dynamic.Mission.MASS, 'mass_trigger') + self.add_trigger(Dynamic.Vehicle.MASS, 'mass_trigger') class SGMDetailedTakeoff(SimuPyProblem): @@ -54,20 +55,21 @@ def __init__( phase_name='detailed_takeoff', simupy_args={}, ): - super().__init__(TakeoffODE( - analysis_scheme=AnalysisScheme.SHOOTING, - **ode_args), + super().__init__( + TakeoffODE(analysis_scheme=AnalysisScheme.SHOOTING, **ode_args), problem_name=phase_name, outputs=[], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, - ], + ], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, aviary_options=ode_args['aviary_options'], - **simupy_args) + **simupy_args + ) self.phase_name = phase_name self.add_trigger(Dynamic.Mission.ALTITUDE, 50, units='ft') @@ -87,20 +89,21 @@ def __init__( phase_name='detailed_landing', simupy_args={}, ): - super().__init__(LandingODE( - analysis_scheme=AnalysisScheme.SHOOTING, - **ode_args), + super().__init__( + LandingODE(analysis_scheme=AnalysisScheme.SHOOTING, **ode_args), problem_name=phase_name, outputs=[], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, - ], + ], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, aviary_options=ode_args['aviary_options'], - **simupy_args) + **simupy_args + ) self.phase_name = phase_name self.add_trigger(Dynamic.Mission.ALTITUDE, 0, units='ft') diff --git a/aviary/mission/gasp_based/idle_descent_estimation.py b/aviary/mission/gasp_based/idle_descent_estimation.py index be3efca5b..58a7e432b 100644 --- a/aviary/mission/gasp_based/idle_descent_estimation.py +++ b/aviary/mission/gasp_based/idle_descent_estimation.py @@ -33,12 +33,12 @@ def add_descent_estimation_as_submodel( traj = FlexibleTraj( Phases=phases, traj_initial_state_input=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], traj_final_state_output=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], @@ -158,7 +158,7 @@ def add_descent_estimation_as_submodel( model.set_input_defaults(Aircraft.CrewPayload.PASSENGER_PAYLOAD_MASS, 0) model.set_input_defaults( Aircraft.Design.OPERATING_MASS, val=0, units='lbm') - model.set_input_defaults('descent_traj.'+Dynamic.Mission.THROTTLE, 0) + model.set_input_defaults('descent_traj.' + Dynamic.Vehicle.Propulsion.THROTTLE, 0) promote_aircraft_and_mission_vars(model) diff --git a/aviary/mission/gasp_based/ode/accel_eom.py b/aviary/mission/gasp_based/ode/accel_eom.py index 04f0d3ac9..fff79efe6 100644 --- a/aviary/mission/gasp_based/ode/accel_eom.py +++ b/aviary/mission/gasp_based/ode/accel_eom.py @@ -21,19 +21,19 @@ def setup(self): arange = np.arange(nn) self.add_input( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=np.ones(nn) * 1e6, units="lbm", desc="total mass of the aircraft", ) self.add_input( - Dynamic.Mission.DRAG, + Dynamic.Vehicle.DRAG, val=np.zeros(nn), units="lbf", desc="drag on aircraft", ) self.add_input( - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.zeros(nn), units="lbf", desc="total thrust", @@ -59,28 +59,45 @@ def setup(self): ) self.declare_partials( - Dynamic.Mission.VELOCITY_RATE, [ - Dynamic.Mission.MASS, Dynamic.Mission.DRAG, Dynamic.Mission.THRUST_TOTAL], rows=arange, cols=arange) - self.declare_partials(Dynamic.Mission.DISTANCE_RATE, [ - Dynamic.Mission.VELOCITY], rows=arange, cols=arange, val=1.) + Dynamic.Mission.VELOCITY_RATE, + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ], + rows=arange, + cols=arange, + ) + self.declare_partials( + Dynamic.Mission.DISTANCE_RATE, + [Dynamic.Mission.VELOCITY], + rows=arange, + cols=arange, + val=1.0, + ) def compute(self, inputs, outputs): - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - drag = inputs[Dynamic.Mission.DRAG] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + drag = inputs[Dynamic.Vehicle.DRAG] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] TAS = inputs[Dynamic.Mission.VELOCITY] - outputs[Dynamic.Mission.VELOCITY_RATE] = ( - GRAV_ENGLISH_GASP / weight) * (thrust - drag) + outputs[Dynamic.Mission.VELOCITY_RATE] = (GRAV_ENGLISH_GASP / weight) * ( + thrust - drag + ) outputs[Dynamic.Mission.DISTANCE_RATE] = TAS def compute_partials(self, inputs, J): - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - drag = inputs[Dynamic.Mission.DRAG] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + drag = inputs[Dynamic.Vehicle.DRAG] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.MASS] = \ + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.MASS] = ( -(GRAV_ENGLISH_GASP / weight**2) * (thrust - drag) * GRAV_ENGLISH_LBM - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.DRAG] = - \ - (GRAV_ENGLISH_GASP / weight) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.THRUST_TOTAL] = GRAV_ENGLISH_GASP / weight + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.DRAG] = -( + GRAV_ENGLISH_GASP / weight + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + GRAV_ENGLISH_GASP / weight + ) diff --git a/aviary/mission/gasp_based/ode/accel_ode.py b/aviary/mission/gasp_based/ode/accel_ode.py index 1278e99c4..91781f45c 100644 --- a/aviary/mission/gasp_based/ode/accel_ode.py +++ b/aviary/mission/gasp_based/ode/accel_ode.py @@ -28,9 +28,12 @@ def setup(self): 't_curr': {'units': 's'}, Dynamic.Mission.DISTANCE: {'units': 'ft'}, }) - add_SGM_required_outputs(self, { - Dynamic.Mission.ALTITUDE_RATE: {'units': 'ft/s'}, - }) + add_SGM_required_outputs( + self, + { + Dynamic.Mission.ALTITUDE_RATE: {'units': 'ft/s'}, + }, + ) # TODO: paramport self.add_subsystem("params", ParamPort(), promotes=["*"]) @@ -40,8 +43,8 @@ def setup(self): self.add_subsystem( "calc_weight", MassToWeight(num_nodes=nn), - promotes_inputs=[("mass", Dynamic.Mission.MASS)], - promotes_outputs=["weight"] + promotes_inputs=[("mass", Dynamic.Vehicle.MASS)], + promotes_outputs=["weight"], ) kwargs = {'num_nodes': nn, 'aviary_inputs': aviary_options, @@ -58,21 +61,26 @@ def setup(self): "accel_eom", AccelerationRates(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.VELOCITY, - Dynamic.Mission.DRAG, - Dynamic.Mission.THRUST_TOTAL, ], + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ], promotes_outputs=[ Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.DISTANCE_RATE, ], + Dynamic.Mission.DISTANCE_RATE, + ], ) self.add_excess_rate_comps(nn) ParamPort.set_default_vals(self) - self.set_input_defaults(Dynamic.Mission.MASS, val=14e4 * - np.ones(nn), units="lbm") - self.set_input_defaults(Dynamic.Mission.ALTITUDE, - val=500 * np.ones(nn), units="ft") - self.set_input_defaults(Dynamic.Mission.VELOCITY, val=200*np.ones(nn), - units="m/s") # val here is nominal + self.set_input_defaults( + Dynamic.Vehicle.MASS, val=14e4 * np.ones(nn), units="lbm" + ) + self.set_input_defaults( + Dynamic.Mission.ALTITUDE, val=500 * np.ones(nn), units="ft" + ) + self.set_input_defaults( + Dynamic.Mission.VELOCITY, val=200 * np.ones(nn), units="m/s" + ) # val here is nominal diff --git a/aviary/mission/gasp_based/ode/ascent_eom.py b/aviary/mission/gasp_based/ode/ascent_eom.py index 00d379462..761ed6d9f 100644 --- a/aviary/mission/gasp_based/ode/ascent_eom.py +++ b/aviary/mission/gasp_based/ode/ascent_eom.py @@ -19,38 +19,58 @@ def initialize(self): def setup(self): nn = self.options["num_nodes"] - self.add_input(Dynamic.Mission.MASS, val=np.ones(nn), - desc="aircraft mass", units="lbm") - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.ones( - nn), desc=Dynamic.Mission.THRUST_TOTAL, units="lbf") self.add_input( - Dynamic.Mission.LIFT, + Dynamic.Vehicle.MASS, val=np.ones(nn), desc="aircraft mass", units="lbm" + ) + self.add_input( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=np.ones(nn), + desc=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.LIFT, + val=np.ones(nn), + desc=Dynamic.Vehicle.LIFT, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.DRAG, val=np.ones(nn), - desc=Dynamic.Mission.LIFT, - units="lbf") + desc=Dynamic.Vehicle.DRAG, + units="lbf", + ) self.add_input( - Dynamic.Mission.DRAG, + Dynamic.Mission.VELOCITY, val=np.ones(nn), desc="Velocity", units="ft/s" + ) + self.add_input( + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.ones(nn), - desc=Dynamic.Mission.DRAG, - units="lbf") - self.add_input(Dynamic.Mission.VELOCITY, val=np.ones(nn), - desc="Velocity", units="ft/s") - self.add_input(Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.ones(nn), - desc="flight path angle", units="rad") + desc="flight path angle", + units="rad", + ) add_aviary_input(self, Aircraft.Wing.INCIDENCE, val=0, units="deg") self.add_input("alpha", val=np.ones(nn), desc="angle of attack", units="deg") - self.add_output(Dynamic.Mission.VELOCITY_RATE, val=np.ones(nn), - desc="Velocity rate", units="ft/s**2") self.add_output( - Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, val=np.ones(nn), desc="flight path angle rate", units="rad/s" + Dynamic.Mission.VELOCITY_RATE, + val=np.ones(nn), + desc="Velocity rate", + units="ft/s**2", + ) + self.add_output( + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + val=np.ones(nn), + desc="flight path angle rate", + units="rad/s", ) self.add_output( Dynamic.Mission.ALTITUDE_RATE, val=np.ones(nn), desc="altitude rate", - units="ft/s") + units="ft/s", + ) self.add_output( Dynamic.Mission.DISTANCE_RATE, val=np.ones(nn), desc="distance rate", units="ft/s" ) @@ -71,17 +91,29 @@ def setup_partials(self): self.declare_partials( Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, - [Dynamic.Mission.THRUST_TOTAL, "alpha", - Dynamic.Mission.LIFT, Dynamic.Mission.MASS, Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY], + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Mission.VELOCITY, + ], rows=arange, cols=arange, ) - self.declare_partials(Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, [ - Aircraft.Wing.INCIDENCE]) + self.declare_partials( + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, [Aircraft.Wing.INCIDENCE] + ) self.declare_partials( "load_factor", - [Dynamic.Mission.LIFT, Dynamic.Mission.MASS, - Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.THRUST_TOTAL, "alpha"], + [ + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + ], rows=arange, cols=arange, ) @@ -89,38 +121,57 @@ def setup_partials(self): self.declare_partials( Dynamic.Mission.VELOCITY_RATE, - [Dynamic.Mission.THRUST_TOTAL, "alpha", Dynamic.Mission.DRAG, - Dynamic.Mission.MASS, Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.LIFT], + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Vehicle.LIFT, + ], rows=arange, cols=arange, ) self.declare_partials(Dynamic.Mission.VELOCITY_RATE, [Aircraft.Wing.INCIDENCE]) self.declare_partials( - Dynamic.Mission.ALTITUDE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange) + Dynamic.Mission.ALTITUDE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, + ) self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange + Dynamic.Mission.DISTANCE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, ) self.declare_partials( "normal_force", - [Dynamic.Mission.MASS, Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, "alpha"], + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + ], rows=arange, cols=arange, ) self.declare_partials("normal_force", [Aircraft.Wing.INCIDENCE]) self.declare_partials( - "fuselage_pitch", Dynamic.Mission.FLIGHT_PATH_ANGLE, rows=arange, cols=arange, val=180 / np.pi, + "fuselage_pitch", + Dynamic.Mission.FLIGHT_PATH_ANGLE, + rows=arange, + cols=arange, + val=180 / np.pi, ) self.declare_partials("fuselage_pitch", "alpha", rows=arange, cols=arange, val=1) self.declare_partials("fuselage_pitch", Aircraft.Wing.INCIDENCE, val=-1) def compute(self, inputs, outputs): - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -168,10 +219,10 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): nn = self.options["num_nodes"] - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -191,17 +242,25 @@ def compute_partials(self, inputs, J): dTAcF_dAlpha = thrust * np.cos((alpha - i_wing) * np.pi / 180) * np.pi / 180 dTAcF_dIwing = -thrust * np.cos((alpha - i_wing) * np.pi / 180) * np.pi / 180 - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.THRUST_TOTAL] = dTAcF_dThrust * \ - GRAV_ENGLISH_GASP / (TAS * weight) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, "alpha"] = dTAcF_dAlpha * \ - GRAV_ENGLISH_GASP / (TAS * weight) + J[ + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ] = ( + dTAcF_dThrust * GRAV_ENGLISH_GASP / (TAS * weight) + ) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, "alpha"] = ( + dTAcF_dAlpha * GRAV_ENGLISH_GASP / (TAS * weight) + ) J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Aircraft.Wing.INCIDENCE] = ( dTAcF_dIwing * GRAV_ENGLISH_GASP / (TAS * weight) ) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, - Dynamic.Mission.LIFT] = GRAV_ENGLISH_GASP / (TAS * weight) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.MASS] = (GRAV_ENGLISH_GASP / TAS) * GRAV_ENGLISH_LBM * ( - -thrust_across_flightpath / weight**2 - incremented_lift / weight**2 + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Vehicle.LIFT] = ( + GRAV_ENGLISH_GASP / (TAS * weight) + ) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Vehicle.MASS] = ( + (GRAV_ENGLISH_GASP / TAS) + * GRAV_ENGLISH_LBM + * (-thrust_across_flightpath / weight**2 - incremented_lift / weight**2) ) J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( weight * np.sin(gamma) * GRAV_ENGLISH_GASP / (TAS * weight) @@ -212,17 +271,20 @@ def compute_partials(self, inputs, J): / (TAS**2 * weight) ) - J["load_factor", Dynamic.Mission.LIFT] = 1 / (weight * np.cos(gamma)) - J["load_factor", Dynamic.Mission.MASS] = -(incremented_lift + thrust_across_flightpath) / ( - weight**2 * np.cos(gamma) - ) * GRAV_ENGLISH_LBM + J["load_factor", Dynamic.Vehicle.LIFT] = 1 / (weight * np.cos(gamma)) + J["load_factor", Dynamic.Vehicle.MASS] = ( + -(incremented_lift + thrust_across_flightpath) + / (weight**2 * np.cos(gamma)) + * GRAV_ENGLISH_LBM + ) J["load_factor", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( -(incremented_lift + thrust_across_flightpath) / (weight * (np.cos(gamma)) ** 2) * (-np.sin(gamma)) ) - J["load_factor", Dynamic.Mission.THRUST_TOTAL] = dTAcF_dThrust / \ - (weight * np.cos(gamma)) + J["load_factor", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = dTAcF_dThrust / ( + weight * np.cos(gamma) + ) J["load_factor", "alpha"] = dTAcF_dAlpha / (weight * np.cos(gamma)) J["load_factor", Aircraft.Wing.INCIDENCE] = dTAcF_dIwing / ( weight * np.cos(gamma) @@ -246,7 +308,7 @@ def compute_partials(self, inputs, J): dNF_dIwing = -np.ones(nn) * dTAcF_dIwing dNF_dIwing[normal_force1 < 0] = 0 - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.THRUST_TOTAL] = ( + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( (dTAlF_dThrust - mu * dNF_dThrust) * GRAV_ENGLISH_GASP / weight ) J[Dynamic.Mission.VELOCITY_RATE, "alpha"] = ( @@ -255,9 +317,12 @@ def compute_partials(self, inputs, J): J[Dynamic.Mission.VELOCITY_RATE, Aircraft.Wing.INCIDENCE] = ( (dTAlF_dIwing - mu * dNF_dIwing) * GRAV_ENGLISH_GASP / weight ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.DRAG] = -GRAV_ENGLISH_GASP / weight - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.MASS] = ( - GRAV_ENGLISH_GASP * GRAV_ENGLISH_LBM + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.DRAG] = ( + -GRAV_ENGLISH_GASP / weight + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.MASS] = ( + GRAV_ENGLISH_GASP + * GRAV_ENGLISH_LBM * ( weight * (-np.sin(gamma) - mu * dNF_dWeight) - ( @@ -269,21 +334,25 @@ def compute_partials(self, inputs, J): ) / weight**2 ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = - \ - np.cos(gamma) * GRAV_ENGLISH_GASP - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.LIFT] = GRAV_ENGLISH_GASP * \ - (-mu * dNF_dLift) / weight + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -np.cos(gamma) * GRAV_ENGLISH_GASP + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.LIFT] = ( + GRAV_ENGLISH_GASP * (-mu * dNF_dLift) / weight + ) J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = np.sin(gamma) - J[Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = TAS * np.cos(gamma) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + TAS * np.cos(gamma) + ) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = np.cos(gamma) - J[Dynamic.Mission.DISTANCE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = -TAS * np.sin(gamma) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -TAS * np.sin(gamma) + ) - J["normal_force", Dynamic.Mission.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM - J["normal_force", Dynamic.Mission.LIFT] = dNF_dLift - J["normal_force", Dynamic.Mission.THRUST_TOTAL] = dNF_dThrust + J["normal_force", Dynamic.Vehicle.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM + J["normal_force", Dynamic.Vehicle.LIFT] = dNF_dLift + J["normal_force", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = dNF_dThrust J["normal_force", "alpha"] = dNF_dAlpha J["normal_force", Aircraft.Wing.INCIDENCE] = dNF_dIwing diff --git a/aviary/mission/gasp_based/ode/ascent_ode.py b/aviary/mission/gasp_based/ode/ascent_ode.py index 452ea4bcd..9e1fe8d31 100644 --- a/aviary/mission/gasp_based/ode/ascent_ode.py +++ b/aviary/mission/gasp_based/ode/ascent_ode.py @@ -30,10 +30,13 @@ def setup(self): # TODO: paramport ascent_params = ParamPort() if analysis_scheme is AnalysisScheme.SHOOTING: - add_SGM_required_inputs(self, { - Dynamic.Mission.ALTITUDE: {'units': 'ft'}, - Dynamic.Mission.DISTANCE: {'units': 'ft'}, - }) + add_SGM_required_inputs( + self, + { + Dynamic.Mission.ALTITUDE: {'units': 'ft'}, + Dynamic.Mission.DISTANCE: {'units': 'ft'}, + }, + ) ascent_params.add_params({ Aircraft.Design.MAX_FUSELAGE_PITCH_ANGLE: dict(units='deg', val=0), @@ -62,14 +65,15 @@ def setup(self): "ascent_eom", AscentEOM(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.MASS, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.LIFT, - Dynamic.Mission.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.DRAG, Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE, "alpha", - ] + ["aircraft:*"], + ] + + ["aircraft:*"], promotes_outputs=[ Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, @@ -88,8 +92,9 @@ def setup(self): self.set_input_defaults("t_init_flaps", val=47.5) self.set_input_defaults("t_init_gear", val=37.3) self.set_input_defaults("alpha", val=np.zeros(nn), units="deg") - self.set_input_defaults(Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units="deg") + self.set_input_defaults( + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units="deg" + ) self.set_input_defaults(Dynamic.Mission.ALTITUDE, val=np.zeros(nn), units="ft") self.set_input_defaults(Dynamic.Mission.VELOCITY, val=np.zeros(nn), units="kn") self.set_input_defaults("t_curr", val=np.zeros(nn), units="s") @@ -97,5 +102,6 @@ def setup(self): self.set_input_defaults('aero_ramps.gear_factor:final_val', val=0.) self.set_input_defaults('aero_ramps.flap_factor:initial_val', val=1.) self.set_input_defaults('aero_ramps.gear_factor:initial_val', val=1.) - self.set_input_defaults(Dynamic.Mission.MASS, val=np.ones( - nn), units='kg') # val here is nominal + self.set_input_defaults( + Dynamic.Vehicle.MASS, val=np.ones(nn), units='kg' + ) # val here is nominal diff --git a/aviary/mission/gasp_based/ode/base_ode.py b/aviary/mission/gasp_based/ode/base_ode.py index 9aad746bd..c5321484e 100644 --- a/aviary/mission/gasp_based/ode/base_ode.py +++ b/aviary/mission/gasp_based/ode/base_ode.py @@ -94,9 +94,11 @@ def AddAlphaControl( gamma=dict(val=0., units='deg'), i_wing=dict(val=0., units='deg'), ) - alpha_comp_inputs = [("max_fus_angle", Aircraft.Design.MAX_FUSELAGE_PITCH_ANGLE), - ("gamma", Dynamic.Mission.FLIGHT_PATH_ANGLE), - ("i_wing", Aircraft.Wing.INCIDENCE)] + alpha_comp_inputs = [ + ("max_fus_angle", Aircraft.Design.MAX_FUSELAGE_PITCH_ANGLE), + ("gamma", Dynamic.Mission.FLIGHT_PATH_ANGLE), + ("i_wing", Aircraft.Wing.INCIDENCE), + ] elif alpha_mode is AlphaModes.DECELERATION: alpha_comp = om.BalanceComp( @@ -107,8 +109,8 @@ def AddAlphaControl( rhs_name='target_tas_rate', rhs_val=target_tas_rate, eq_units="kn/s", - upper=25., - lower=-2., + upper=25.0, + lower=-2.0, ) alpha_comp_inputs = [Dynamic.Mission.VELOCITY_RATE] @@ -118,12 +120,12 @@ def AddAlphaControl( val=8.0 * np.ones(nn), units="deg", rhs_name="required_lift", - lhs_name=Dynamic.Mission.LIFT, + lhs_name=Dynamic.Vehicle.LIFT, eq_units="lbf", upper=12.0, lower=-2, ) - alpha_comp_inputs = ["required_lift", Dynamic.Mission.LIFT] + alpha_comp_inputs = ["required_lift", Dynamic.Vehicle.LIFT] # Future controller modes # elif alpha_mode is AlphaModes.FLIGHT_PATH_ANGLE: @@ -198,21 +200,24 @@ def AddThrottleControl( nn = num_nodes thrust_bal = om.BalanceComp( - name=Dynamic.Mission.THROTTLE, + name=Dynamic.Vehicle.Propulsion.THROTTLE, val=np.ones(nn), upper=1.0, lower=0.0, units='unitless', - lhs_name=Dynamic.Mission.THRUST_TOTAL, + lhs_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, rhs_name="required_thrust", eq_units="lbf", ) - prop_group.add_subsystem("thrust_balance", - thrust_bal, - promotes_inputs=[ - Dynamic.Mission.THRUST_TOTAL, 'required_thrust'], - promotes_outputs=[Dynamic.Mission.THROTTLE], - ) + prop_group.add_subsystem( + "thrust_balance", + thrust_bal, + promotes_inputs=[ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + 'required_thrust', + ], + promotes_outputs=[Dynamic.Vehicle.Propulsion.THROTTLE], + ) if add_default_solver: prop_group.linear_solver = om.DirectSolver() @@ -248,21 +253,35 @@ def add_excess_rate_comps(self, nn): self.add_subsystem( name='SPECIFIC_ENERGY_RATE_EXCESS', subsys=SpecificEnergyRate(num_nodes=nn), - promotes_inputs=[Dynamic.Mission.VELOCITY, Dynamic.Mission.MASS, - (Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.THRUST_MAX_TOTAL), - Dynamic.Mission.DRAG], - promotes_outputs=[(Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS)] + promotes_inputs=[ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.MASS, + ( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + ), + Dynamic.Vehicle.DRAG, + ], + promotes_outputs=[ + ( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + ) + ], ) self.add_subsystem( name='ALTITUDE_RATE_MAX', subsys=AltitudeRate(num_nodes=nn), promotes_inputs=[ - (Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS), + ( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + ), Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.VELOCITY], + Dynamic.Mission.VELOCITY, + ], promotes_outputs=[ - (Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.ALTITUDE_RATE_MAX)]) + (Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.ALTITUDE_RATE_MAX) + ], + ) diff --git a/aviary/mission/gasp_based/ode/breguet_cruise_eom.py b/aviary/mission/gasp_based/ode/breguet_cruise_eom.py index 1f77f98ed..00ad43505 100644 --- a/aviary/mission/gasp_based/ode/breguet_cruise_eom.py +++ b/aviary/mission/gasp_based/ode/breguet_cruise_eom.py @@ -27,7 +27,7 @@ def setup(self): self.add_input("mass", val=150000 * np.ones(nn), units="lbm", desc="mass at each node, monotonically nonincreasing") - self.add_input(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + self.add_input(Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, 0.74 * np.ones(nn), units="lbm/h") self.add_output("cruise_time", shape=(nn,), units="s", desc="time in cruise", @@ -64,9 +64,25 @@ def setup_partials(self): self._tril_rs, self._tril_cs = rs, cs self.declare_partials( - "cruise_range", [Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, "mass", "TAS_cruise"], rows=rs, cols=cs) + "cruise_range", + [ + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + "mass", + "TAS_cruise", + ], + rows=rs, + cols=cs, + ) self.declare_partials( - "cruise_time", [Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, "mass", "TAS_cruise"], rows=rs, cols=cs) + "cruise_time", + [ + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + "mass", + "TAS_cruise", + ], + rows=rs, + cols=cs, + ) self.declare_partials("cruise_range", "cruise_distance_initial", val=1.0) self.declare_partials("cruise_time", "cruise_time_initial", val=1.0) @@ -81,7 +97,7 @@ def setup_partials(self): def compute(self, inputs, outputs): v_x = inputs["TAS_cruise"] m = inputs["mass"] - FF = -inputs[Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL] + FF = -inputs[Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL] r0 = inputs["cruise_distance_initial"] t0 = inputs["cruise_time_initial"] r0 = r0[0] @@ -121,7 +137,7 @@ def compute_partials(self, inputs, J): W1 = m[:-1] * GRAV_ENGLISH_LBM W2 = m[1:] * GRAV_ENGLISH_LBM # Final mass across each two-node pair - FF = -inputs[Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL] + FF = -inputs[Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL] FF_1 = FF[:-1] # Initial fuel flow across each two-node pair FF_2 = FF[1:] # Final fuel flow across each two_node pair @@ -161,8 +177,9 @@ def compute_partials(self, inputs, J): np.fill_diagonal(self._scratch_nn_x_nn[1:, :-1], dRange_dFF1) np.fill_diagonal(self._scratch_nn_x_nn[1:, 1:], dRange_dFF2) - J["cruise_range", Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL][...] = \ - (self._d_cumsum_dx @ self._scratch_nn_x_nn)[self._tril_rs, self._tril_cs] + J["cruise_range", Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL][ + ... + ] = (self._d_cumsum_dx @ self._scratch_nn_x_nn)[self._tril_rs, self._tril_cs] # WRT Mass: dRange_dm = dRange_dW * dW_dm np.fill_diagonal(self._scratch_nn_x_nn[1:, :-1], @@ -186,9 +203,15 @@ def compute_partials(self, inputs, J): # But the jacobian is in a flat format in row-major order. The rows associated # with the nonzero elements are stored in self._tril_rs. - J["cruise_time", Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL][1:] = \ - J["cruise_range", Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL][1:] / \ - vx_m[self._tril_rs[1:] - 1] * 6076.1 + J["cruise_time", Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL][ + 1: + ] = ( + J["cruise_range", Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL][ + 1: + ] + / vx_m[self._tril_rs[1:] - 1] + * 6076.1 + ) J["cruise_time", "mass"][1:] = \ J["cruise_range", "mass"][1:] / vx_m[self._tril_rs[1:] - 1] * 6076.1 diff --git a/aviary/mission/gasp_based/ode/breguet_cruise_ode.py b/aviary/mission/gasp_based/ode/breguet_cruise_ode.py index 6af356f29..19a9c8094 100644 --- a/aviary/mission/gasp_based/ode/breguet_cruise_ode.py +++ b/aviary/mission/gasp_based/ode/breguet_cruise_ode.py @@ -58,13 +58,13 @@ def setup(self): promotes_outputs=subsystem.mission_outputs(**kwargs)) bal = om.BalanceComp( - name=Dynamic.Mission.THROTTLE, + name=Dynamic.Vehicle.Propulsion.THROTTLE, val=np.ones(nn), upper=1.0, lower=0.0, units="unitless", - lhs_name=Dynamic.Mission.THRUST_TOTAL, - rhs_name=Dynamic.Mission.DRAG, + lhs_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + rhs_name=Dynamic.Vehicle.DRAG, eq_units="lbf", ) @@ -104,39 +104,54 @@ def setup(self): ("cruise_distance_initial", "initial_distance"), ("cruise_time_initial", "initial_time"), "mass", - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, ("TAS_cruise", Dynamic.Mission.VELOCITY), ], - promotes_outputs=[("cruise_range", Dynamic.Mission.DISTANCE), - ("cruise_time", "time")], + promotes_outputs=[ + ("cruise_range", Dynamic.Mission.DISTANCE), + ("cruise_time", "time"), + ], ) self.add_subsystem( name='SPECIFIC_ENERGY_RATE_EXCESS', subsys=SpecificEnergyRate(num_nodes=nn), - promotes_inputs=[Dynamic.Mission.VELOCITY, Dynamic.Mission.MASS, - (Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.THRUST_MAX_TOTAL), - Dynamic.Mission.DRAG], - promotes_outputs=[(Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS)] + promotes_inputs=[ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.MASS, + ( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + ), + Dynamic.Vehicle.DRAG, + ], + promotes_outputs=[ + ( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + ) + ], ) self.add_subsystem( name='ALTITUDE_RATE_MAX', subsys=AltitudeRate(num_nodes=nn), promotes_inputs=[ - (Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS), + ( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + ), Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.VELOCITY], + Dynamic.Mission.VELOCITY, + ], promotes_outputs=[ - (Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.ALTITUDE_RATE_MAX)]) + (Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.ALTITUDE_RATE_MAX) + ], + ) ParamPort.set_default_vals(self) self.set_input_defaults( - Dynamic.Mission.ALTITUDE, - val=37500 * np.ones(nn), - units="ft") + Dynamic.Mission.ALTITUDE, val=37500 * np.ones(nn), units="ft" + ) self.set_input_defaults("mass", val=np.linspace( 171481, 171581 - 10000, nn), units="lbm") diff --git a/aviary/mission/gasp_based/ode/climb_eom.py b/aviary/mission/gasp_based/ode/climb_eom.py index 63120bce7..fcd95977d 100644 --- a/aviary/mission/gasp_based/ode/climb_eom.py +++ b/aviary/mission/gasp_based/ode/climb_eom.py @@ -27,15 +27,15 @@ def setup(self): desc="true air speed", ) - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.zeros(nn), + self.add_input(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.zeros(nn), units="lbf", desc="net thrust") self.add_input( - Dynamic.Mission.DRAG, + Dynamic.Vehicle.DRAG, val=np.zeros(nn), units="lbf", desc="net drag on aircraft") self.add_input( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=np.zeros(nn), units="lbm", desc="mass of aircraft", @@ -66,39 +66,55 @@ def setup(self): desc="flight path angle", ) - self.declare_partials(Dynamic.Mission.ALTITUDE_RATE, - [Dynamic.Mission.VELOCITY, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, - Dynamic.Mission.MASS], - rows=arange, - cols=arange) + self.declare_partials( + Dynamic.Mission.ALTITUDE_RATE, + [ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + ], + rows=arange, + cols=arange, + ) self.declare_partials( Dynamic.Mission.DISTANCE_RATE, - [Dynamic.Mission.VELOCITY, Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, Dynamic.Mission.MASS], + [ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + ], + rows=arange, + cols=arange, + ) + self.declare_partials( + "required_lift", + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], + rows=arange, + cols=arange, + ) + self.declare_partials( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + ], rows=arange, cols=arange, ) - self.declare_partials("required_lift", - [Dynamic.Mission.MASS, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], - rows=arange, - cols=arange) - self.declare_partials(Dynamic.Mission.FLIGHT_PATH_ANGLE, - [Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, - Dynamic.Mission.MASS], - rows=arange, - cols=arange) def compute(self, inputs, outputs): TAS = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM gamma = np.arcsin((thrust - drag) / weight) @@ -110,9 +126,9 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): TAS = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM gamma = np.arcsin((thrust - drag) / weight) @@ -125,29 +141,37 @@ def compute_partials(self, inputs, J): ) J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = np.sin(gamma) - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.THRUST_TOTAL] = TAS * \ - np.cos(gamma) * dGamma_dThrust - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.DRAG] = TAS * \ - np.cos(gamma) * dGamma_dDrag - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.MASS] = \ + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + TAS * np.cos(gamma) * dGamma_dThrust + ) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Vehicle.DRAG] = ( + TAS * np.cos(gamma) * dGamma_dDrag + ) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Vehicle.MASS] = ( TAS * np.cos(gamma) * dGamma_dWeight * GRAV_ENGLISH_LBM + ) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = np.cos(gamma) - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.THRUST_TOTAL] = - \ - TAS * np.sin(gamma) * dGamma_dThrust - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.DRAG] = - \ + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + -TAS * np.sin(gamma) * dGamma_dThrust + ) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Vehicle.DRAG] = - \ TAS * np.sin(gamma) * dGamma_dDrag - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.MASS] = \ + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Vehicle.MASS] = \ -TAS * np.sin(gamma) * dGamma_dWeight * GRAV_ENGLISH_LBM - J["required_lift", Dynamic.Mission.MASS] = ( + J["required_lift", Dynamic.Vehicle.MASS] = ( np.cos(gamma) - weight * np.sin(gamma) * dGamma_dWeight ) * GRAV_ENGLISH_LBM - J["required_lift", Dynamic.Mission.THRUST_TOTAL] = - \ - weight * np.sin(gamma) * dGamma_dThrust - J["required_lift", Dynamic.Mission.DRAG] = -weight * np.sin(gamma) * dGamma_dDrag - - J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.THRUST_TOTAL] = dGamma_dThrust - J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.DRAG] = dGamma_dDrag - J[Dynamic.Mission.FLIGHT_PATH_ANGLE, - Dynamic.Mission.MASS] = dGamma_dWeight * GRAV_ENGLISH_LBM + J["required_lift", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + -weight * np.sin(gamma) * dGamma_dThrust + ) + J["required_lift", Dynamic.Vehicle.DRAG] = -weight * np.sin(gamma) * dGamma_dDrag + + J[ + Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL + ] = dGamma_dThrust + J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Vehicle.DRAG] = dGamma_dDrag + J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Vehicle.MASS] = ( + dGamma_dWeight * GRAV_ENGLISH_LBM + ) diff --git a/aviary/mission/gasp_based/ode/climb_ode.py b/aviary/mission/gasp_based/ode/climb_ode.py index 42c233736..19f17677e 100644 --- a/aviary/mission/gasp_based/ode/climb_ode.py +++ b/aviary/mission/gasp_based/ode/climb_ode.py @@ -5,13 +5,17 @@ from aviary.subsystems.atmosphere.flight_conditions import FlightConditions from aviary.mission.gasp_based.ode.base_ode import BaseODE from aviary.mission.gasp_based.ode.climb_eom import ClimbRates -from aviary.mission.gasp_based.ode.constraints.flight_constraints import FlightConstraints +from aviary.mission.gasp_based.ode.constraints.flight_constraints import ( + FlightConstraints, +) from aviary.mission.gasp_based.ode.constraints.speed_constraints import SpeedConstraints from aviary.mission.gasp_based.ode.params import ParamPort from aviary.subsystems.aerodynamics.aerodynamics_builder import AerodynamicsBuilderBase from aviary.variable_info.enums import AnalysisScheme, AlphaModes, SpeedType -from aviary.variable_info.variables import Dynamic -from aviary.mission.gasp_based.ode.time_integration_base_classes import add_SGM_required_inputs +from aviary.variable_info.variables import Aircraft, Dynamic +from aviary.mission.gasp_based.ode.time_integration_base_classes import ( + add_SGM_required_inputs, +) class ClimbODE(BaseODE): @@ -23,14 +27,28 @@ class ClimbODE(BaseODE): def initialize(self): super().initialize() - self.options.declare("input_speed_type", default=SpeedType.EAS, types=SpeedType, - desc="Whether the speed is given as a equivalent airspeed, true airspeed, or mach number") - self.options.declare("alt_trigger_units", default='ft', - desc='The units that the altitude trigger is provided in') - self.options.declare("speed_trigger_units", default='kn', - desc='The units that the speed trigger is provided in.') - self.options.declare("input_speed_type", default=SpeedType.EAS, types=SpeedType, - desc="Whether the speed is given as a equivalent airspeed, true airspeed, or mach number") + self.options.declare( + "input_speed_type", + default=SpeedType.EAS, + types=SpeedType, + desc="Whether the speed is given as a equivalent airspeed, true airspeed, or mach number", + ) + self.options.declare( + "alt_trigger_units", + default='ft', + desc='The units that the altitude trigger is provided in', + ) + self.options.declare( + "speed_trigger_units", + default='kn', + desc='The units that the speed trigger is provided in.', + ) + self.options.declare( + "input_speed_type", + default=SpeedType.EAS, + types=SpeedType, + desc="Whether the speed is given as a equivalent airspeed, true airspeed, or mach number", + ) self.options.declare("EAS_target", desc="target climbing EAS in knots") self.options.declare( "mach_cruise", default=0, desc="targeted cruise mach number" @@ -52,12 +70,21 @@ def setup(self): speed_outputs = ["EAS", Dynamic.Mission.VELOCITY] if analysis_scheme is AnalysisScheme.SHOOTING: - add_SGM_required_inputs(self, { - 't_curr': {'units': 's'}, - Dynamic.Mission.DISTANCE: {'units': 'ft'}, - 'alt_trigger': {'units': self.options['alt_trigger_units'], 'val': 10e3}, - 'speed_trigger': {'units': self.options['speed_trigger_units'], 'val': 100}, - }) + add_SGM_required_inputs( + self, + { + 't_curr': {'units': 's'}, + Dynamic.Mission.DISTANCE: {'units': 'ft'}, + 'alt_trigger': { + 'units': self.options['alt_trigger_units'], + 'val': 10e3, + }, + 'speed_trigger': { + 'units': self.options['speed_trigger_units'], + 'val': 100, + }, + }, + ) # TODO: paramport self.add_subsystem("params", ParamPort(), promotes=["*"]) @@ -67,10 +94,10 @@ def setup(self): subsys=Atmosphere(num_nodes=nn), promotes_inputs=[Dynamic.Mission.ALTITUDE], promotes_outputs=[ - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, "viscosity", ], ) @@ -95,7 +122,7 @@ def setup(self): SpeedConstraints( num_nodes=nn, EAS_target=EAS_target, mach_cruise=mach_cruise ), - promotes_inputs=["EAS", Dynamic.Mission.MACH], + promotes_inputs=["EAS", Dynamic.Atmosphere.MACH], promotes_outputs=["speed_constraint"], ) mach_balance_group.add_subsystem( @@ -133,29 +160,33 @@ def setup(self): flight_condition_group.add_subsystem( name='flight_conditions', subsys=FlightConditions(num_nodes=nn, input_speed_type=input_speed_type), - promotes_inputs=[Dynamic.Mission.DENSITY, Dynamic.Mission.SPEED_OF_SOUND] + promotes_inputs=[ + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + ] + speed_inputs, - promotes_outputs=[Dynamic.Mission.DYNAMIC_PRESSURE] + speed_outputs, + promotes_outputs=[Dynamic.Atmosphere.DYNAMIC_PRESSURE] + speed_outputs, ) - kwargs = {'num_nodes': nn, 'aviary_inputs': aviary_options, - 'method': 'cruise'} + kwargs = {'num_nodes': nn, 'aviary_inputs': aviary_options, 'method': 'cruise'} # collect the propulsion group names for later use with for subsystem in core_subsystems: system = subsystem.build_mission(**kwargs) if system is not None: if isinstance(subsystem, AerodynamicsBuilderBase): - lift_balance_group.add_subsystem(subsystem.name, - system, - promotes_inputs=subsystem.mission_inputs( - **kwargs), - promotes_outputs=subsystem.mission_outputs(**kwargs)) + lift_balance_group.add_subsystem( + subsystem.name, + system, + promotes_inputs=subsystem.mission_inputs(**kwargs), + promotes_outputs=subsystem.mission_outputs(**kwargs), + ) else: - self.add_subsystem(subsystem.name, - system, - promotes_inputs=subsystem.mission_inputs( - **kwargs), - promotes_outputs=subsystem.mission_outputs(**kwargs)) + self.add_subsystem( + subsystem.name, + system, + promotes_inputs=subsystem.mission_inputs(**kwargs), + promotes_outputs=subsystem.mission_outputs(**kwargs), + ) # maybe replace this with the solver in AddAlphaControl? lift_balance_group.nonlinear_solver = om.NewtonSolver() @@ -170,10 +201,10 @@ def setup(self): "climb_eom", ClimbRates(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.VELOCITY, - Dynamic.Mission.DRAG, - Dynamic.Mission.THRUST_TOTAL + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, ], promotes_outputs=[ Dynamic.Mission.ALTITUDE_RATE, @@ -187,17 +218,18 @@ def setup(self): alpha_group=lift_balance_group, alpha_mode=AlphaModes.REQUIRED_LIFT, add_default_solver=False, - num_nodes=nn) + num_nodes=nn, + ) self.add_subsystem( "constraints", FlightConstraints(num_nodes=nn), promotes_inputs=[ "alpha", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, "CL_max", Dynamic.Mission.FLIGHT_PATH_ANGLE, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.VELOCITY, ] + ["aircraft:*"], @@ -209,12 +241,14 @@ def setup(self): ParamPort.set_default_vals(self) self.set_input_defaults("CL_max", val=5 * np.ones(nn), units="unitless") - self.set_input_defaults(Dynamic.Mission.ALTITUDE, - val=500 * np.ones(nn), units='ft') - self.set_input_defaults(Dynamic.Mission.MASS, - val=174000 * np.ones(nn), units='lbm') - self.set_input_defaults(Dynamic.Mission.MACH, - val=0 * np.ones(nn), units="unitless") - - from aviary.variable_info.variables import Aircraft + self.set_input_defaults( + Dynamic.Mission.ALTITUDE, val=500 * np.ones(nn), units='ft' + ) + self.set_input_defaults( + Dynamic.Vehicle.MASS, val=174000 * np.ones(nn), units='lbm' + ) + self.set_input_defaults( + Dynamic.Atmosphere.MACH, val=0 * np.ones(nn), units="unitless" + ) + self.set_input_defaults(Aircraft.Wing.AREA, val=1.0, units="ft**2") diff --git a/aviary/mission/gasp_based/ode/constraints/flight_constraints.py b/aviary/mission/gasp_based/ode/constraints/flight_constraints.py index 7cc0039e1..2c3e6f2d0 100644 --- a/aviary/mission/gasp_based/ode/constraints/flight_constraints.py +++ b/aviary/mission/gasp_based/ode/constraints/flight_constraints.py @@ -25,7 +25,7 @@ def setup(self): arange = np.arange(nn) self.add_input( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=np.ones(nn), units="lbm", desc="mass of aircraft", @@ -35,7 +35,7 @@ def setup(self): add_aviary_input( self, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=np.ones(nn), units="slug/ft**3", desc="density of air", @@ -85,7 +85,11 @@ def setup(self): self.add_output("TAS_min", val=np.zeros(nn), units="ft/s") self.declare_partials( - "theta", [Dynamic.Mission.FLIGHT_PATH_ANGLE, "alpha"], rows=arange, cols=arange) + "theta", + [Dynamic.Mission.FLIGHT_PATH_ANGLE, "alpha"], + rows=arange, + cols=arange, + ) self.declare_partials( "theta", [ @@ -95,8 +99,8 @@ def setup(self): self.declare_partials( "TAS_violation", [ - Dynamic.Mission.MASS, - Dynamic.Mission.DENSITY, + Dynamic.Vehicle.MASS, + Dynamic.Atmosphere.DENSITY, "CL_max", Dynamic.Mission.VELOCITY, ], @@ -111,7 +115,7 @@ def setup(self): ) self.declare_partials( "TAS_min", - [Dynamic.Mission.MASS, Dynamic.Mission.DENSITY, "CL_max"], + [Dynamic.Vehicle.MASS, Dynamic.Atmosphere.DENSITY, "CL_max"], rows=arange, cols=arange, ) @@ -124,9 +128,9 @@ def setup(self): def compute(self, inputs, outputs): - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM wing_area = inputs[Aircraft.Wing.AREA] - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] CL_max = inputs["CL_max"] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -144,9 +148,9 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM wing_area = inputs[Aircraft.Wing.AREA] - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] CL_max = inputs["CL_max"] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -157,11 +161,11 @@ def compute_partials(self, inputs, J): J["theta", "alpha"] = 1 J["theta", Aircraft.Wing.INCIDENCE] = -1 - J["TAS_violation", Dynamic.Mission.MASS] = ( + J["TAS_violation", Dynamic.Vehicle.MASS] = ( 1.1 * 0.5 * (2 / (wing_area * rho * CL_max)) ** 0.5 * weight ** (-0.5) * GRAV_ENGLISH_LBM ) - J["TAS_violation", Dynamic.Mission.DENSITY] = ( + J["TAS_violation", Dynamic.Atmosphere.DENSITY] = ( 1.1 * (2 * weight / (wing_area * CL_max)) ** 0.5 * (-0.5) * rho ** (-1.5) ) J["TAS_violation", "CL_max"] = ( @@ -172,11 +176,11 @@ def compute_partials(self, inputs, J): 1.1 * (2 * weight / (rho * CL_max)) ** 0.5 * (-0.5) * wing_area ** (-1.5) ) - J["TAS_min", Dynamic.Mission.MASS] = 1.1 * ( + J["TAS_min", Dynamic.Vehicle.MASS] = 1.1 * ( 0.5 * (2 / (wing_area * rho * CL_max)) ** 0.5 * weight ** (-0.5) * GRAV_ENGLISH_LBM ) - J["TAS_min", Dynamic.Mission.DENSITY] = 1.1 * ( + J["TAS_min", Dynamic.Atmosphere.DENSITY] = 1.1 * ( (2 * weight / (wing_area * CL_max)) ** 0.5 * (-0.5) * rho ** (-1.5) ) J["TAS_min", "CL_max"] = 1.1 * ( @@ -194,8 +198,7 @@ class ClimbAtTopOfClimb(om.ExplicitComponent): def setup(self): self.add_input(Dynamic.Mission.VELOCITY, units="ft/s", val=-200) - self.add_input( - Dynamic.Mission.FLIGHT_PATH_ANGLE, units="rad", val=0.) + self.add_input(Dynamic.Mission.FLIGHT_PATH_ANGLE, units="rad", val=0.0) self.add_output("ROC", units="ft/s") self.declare_partials("*", "*") diff --git a/aviary/mission/gasp_based/ode/constraints/speed_constraints.py b/aviary/mission/gasp_based/ode/constraints/speed_constraints.py index d3540a45c..f171026a0 100644 --- a/aviary/mission/gasp_based/ode/constraints/speed_constraints.py +++ b/aviary/mission/gasp_based/ode/constraints/speed_constraints.py @@ -32,7 +32,7 @@ def setup(self): desc="equivalent airspeed", ) self.add_input( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.ones(nn), units="unitless", desc="mach number", @@ -50,7 +50,7 @@ def setup(self): ) self.declare_partials( "speed_constraint", - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, rows=arange * 2 + 1, cols=arange, val=self.options["EAS_target"], @@ -60,7 +60,7 @@ def compute(self, inputs, outputs): EAS = inputs["EAS"] EAS_target = self.options["EAS_target"] - mach = inputs[Dynamic.Mission.MACH] + mach = inputs[Dynamic.Atmosphere.MACH] mach_cruise = self.options["mach_cruise"] EAS_constraint = EAS - EAS_target diff --git a/aviary/mission/gasp_based/ode/constraints/test/test_climb_constraints.py b/aviary/mission/gasp_based/ode/constraints/test/test_climb_constraints.py index d2ff00e0b..8a67a4396 100644 --- a/aviary/mission/gasp_based/ode/constraints/test/test_climb_constraints.py +++ b/aviary/mission/gasp_based/ode/constraints/test/test_climb_constraints.py @@ -26,7 +26,7 @@ def setUp(self): self.prob.model.set_input_defaults("EAS", np.array([229, 229, 229]), units="kn") self.prob.model.set_input_defaults( - Dynamic.Mission.MACH, np.array([0.6, 0.6, 0.6]), units="unitless" + Dynamic.Atmosphere.MACH, np.array([0.6, 0.6, 0.6]), units="unitless" ) self.prob.setup(check=False, force_alloc_complex=True) @@ -62,7 +62,7 @@ def setUp(self): self.prob.model.set_input_defaults("EAS", np.array([229, 229, 229]), units="kn") self.prob.model.set_input_defaults( - Dynamic.Mission.MACH, np.array([0.9, 0.9, 0.9]), units="unitless" + Dynamic.Atmosphere.MACH, np.array([0.9, 0.9, 0.9]), units="unitless" ) self.prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/mission/gasp_based/ode/constraints/test/test_flight_constraints.py b/aviary/mission/gasp_based/ode/constraints/test/test_flight_constraints.py index 1992c3407..69f85811b 100644 --- a/aviary/mission/gasp_based/ode/constraints/test/test_flight_constraints.py +++ b/aviary/mission/gasp_based/ode/constraints/test/test_flight_constraints.py @@ -22,16 +22,17 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([174878.0, 174878.0]), units="lbm" + Dynamic.Vehicle.MASS, np.array([174878.0, 174878.0]), units="lbm" ) self.prob.model.set_input_defaults(Aircraft.Wing.AREA, 1370.3, units="ft**2") self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, 0.0023081 * np.ones(2), units="slug/ft**3" + Dynamic.Atmosphere.DENSITY, 0.0023081 * np.ones(2), units="slug/ft**3" ) self.prob.model.set_input_defaults( "CL_max", 1.2596 * np.ones(2), units="unitless") self.prob.model.set_input_defaults( - Dynamic.Mission.FLIGHT_PATH_ANGLE, 7.76 * np.ones(2), units="deg") + Dynamic.Mission.FLIGHT_PATH_ANGLE, 7.76 * np.ones(2), units="deg" + ) self.prob.model.set_input_defaults(Aircraft.Wing.INCIDENCE, 0.0, units="deg") self.prob.model.set_input_defaults("alpha", 5.19 * np.ones(2), units="deg") self.prob.model.set_input_defaults( diff --git a/aviary/mission/gasp_based/ode/descent_eom.py b/aviary/mission/gasp_based/ode/descent_eom.py index 37cdc2287..57e843e53 100644 --- a/aviary/mission/gasp_based/ode/descent_eom.py +++ b/aviary/mission/gasp_based/ode/descent_eom.py @@ -22,15 +22,15 @@ def setup(self): desc="true air speed", ) - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.zeros(nn), + self.add_input(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.zeros(nn), units="lbf", desc="net thrust") self.add_input( - Dynamic.Mission.DRAG, + Dynamic.Vehicle.DRAG, val=np.zeros(nn), units="lbf", desc="net drag on aircraft") self.add_input( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=np.zeros(nn), units="lbm", desc="mass of aircraft", @@ -67,39 +67,56 @@ def setup(self): desc="flight path angle", ) - self.declare_partials(Dynamic.Mission.ALTITUDE_RATE, - [Dynamic.Mission.VELOCITY, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, - Dynamic.Mission.MASS], - rows=arange, - cols=arange) + self.declare_partials( + Dynamic.Mission.ALTITUDE_RATE, + [ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + ], + rows=arange, + cols=arange, + ) self.declare_partials( Dynamic.Mission.DISTANCE_RATE, - [Dynamic.Mission.VELOCITY, Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, Dynamic.Mission.MASS], + [ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + ], rows=arange, cols=arange, ) self.declare_partials( "required_lift", - [Dynamic.Mission.MASS, Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.DRAG, "alpha"], + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + "alpha", + ], + rows=arange, + cols=arange, + ) + self.declare_partials( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + ], rows=arange, cols=arange, ) - self.declare_partials(Dynamic.Mission.FLIGHT_PATH_ANGLE, - [Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, - Dynamic.Mission.MASS], - rows=arange, - cols=arange) def compute(self, inputs, outputs): TAS = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM alpha = inputs["alpha"] gamma = (thrust - drag) / weight @@ -112,42 +129,50 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): TAS = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM alpha = inputs["alpha"] gamma = (thrust - drag) / weight J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = np.sin(gamma) - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.THRUST_TOTAL] = TAS * \ - np.cos(gamma) / weight - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.DRAG] = TAS * \ - np.cos(gamma) * (-1 / weight) - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.MASS] = TAS * \ - np.cos(gamma) * (-(thrust - drag) / weight**2) * GRAV_ENGLISH_LBM + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + TAS * np.cos(gamma) / weight + ) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Vehicle.DRAG] = ( + TAS * np.cos(gamma) * (-1 / weight) + ) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Vehicle.MASS] = ( + TAS * np.cos(gamma) * (-(thrust - drag) / weight**2) * GRAV_ENGLISH_LBM + ) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = np.cos(gamma) - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.THRUST_TOTAL] = - \ - TAS * np.sin(gamma) / weight - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.DRAG] = - \ + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + -TAS * np.sin(gamma) / weight + ) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Vehicle.DRAG] = - \ TAS * np.sin(gamma) * (-1 / weight) - J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.MASS] = ( + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Vehicle.MASS] = ( -TAS * np.sin(gamma) * (-(thrust - drag) / weight**2) * GRAV_ENGLISH_LBM ) - J["required_lift", Dynamic.Mission.MASS] = ( + J["required_lift", Dynamic.Vehicle.MASS] = ( np.cos(gamma) - weight * np.sin( (thrust - drag) / weight ) * (-(thrust - drag) / weight**2) ) * GRAV_ENGLISH_LBM - J["required_lift", Dynamic.Mission.THRUST_TOTAL] = - \ - weight * np.sin(gamma) / weight - np.sin(alpha) - J["required_lift", Dynamic.Mission.DRAG] = - \ + J["required_lift", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = -weight * np.sin( + gamma + ) / weight - np.sin(alpha) + J["required_lift", Dynamic.Vehicle.DRAG] = - \ weight * np.sin(gamma) * (-1 / weight) J["required_lift", "alpha"] = -thrust * np.cos(alpha) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.THRUST_TOTAL] = 1 / weight - J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.DRAG] = -1 / weight - J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.MASS] = - \ - (thrust - drag) / weight**2 * GRAV_ENGLISH_LBM + J[ + Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL + ] = (1 / weight) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Vehicle.DRAG] = -1 / weight + J[Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Vehicle.MASS] = ( + -(thrust - drag) / weight**2 * GRAV_ENGLISH_LBM + ) diff --git a/aviary/mission/gasp_based/ode/descent_ode.py b/aviary/mission/gasp_based/ode/descent_ode.py index 9f9b3ab1e..9cc39fed7 100644 --- a/aviary/mission/gasp_based/ode/descent_ode.py +++ b/aviary/mission/gasp_based/ode/descent_ode.py @@ -74,10 +74,10 @@ def setup(self): subsys=Atmosphere(num_nodes=nn), promotes_inputs=[Dynamic.Mission.ALTITUDE], promotes_outputs=[ - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, "viscosity", ], ) @@ -103,7 +103,7 @@ def setup(self): mach_balance_group.linear_solver = om.DirectSolver(assemble_jac=True) speed_bal = om.BalanceComp( - name=Dynamic.Mission.MACH, + name=Dynamic.Atmosphere.MACH, val=mach_cruise * np.ones(nn), units="unitless", lhs_name="KS", @@ -116,7 +116,7 @@ def setup(self): "speed_bal", speed_bal, promotes_inputs=["KS"], - promotes_outputs=[Dynamic.Mission.MACH], + promotes_outputs=[Dynamic.Atmosphere.MACH], ) mach_balance_group.add_subsystem( @@ -126,7 +126,7 @@ def setup(self): mach_cruise=mach_cruise, EAS_target=EAS_limit, ), - promotes_inputs=["EAS", Dynamic.Mission.MACH], + promotes_inputs=["EAS", Dynamic.Atmosphere.MACH], promotes_outputs=["speed_constraint"], ) mach_balance_group.add_subsystem( @@ -150,7 +150,7 @@ def setup(self): promotes_inputs=['*'], # + speed_inputs, promotes_outputs=[ '*' - ], # [Dynamic.Mission.DYNAMIC_PRESSURE] + speed_outputs, + ], # [Dynamic.Atmosphere.DYNAMIC_PRESSURE] + speed_outputs, ) # maybe replace this with the solver in AddAlphaControl? @@ -166,10 +166,10 @@ def setup(self): "descent_eom", DescentRates(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.VELOCITY, - Dynamic.Mission.DRAG, - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "alpha", ], promotes_outputs=[ @@ -184,9 +184,9 @@ def setup(self): "constraints", FlightConstraints(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, "alpha", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, "CL_max", Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY, @@ -224,13 +224,16 @@ def setup(self): self.add_excess_rate_comps(nn) ParamPort.set_default_vals(self) - self.set_input_defaults(Dynamic.Mission.ALTITUDE, - val=37500 * np.ones(nn), units="ft") - self.set_input_defaults(Dynamic.Mission.MASS, - val=147000 * np.ones(nn), units="lbm") - self.set_input_defaults(Dynamic.Mission.MACH, - val=0 * np.ones(nn), units="unitless") - self.set_input_defaults(Dynamic.Mission.THROTTLE, + self.set_input_defaults( + Dynamic.Mission.ALTITUDE, val=37500 * np.ones(nn), units="ft" + ) + self.set_input_defaults( + Dynamic.Vehicle.MASS, val=147000 * np.ones(nn), units="lbm" + ) + self.set_input_defaults( + Dynamic.Atmosphere.MACH, val=0 * np.ones(nn), units="unitless" + ) + self.set_input_defaults(Dynamic.Vehicle.Propulsion.THROTTLE, val=0 * np.ones(nn), units="unitless") self.set_input_defaults(Aircraft.Wing.AREA, val=1.0, units="ft**2") diff --git a/aviary/mission/gasp_based/ode/flight_path_eom.py b/aviary/mission/gasp_based/ode/flight_path_eom.py index 07399a23f..31dff7641 100644 --- a/aviary/mission/gasp_based/ode/flight_path_eom.py +++ b/aviary/mission/gasp_based/ode/flight_path_eom.py @@ -24,29 +24,49 @@ def setup(self): nn = self.options["num_nodes"] ground_roll = self.options["ground_roll"] - self.add_input(Dynamic.Mission.MASS, val=np.ones(nn), - desc="aircraft mass", units="lbm") - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.ones( - nn), desc=Dynamic.Mission.THRUST_TOTAL, units="lbf") self.add_input( - Dynamic.Mission.LIFT, + Dynamic.Vehicle.MASS, val=np.ones(nn), desc="aircraft mass", units="lbm" + ) + self.add_input( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.ones(nn), - desc=Dynamic.Mission.LIFT, - units="lbf") + desc=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.LIFT, + val=np.ones(nn), + desc=Dynamic.Vehicle.LIFT, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.DRAG, + val=np.ones(nn), + desc=Dynamic.Vehicle.DRAG, + units="lbf", + ) + self.add_input( + Dynamic.Mission.VELOCITY, + val=np.ones(nn), + desc="true air speed", + units="ft/s", + ) self.add_input( - Dynamic.Mission.DRAG, + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.ones(nn), - desc=Dynamic.Mission.DRAG, - units="lbf") - self.add_input(Dynamic.Mission.VELOCITY, val=np.ones(nn), - desc="true air speed", units="ft/s") - self.add_input(Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.ones(nn), - desc="flight path angle", units="rad") + desc="flight path angle", + units="rad", + ) add_aviary_input(self, Aircraft.Wing.INCIDENCE, val=0) - self.add_output(Dynamic.Mission.VELOCITY_RATE, val=np.ones(nn), desc="TAS rate", units="ft/s**2", - tags=['dymos.state_rate_source:velocity', 'dymos.state_units:kn']) + self.add_output( + Dynamic.Mission.VELOCITY_RATE, + val=np.ones(nn), + desc="TAS rate", + units="ft/s**2", + tags=['dymos.state_rate_source:velocity', 'dymos.state_units:kn'], + ) if not ground_roll: self._mu = 0.0 @@ -55,9 +75,8 @@ def setup(self): val=np.ones(nn), desc="altitude rate", units="ft/s", - tags=[ - 'dymos.state_rate_source:altitude', - 'dymos.state_units:ft']) + tags=['dymos.state_rate_source:altitude', 'dymos.state_units:ft'], + ) self.add_output( Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, val=np.ones(nn), @@ -65,7 +84,9 @@ def setup(self): units="rad/s", tags=[ 'dymos.state_rate_source:flight_path_angle', - 'dymos.state_units:rad']) + 'dymos.state_units:rad', + ], + ) self.add_input("alpha", val=np.ones(nn), desc="angle of attack", units="deg") self.add_output( @@ -90,8 +111,12 @@ def setup_partials(self): self.declare_partials( "load_factor", - [Dynamic.Mission.LIFT, Dynamic.Mission.MASS, - Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.THRUST_TOTAL], + [ + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ], rows=arange, cols=arange, ) @@ -99,8 +124,13 @@ def setup_partials(self): self.declare_partials( Dynamic.Mission.VELOCITY_RATE, - [Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.DRAG, - Dynamic.Mission.MASS, Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.LIFT], + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Vehicle.LIFT, + ], rows=arange, cols=arange, ) @@ -109,17 +139,27 @@ def setup_partials(self): if not ground_roll: self.declare_partials( - Dynamic.Mission.ALTITUDE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange) + Dynamic.Mission.ALTITUDE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, + ) self.declare_partials( Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, - [Dynamic.Mission.THRUST_TOTAL, "alpha", - Dynamic.Mission.LIFT, Dynamic.Mission.MASS, Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.VELOCITY], + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Mission.VELOCITY, + ], rows=arange, cols=arange, ) - self.declare_partials(Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, [ - Aircraft.Wing.INCIDENCE]) + self.declare_partials( + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, [Aircraft.Wing.INCIDENCE] + ) self.declare_partials( "normal_force", "alpha", @@ -146,19 +186,29 @@ def setup_partials(self): ) self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange + Dynamic.Mission.DISTANCE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, ) # self.declare_partials("alpha_rate", ["*"], val=0.0) self.declare_partials( "normal_force", - [Dynamic.Mission.MASS, Dynamic.Mission.LIFT, Dynamic.Mission.THRUST_TOTAL], + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ], rows=arange, cols=arange, ) self.declare_partials("normal_force", [Aircraft.Wing.INCIDENCE]) self.declare_partials( - "fuselage_pitch", Dynamic.Mission.FLIGHT_PATH_ANGLE, rows=arange, cols=arange, val=180 / np.pi + "fuselage_pitch", + Dynamic.Mission.FLIGHT_PATH_ANGLE, + rows=arange, + cols=arange, + val=180 / np.pi, ) self.declare_partials("fuselage_pitch", [Aircraft.Wing.INCIDENCE]) @@ -166,10 +216,10 @@ def compute(self, inputs, outputs): mu = MU_TAKEOFF if self.options['ground_roll'] else 0.0 - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -216,10 +266,10 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): mu = MU_TAKEOFF if self.options['ground_roll'] else 0.0 - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -241,17 +291,20 @@ def compute_partials(self, inputs, J): dTAcF_dAlpha = thrust * np.cos((alpha - i_wing) * np.pi / 180) * np.pi / 180 dTAcF_dIwing = -thrust * np.cos((alpha - i_wing) * np.pi / 180) * np.pi / 180 - J["load_factor", Dynamic.Mission.LIFT] = 1 / (weight * np.cos(gamma)) - J["load_factor", Dynamic.Mission.MASS] = -(incremented_lift + thrust_across_flightpath) / ( - weight**2 * np.cos(gamma) - ) * GRAV_ENGLISH_LBM + J["load_factor", Dynamic.Vehicle.LIFT] = 1 / (weight * np.cos(gamma)) + J["load_factor", Dynamic.Vehicle.MASS] = ( + -(incremented_lift + thrust_across_flightpath) + / (weight**2 * np.cos(gamma)) + * GRAV_ENGLISH_LBM + ) J["load_factor", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( -(incremented_lift + thrust_across_flightpath) / (weight * (np.cos(gamma)) ** 2) * (-np.sin(gamma)) ) - J["load_factor", Dynamic.Mission.THRUST_TOTAL] = dTAcF_dThrust / \ - (weight * np.cos(gamma)) + J["load_factor", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = dTAcF_dThrust / ( + weight * np.cos(gamma) + ) normal_force = weight - incremented_lift - thrust_across_flightpath # normal_force = np.where(normal_force1 < 0, np.zeros(nn), normal_force1) @@ -268,13 +321,16 @@ def compute_partials(self, inputs, J): dNF_dIwing = -np.ones(nn) * dTAcF_dIwing # dNF_dIwing[normal_force1 < 0] = 0 - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.THRUST_TOTAL] = ( + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( (dTAlF_dThrust - mu * dNF_dThrust) * GRAV_ENGLISH_GASP / weight ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.DRAG] = -GRAV_ENGLISH_GASP / weight - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.MASS] = ( - GRAV_ENGLISH_GASP * GRAV_ENGLISH_LBM + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.DRAG] = ( + -GRAV_ENGLISH_GASP / weight + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.MASS] = ( + GRAV_ENGLISH_GASP + * GRAV_ENGLISH_LBM * ( weight * (-np.sin(gamma) - mu * dNF_dWeight) - ( @@ -286,29 +342,44 @@ def compute_partials(self, inputs, J): ) / weight**2 ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = - \ - np.cos(gamma) * GRAV_ENGLISH_GASP - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.LIFT] = GRAV_ENGLISH_GASP * \ - (-mu * dNF_dLift) / weight + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -np.cos(gamma) * GRAV_ENGLISH_GASP + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.LIFT] = ( + GRAV_ENGLISH_GASP * (-mu * dNF_dLift) / weight + ) # TODO: check partials, esp. for alphas if not self.options['ground_roll']: J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = np.sin(gamma) - J[Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = TAS * np.cos(gamma) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + TAS * np.cos(gamma) + ) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.THRUST_TOTAL] = dTAcF_dThrust * \ - GRAV_ENGLISH_GASP / (TAS * weight) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, "alpha"] = dTAcF_dAlpha * \ - GRAV_ENGLISH_GASP / (TAS * weight) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Aircraft.Wing.INCIDENCE] = dTAcF_dIwing * \ + J[ + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ] = ( + dTAcF_dThrust * GRAV_ENGLISH_GASP / (TAS * weight) + ) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, "alpha"] = ( + dTAcF_dAlpha * GRAV_ENGLISH_GASP / (TAS * weight) + ) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Aircraft.Wing.INCIDENCE] = ( + dTAcF_dIwing * GRAV_ENGLISH_GASP / (TAS * weight) + ) + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Vehicle.LIFT] = ( GRAV_ENGLISH_GASP / (TAS * weight) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, - Dynamic.Mission.LIFT] = GRAV_ENGLISH_GASP / (TAS * weight) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.MASS] = (GRAV_ENGLISH_GASP / TAS) * GRAV_ENGLISH_LBM * ( - -thrust_across_flightpath / weight**2 - incremented_lift / weight**2 ) - J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Vehicle.MASS] = ( + (GRAV_ENGLISH_GASP / TAS) + * GRAV_ENGLISH_LBM + * (-thrust_across_flightpath / weight**2 - incremented_lift / weight**2) + ) + J[ + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ] = ( weight * np.sin(gamma) * GRAV_ENGLISH_GASP / (TAS * weight) ) J[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, Dynamic.Mission.VELOCITY] = -( @@ -334,9 +405,10 @@ def compute_partials(self, inputs, J): (weight * np.cos(gamma)) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = np.cos(gamma) - J[Dynamic.Mission.DISTANCE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = -TAS * np.sin(gamma) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -TAS * np.sin(gamma) + ) - J["normal_force", Dynamic.Mission.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM - J["normal_force", Dynamic.Mission.LIFT] = dNF_dLift - J["normal_force", Dynamic.Mission.THRUST_TOTAL] = dNF_dThrust + J["normal_force", Dynamic.Vehicle.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM + J["normal_force", Dynamic.Vehicle.LIFT] = dNF_dLift + J["normal_force", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = dNF_dThrust diff --git a/aviary/mission/gasp_based/ode/flight_path_ode.py b/aviary/mission/gasp_based/ode/flight_path_ode.py index dd0617674..dc87ee833 100644 --- a/aviary/mission/gasp_based/ode/flight_path_ode.py +++ b/aviary/mission/gasp_based/ode/flight_path_ode.py @@ -52,10 +52,10 @@ def setup(self): kwargs['output_alpha'] = False EOM_inputs = [ - Dynamic.Mission.MASS, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.LIFT, - Dynamic.Mission.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.DRAG, Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE, ] + ['aircraft:*'] @@ -71,7 +71,9 @@ def setup(self): } if kwargs['method'] == 'cruise': SGM_required_inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] = { - 'val': 0, 'units': 'deg'} + 'val': 0, + 'units': 'deg', + } add_SGM_required_inputs(self, SGM_required_inputs) prop_group = om.Group() else: @@ -102,8 +104,8 @@ def setup(self): self.add_subsystem( "calc_weight", MassToWeight(num_nodes=nn), - promotes_inputs=[("mass", Dynamic.Mission.MASS)], - promotes_outputs=["weight"] + promotes_inputs=[("mass", Dynamic.Vehicle.MASS)], + promotes_outputs=["weight"], ) self.add_subsystem( 'calc_lift', @@ -118,12 +120,12 @@ def setup(self): ), promotes_inputs=[ 'weight', - ('thrust', Dynamic.Mission.THRUST_TOTAL), + ('thrust', Dynamic.Vehicle.Propulsion.THRUST_TOTAL), 'alpha', ('gamma', Dynamic.Mission.FLIGHT_PATH_ANGLE), - ('i_wing', Aircraft.Wing.INCIDENCE) + ('i_wing', Aircraft.Wing.INCIDENCE), ], - promotes_outputs=['required_lift'] + promotes_outputs=['required_lift'], ) self.AddAlphaControl( alpha_mode=alpha_mode, @@ -161,13 +163,13 @@ def setup(self): i_wing={'val': 0, 'units': 'rad'}, ), promotes_inputs=[ - ('drag', Dynamic.Mission.DRAG), + ('drag', Dynamic.Vehicle.DRAG), # 'weight', # 'alpha', # ('gamma', Dynamic.Mission.FLIGHT_PATH_ANGLE), - ('i_wing', Aircraft.Wing.INCIDENCE) + ('i_wing', Aircraft.Wing.INCIDENCE), ], - promotes_outputs=['required_thrust'] + promotes_outputs=['required_thrust'], ) self.AddThrottleControl(prop_group=prop_group, @@ -190,8 +192,13 @@ def setup(self): ) if not self.options['ground_roll']: - self.promotes('flight_path_eom', outputs=[ - Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE]) + self.promotes( + 'flight_path_eom', + outputs=[ + Dynamic.Mission.ALTITUDE_RATE, + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + ], + ) self.add_excess_rate_comps(nn) @@ -201,9 +208,12 @@ def setup(self): self.set_input_defaults("t_init_gear", val=37.3) self.set_input_defaults("t_curr", val=np.zeros(nn), units="s") self.set_input_defaults("alpha", val=np.zeros(nn), units="rad") - self.set_input_defaults(Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units="deg") + self.set_input_defaults( + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units="deg" + ) self.set_input_defaults(Dynamic.Mission.ALTITUDE, val=np.zeros(nn), units="ft") - self.set_input_defaults(Dynamic.Mission.MACH, val=np.zeros(nn), units="unitless") - self.set_input_defaults(Dynamic.Mission.MASS, val=np.zeros(nn), units="lbm") + self.set_input_defaults( + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless" + ) + self.set_input_defaults(Dynamic.Vehicle.MASS, val=np.zeros(nn), units="lbm") self.set_input_defaults(Dynamic.Mission.VELOCITY, val=np.zeros(nn), units="kn") diff --git a/aviary/mission/gasp_based/ode/groundroll_eom.py b/aviary/mission/gasp_based/ode/groundroll_eom.py index 83ca58973..17aeb0160 100644 --- a/aviary/mission/gasp_based/ode/groundroll_eom.py +++ b/aviary/mission/gasp_based/ode/groundroll_eom.py @@ -20,28 +20,60 @@ def setup(self): nn = self.options["num_nodes"] arange = np.arange(nn) - self.add_input(Dynamic.Mission.MASS, val=np.ones(nn), - desc="aircraft mass", units="lbm") - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.ones( - nn), desc=Dynamic.Mission.THRUST_TOTAL, units="lbf") - self.add_input(Dynamic.Mission.LIFT, val=np.ones( - nn), desc=Dynamic.Mission.LIFT, units="lbf") - self.add_input(Dynamic.Mission.DRAG, val=np.ones( - nn), desc=Dynamic.Mission.DRAG, units="lbf") - self.add_input(Dynamic.Mission.VELOCITY, val=np.ones(nn), - desc="true air speed", units="ft/s") - self.add_input(Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.ones(nn), - desc="flight path angle", units="rad") + self.add_input( + Dynamic.Vehicle.MASS, val=np.ones(nn), desc="aircraft mass", units="lbm" + ) + self.add_input( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=np.ones(nn), + desc=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.LIFT, + val=np.ones(nn), + desc=Dynamic.Vehicle.LIFT, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.DRAG, + val=np.ones(nn), + desc=Dynamic.Vehicle.DRAG, + units="lbf", + ) + self.add_input( + Dynamic.Mission.VELOCITY, + val=np.ones(nn), + desc="true air speed", + units="ft/s", + ) + self.add_input( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + val=np.ones(nn), + desc="flight path angle", + units="rad", + ) add_aviary_input(self, Aircraft.Wing.INCIDENCE, val=0) self.add_input("alpha", val=np.zeros(nn), desc="angle of attack", units="deg") - self.add_output(Dynamic.Mission.VELOCITY_RATE, val=np.ones(nn), - desc="TAS rate", units="ft/s**2") self.add_output( - Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, val=np.ones(nn), desc="flight path angle rate", units="rad/s" + Dynamic.Mission.VELOCITY_RATE, + val=np.ones(nn), + desc="TAS rate", + units="ft/s**2", + ) + self.add_output( + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + val=np.ones(nn), + desc="flight path angle rate", + units="rad/s", + ) + self.add_output( + Dynamic.Mission.ALTITUDE_RATE, + val=np.ones(nn), + desc="altitude rate", + units="ft/s", ) - self.add_output(Dynamic.Mission.ALTITUDE_RATE, val=np.ones(nn), - desc="altitude rate", units="ft/s") self.add_output( Dynamic.Mission.DISTANCE_RATE, val=np.ones(nn), desc="distance rate", units="ft/s" ) @@ -55,28 +87,48 @@ def setup(self): self.declare_partials(Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, "*") self.declare_partials( Dynamic.Mission.VELOCITY_RATE, - [Dynamic.Mission.THRUST_TOTAL, "alpha", Dynamic.Mission.DRAG, - Dynamic.Mission.MASS, Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.LIFT], + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Vehicle.LIFT, + ], rows=arange, cols=arange, ) self.declare_partials(Dynamic.Mission.VELOCITY_RATE, Aircraft.Wing.INCIDENCE) - self.declare_partials(Dynamic.Mission.ALTITUDE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange) self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange + Dynamic.Mission.ALTITUDE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, + ) + self.declare_partials( + Dynamic.Mission.DISTANCE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, ) self.declare_partials( "normal_force", - [Dynamic.Mission.MASS, Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, "alpha"], + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + ], rows=arange, cols=arange, ) self.declare_partials("normal_force", Aircraft.Wing.INCIDENCE) self.declare_partials( - "fuselage_pitch", Dynamic.Mission.FLIGHT_PATH_ANGLE, rows=arange, cols=arange, val=180 / np.pi, + "fuselage_pitch", + Dynamic.Mission.FLIGHT_PATH_ANGLE, + rows=arange, + cols=arange, + val=180 / np.pi, ) self.declare_partials("fuselage_pitch", "alpha", rows=arange, cols=arange, val=1) self.declare_partials("fuselage_pitch", Aircraft.Wing.INCIDENCE, val=-1) @@ -93,10 +145,10 @@ def compute(self, inputs, outputs): mu = MU_TAKEOFF - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -133,10 +185,10 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): mu = MU_TAKEOFF - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -173,7 +225,7 @@ def compute_partials(self, inputs, J): dNF_dIwing = -np.ones(nn) * dTAcF_dIwing dNF_dIwing[normal_force1 < 0] = 0 - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.THRUST_TOTAL] = ( + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( (dTAlF_dThrust - mu * dNF_dThrust) * GRAV_ENGLISH_GASP / weight ) J[Dynamic.Mission.VELOCITY_RATE, "alpha"] = ( @@ -182,9 +234,12 @@ def compute_partials(self, inputs, J): J[Dynamic.Mission.VELOCITY_RATE, Aircraft.Wing.INCIDENCE] = ( (dTAlF_dIwing - mu * dNF_dIwing) * GRAV_ENGLISH_GASP / weight ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.DRAG] = -GRAV_ENGLISH_GASP / weight - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.MASS] = ( - GRAV_ENGLISH_GASP * GRAV_ENGLISH_LBM + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.DRAG] = ( + -GRAV_ENGLISH_GASP / weight + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.MASS] = ( + GRAV_ENGLISH_GASP + * GRAV_ENGLISH_LBM * ( weight * (-np.sin(gamma) - mu * dNF_dWeight) - ( @@ -196,21 +251,25 @@ def compute_partials(self, inputs, J): ) / weight**2 ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = - \ - np.cos(gamma) * GRAV_ENGLISH_GASP - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.LIFT] = GRAV_ENGLISH_GASP * \ - (-mu * dNF_dLift) / weight + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -np.cos(gamma) * GRAV_ENGLISH_GASP + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.LIFT] = ( + GRAV_ENGLISH_GASP * (-mu * dNF_dLift) / weight + ) J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = np.sin(gamma) - J[Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = TAS * np.cos(gamma) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + TAS * np.cos(gamma) + ) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = np.cos(gamma) - J[Dynamic.Mission.DISTANCE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = -TAS * np.sin(gamma) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -TAS * np.sin(gamma) + ) - J["normal_force", Dynamic.Mission.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM - J["normal_force", Dynamic.Mission.LIFT] = dNF_dLift - J["normal_force", Dynamic.Mission.THRUST_TOTAL] = dNF_dThrust + J["normal_force", Dynamic.Vehicle.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM + J["normal_force", Dynamic.Vehicle.LIFT] = dNF_dLift + J["normal_force", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = dNF_dThrust J["normal_force", "alpha"] = dNF_dAlpha J["normal_force", Aircraft.Wing.INCIDENCE] = dNF_dIwing diff --git a/aviary/mission/gasp_based/ode/groundroll_ode.py b/aviary/mission/gasp_based/ode/groundroll_ode.py index a4dcb145b..85df33617 100644 --- a/aviary/mission/gasp_based/ode/groundroll_ode.py +++ b/aviary/mission/gasp_based/ode/groundroll_ode.py @@ -8,7 +8,9 @@ from aviary.variable_info.enums import AnalysisScheme from aviary.subsystems.aerodynamics.aerodynamics_builder import AerodynamicsBuilderBase from aviary.variable_info.variable_meta_data import _MetaData -from aviary.mission.gasp_based.ode.time_integration_base_classes import add_SGM_required_inputs +from aviary.mission.gasp_based.ode.time_integration_base_classes import ( + add_SGM_required_inputs, +) class GroundrollODE(BaseODE): @@ -22,14 +24,18 @@ class GroundrollODE(BaseODE): def initialize(self): super().initialize() self.options.declare( - 'external_subsystems', default=[], - desc='list of external subsystem builder instances to be added to the ODE') + 'external_subsystems', + default=[], + desc='list of external subsystem builder instances to be added to the ODE', + ) self.options.declare( - 'meta_data', default=_MetaData, - desc='metadata associated with the variables to be passed into the ODE') + 'meta_data', + default=_MetaData, + desc='metadata associated with the variables to be passed into the ODE', + ) self.options.declare( - 'set_input_defaults', default=True, - desc='set input defaults for the ODE') + 'set_input_defaults', default=True, desc='set input defaults for the ODE' + ) def setup(self): nn = self.options["num_nodes"] @@ -39,9 +45,12 @@ def setup(self): subsystem_options = self.options['subsystem_options'] if analysis_scheme is AnalysisScheme.SHOOTING: - add_SGM_required_inputs(self, { - Dynamic.Mission.DISTANCE: {'units': 'ft'}, - }) + add_SGM_required_inputs( + self, + { + Dynamic.Mission.DISTANCE: {'units': 'ft'}, + }, + ) # TODO: paramport self.add_subsystem("params", ParamPort(), promotes=["*"]) @@ -49,25 +58,33 @@ def setup(self): self.add_atmosphere(nn) # broadcast scalar i_wing to alpha for aero - self.add_subsystem("init_alpha", - om.ExecComp("alpha = i_wing", - i_wing={"units": "deg", "val": 1.1}, - alpha={"units": "deg", "val": 1.1*np.ones(nn)},), - promotes=[("i_wing", Aircraft.Wing.INCIDENCE), - "alpha"]) - - kwargs = {'num_nodes': nn, 'aviary_inputs': aviary_options, - 'method': 'low_speed'} + self.add_subsystem( + "init_alpha", + om.ExecComp( + "alpha = i_wing", + i_wing={"units": "deg", "val": 1.1}, + alpha={"units": "deg", "val": 1.1 * np.ones(nn)}, + ), + promotes=[("i_wing", Aircraft.Wing.INCIDENCE), "alpha"], + ) + + kwargs = { + 'num_nodes': nn, + 'aviary_inputs': aviary_options, + 'method': 'low_speed', + } for subsystem in core_subsystems: # check if subsystem_options has entry for a subsystem of this name if subsystem.name in subsystem_options: kwargs.update(subsystem_options[subsystem.name]) system = subsystem.build_mission(**kwargs) if system is not None: - self.add_subsystem(subsystem.name, - system, - promotes_inputs=subsystem.mission_inputs(**kwargs), - promotes_outputs=subsystem.mission_outputs(**kwargs)) + self.add_subsystem( + subsystem.name, + system, + promotes_inputs=subsystem.mission_inputs(**kwargs), + promotes_outputs=subsystem.mission_outputs(**kwargs), + ) if type(subsystem) is AerodynamicsBuilderBase: self.promotes( subsystem.name, @@ -75,66 +92,69 @@ def setup(self): src_indices=np.zeros(nn, dtype=int), ) - self.add_subsystem("groundroll_eom", GroundrollEOM(num_nodes=nn), promotes=["*"]) - - self.add_subsystem("exec", om.ExecComp(f"over_a = velocity / velocity_rate", - velocity_rate={"units": "kn/s", - "val": np.ones(nn)}, - velocity={"units": "kn", - "val": np.ones(nn)}, - over_a={"units": "s", "val": np.ones(nn)}, - has_diag_partials=True, - ), - promotes=["*"]) - - self.add_subsystem("exec2", om.ExecComp(f"dt_dv = 1 / velocity_rate", - velocity_rate={"units": "kn/s", - "val": np.ones(nn)}, - dt_dv={"units": "s/kn", - "val": np.ones(nn)}, - has_diag_partials=True, - ), - promotes=["*"]) + self.add_subsystem( + "groundroll_eom", GroundrollEOM(num_nodes=nn), promotes=["*"] + ) + + self.add_subsystem( + "exec", + om.ExecComp( + f"over_a = velocity / velocity_rate", + velocity_rate={"units": "kn/s", "val": np.ones(nn)}, + velocity={"units": "kn", "val": np.ones(nn)}, + over_a={"units": "s", "val": np.ones(nn)}, + has_diag_partials=True, + ), + promotes=["*"], + ) + + self.add_subsystem( + "exec2", + om.ExecComp( + f"dt_dv = 1 / velocity_rate", + velocity_rate={"units": "kn/s", "val": np.ones(nn)}, + dt_dv={"units": "s/kn", "val": np.ones(nn)}, + has_diag_partials=True, + ), + promotes=["*"], + ) self.add_subsystem( "exec3", om.ExecComp( "dmass_dv = mass_rate * dt_dv", - mass_rate={ - "units": "lbm/s", - "val": np.ones(nn)}, - dt_dv={ - "units": "s/kn", - "val": np.ones(nn)}, - dmass_dv={ - "units": "lbm/kn", - "val": np.ones(nn)}, + mass_rate={"units": "lbm/s", "val": np.ones(nn)}, + dt_dv={"units": "s/kn", "val": np.ones(nn)}, + dmass_dv={"units": "lbm/kn", "val": np.ones(nn)}, has_diag_partials=True, ), promotes_outputs=[ "dmass_dv", ], promotes_inputs=[ - ("mass_rate", - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL), - "dt_dv"]) + ("mass_rate", Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL), + "dt_dv", + ], + ) ParamPort.set_default_vals(self) if self.options['set_input_defaults']: - self.set_input_defaults("t_init_flaps", val=100.) - self.set_input_defaults("t_init_gear", val=100.) - self.set_input_defaults('aero_ramps.flap_factor:final_val', val=1.) - self.set_input_defaults('aero_ramps.gear_factor:final_val', val=1.) - self.set_input_defaults('aero_ramps.flap_factor:initial_val', val=1.) - self.set_input_defaults('aero_ramps.gear_factor:initial_val', val=1.) + self.set_input_defaults("t_init_flaps", val=100.0) + self.set_input_defaults("t_init_gear", val=100.0) + self.set_input_defaults('aero_ramps.flap_factor:final_val', val=1.0) + self.set_input_defaults('aero_ramps.gear_factor:final_val', val=1.0) + self.set_input_defaults('aero_ramps.flap_factor:initial_val', val=1.0) + self.set_input_defaults('aero_ramps.gear_factor:initial_val', val=1.0) self.set_input_defaults("t_curr", val=np.zeros(nn), units="s") - self.set_input_defaults(Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units="deg") + self.set_input_defaults( + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units="deg" + ) self.set_input_defaults(Dynamic.Mission.ALTITUDE, val=np.zeros(nn), units="ft") self.set_input_defaults(Dynamic.Mission.VELOCITY, val=np.zeros(nn), units="kn") - self.set_input_defaults(Dynamic.Mission.VELOCITY_RATE, - val=np.zeros(nn), units="kn/s") + self.set_input_defaults( + Dynamic.Mission.VELOCITY_RATE, val=np.zeros(nn), units="kn/s" + ) self.set_input_defaults(Aircraft.Wing.INCIDENCE, val=1.0, units="deg") diff --git a/aviary/mission/gasp_based/ode/landing_eom.py b/aviary/mission/gasp_based/ode/landing_eom.py index faf6c1794..d51cf11bb 100644 --- a/aviary/mission/gasp_based/ode/landing_eom.py +++ b/aviary/mission/gasp_based/ode/landing_eom.py @@ -37,11 +37,15 @@ class GlideConditionComponent(om.ExplicitComponent): def setup(self): self.add_input( - Dynamic.Mission.DENSITY, val=0.0, units="slug/ft**3", desc="air density" + Dynamic.Atmosphere.DENSITY, val=0.0, units="slug/ft**3", desc="air density" ) add_aviary_input(self, Mission.Landing.MAXIMUM_SINK_RATE, val=900.0) - self.add_input(Dynamic.Mission.MASS, val=0.0, units="lbm", - desc="aircraft mass at start of landing") + self.add_input( + Dynamic.Vehicle.MASS, + val=0.0, + units="lbm", + desc="aircraft mass at start of landing", + ) add_aviary_input(self, Aircraft.Wing.AREA, val=1.0) add_aviary_input(self, Mission.Landing.GLIDE_TO_STALL_RATIO, val=1.3) self.add_input("CL_max", val=0.0, units='unitless', @@ -97,43 +101,44 @@ def setup(self): self.declare_partials( Mission.Landing.INITIAL_VELOCITY, [ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.GLIDE_TO_STALL_RATIO, ], ) self.declare_partials( Mission.Landing.STALL_VELOCITY, - [ - Dynamic.Mission.MASS, + + [Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, - ], + Dynamic.Atmosphere.DENSITY, + ], ) self.declare_partials( "TAS_touchdown", [ Mission.Landing.GLIDE_TO_STALL_RATIO, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, ], ) - self.declare_partials("density_ratio", [Dynamic.Mission.DENSITY]) - self.declare_partials("wing_loading_land", [ - Dynamic.Mission.MASS, Aircraft.Wing.AREA]) + self.declare_partials("density_ratio", [Dynamic.Atmosphere.DENSITY]) + self.declare_partials( + "wing_loading_land", [Dynamic.Vehicle.MASS, Aircraft.Wing.AREA] + ) self.declare_partials( "theta", [ Mission.Landing.MAXIMUM_SINK_RATE, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.GLIDE_TO_STALL_RATIO, ], ) @@ -142,10 +147,10 @@ def setup(self): [ Mission.Landing.INITIAL_ALTITUDE, Mission.Landing.MAXIMUM_SINK_RATE, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.GLIDE_TO_STALL_RATIO, ], ) @@ -154,10 +159,10 @@ def setup(self): [ Mission.Landing.MAXIMUM_FLARE_LOAD_FACTOR, Mission.Landing.TOUCHDOWN_SINK_RATE, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.GLIDE_TO_STALL_RATIO, Mission.Landing.MAXIMUM_SINK_RATE, ], @@ -166,10 +171,10 @@ def setup(self): "delay_distance", [ Mission.Landing.GLIDE_TO_STALL_RATIO, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.BRAKING_DELAY, ], ) @@ -179,10 +184,10 @@ def setup(self): Mission.Landing.MAXIMUM_FLARE_LOAD_FACTOR, Mission.Landing.TOUCHDOWN_SINK_RATE, Mission.Landing.MAXIMUM_SINK_RATE, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, "CL_max", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.GLIDE_TO_STALL_RATIO, ], ) @@ -283,43 +288,45 @@ def compute_partials(self, inputs, J): * dTasGlide_dWeight ) - J[Mission.Landing.INITIAL_VELOCITY, Dynamic.Mission.MASS] = \ + J[Mission.Landing.INITIAL_VELOCITY, Dynamic.Vehicle.MASS] = ( dTasGlide_dWeight * GRAV_ENGLISH_LBM + ) J[Mission.Landing.INITIAL_VELOCITY, Aircraft.Wing.AREA] = dTasGlide_dWingArea = ( dTasStall_dWingArea * glide_to_stall_ratio ) J[Mission.Landing.INITIAL_VELOCITY, "CL_max"] = dTasGlide_dClMax = ( dTasStall_dClMax * glide_to_stall_ratio ) - J[Mission.Landing.INITIAL_VELOCITY, Dynamic.Mission.DENSITY] = ( + J[Mission.Landing.INITIAL_VELOCITY, Dynamic.Atmosphere.DENSITY] = ( dTasGlide_dRhoApp ) = (dTasStall_dRhoApp * glide_to_stall_ratio) J[Mission.Landing.INITIAL_VELOCITY, Mission.Landing.GLIDE_TO_STALL_RATIO] = TAS_stall - J[Mission.Landing.STALL_VELOCITY, Dynamic.Mission.MASS] = \ + J[Mission.Landing.STALL_VELOCITY, Dynamic.Vehicle.MASS] = ( dTasStall_dWeight * GRAV_ENGLISH_LBM + ) J[Mission.Landing.STALL_VELOCITY, Aircraft.Wing.AREA] = dTasStall_dWingArea J[Mission.Landing.STALL_VELOCITY, "CL_max"] = dTasStall_dClMax - J[Mission.Landing.STALL_VELOCITY, Dynamic.Mission.DENSITY] = dTasStall_dRhoApp + J[Mission.Landing.STALL_VELOCITY, Dynamic.Atmosphere.DENSITY] = dTasStall_dRhoApp J["TAS_touchdown", Mission.Landing.GLIDE_TO_STALL_RATIO] = dTasTd_dGlideToStallRatio = ( 0.5 * TAS_stall ) - J["TAS_touchdown", Dynamic.Mission.MASS] = dTasTd_dWeight * GRAV_ENGLISH_LBM + J["TAS_touchdown", Dynamic.Vehicle.MASS] = dTasTd_dWeight * GRAV_ENGLISH_LBM J["TAS_touchdown", Aircraft.Wing.AREA] = dTasTd_dWingArea = ( touchdown_velocity_ratio * dTasStall_dWingArea ) J["TAS_touchdown", "CL_max"] = dTasTd_dClMax = ( touchdown_velocity_ratio * dTasStall_dClMax ) - J["TAS_touchdown", Dynamic.Mission.DENSITY] = dTasTd_dRhoApp = ( + J["TAS_touchdown", Dynamic.Atmosphere.DENSITY] = dTasTd_dRhoApp = ( touchdown_velocity_ratio * dTasStall_dRhoApp ) - J["density_ratio", Dynamic.Mission.DENSITY] = 1 / RHO_SEA_LEVEL_ENGLISH + J["density_ratio", Dynamic.Atmosphere.DENSITY] = 1 / RHO_SEA_LEVEL_ENGLISH - J["wing_loading_land", Dynamic.Mission.MASS] = GRAV_ENGLISH_LBM / wing_area + J["wing_loading_land", Dynamic.Vehicle.MASS] = GRAV_ENGLISH_LBM / wing_area J["wing_loading_land", Aircraft.Wing.AREA] = -weight / wing_area**2 np.arcsin(rate_of_sink_max / (60.0 * TAS_glide)) @@ -329,7 +336,7 @@ def compute_partials(self, inputs, J): * 1 / (60.0 * TAS_glide) ) - J["theta", Dynamic.Mission.MASS] = dTheta_dWeight * GRAV_ENGLISH_LBM + J["theta", Dynamic.Vehicle.MASS] = dTheta_dWeight * GRAV_ENGLISH_LBM J["theta", Aircraft.Wing.AREA] = dTheta_dWingArea = ( (1 - (rate_of_sink_max / (60.0 * TAS_glide)) ** 2) ** (-0.5) * (-rate_of_sink_max / (60.0 * TAS_glide**2)) @@ -340,7 +347,7 @@ def compute_partials(self, inputs, J): * (-rate_of_sink_max / (60.0 * TAS_glide**2)) * dTasGlide_dClMax ) - J["theta", Dynamic.Mission.DENSITY] = dTheta_dRhoApp = ( + J["theta", Dynamic.Atmosphere.DENSITY] = dTheta_dRhoApp = ( (1 - (rate_of_sink_max / (60.0 * TAS_glide)) ** 2) ** (-0.5) * (-rate_of_sink_max / (60.0 * TAS_glide**2)) * dTasGlide_dRhoApp @@ -360,11 +367,12 @@ def compute_partials(self, inputs, J): * (1 / np.cos(theta)) ** 2 * dTheta_dRateOfSinkMax ) - J["glide_distance", Dynamic.Mission.MASS] = ( + J["glide_distance", Dynamic.Vehicle.MASS] = ( -approach_alt / (np.tan(theta)) ** 2 * (1 / np.cos(theta)) ** 2 - * dTheta_dWeight * GRAV_ENGLISH_LBM + * dTheta_dWeight + * GRAV_ENGLISH_LBM ) J["glide_distance", Aircraft.Wing.AREA] = ( -approach_alt @@ -378,7 +386,7 @@ def compute_partials(self, inputs, J): * (1 / np.cos(theta)) ** 2 * dTheta_dClMax ) - J["glide_distance", Dynamic.Mission.DENSITY] = ( + J["glide_distance", Dynamic.Atmosphere.DENSITY] = ( -approach_alt / (np.tan(theta)) ** 2 * (1 / np.cos(theta)) ** 2 @@ -485,14 +493,14 @@ def compute_partials(self, inputs, J): J["tr_distance", Mission.Landing.MAXIMUM_SINK_RATE] = ( dInter1_dRateOfSinkMax * inter2 + inter1 * dInter2_dRateOfSinkMax ) - J["tr_distance", Dynamic.Mission.MASS] = ( + J["tr_distance", Dynamic.Vehicle.MASS] = ( dInter1_dWeight * inter2 + inter1 * dInter2_dWeight ) * GRAV_ENGLISH_LBM J["tr_distance", Aircraft.Wing.AREA] = ( dInter1_dWingArea * inter2 + inter1 * dInter2_dWingArea ) J["tr_distance", "CL_max"] = dInter1_dClMax * inter2 + inter1 * dInter2_dClMax - J["tr_distance", Dynamic.Mission.DENSITY] = ( + J["tr_distance", Dynamic.Atmosphere.DENSITY] = ( dInter1_dRhoApp * inter2 + inter1 * dInter2_dRhoApp ) J["tr_distance", Mission.Landing.GLIDE_TO_STALL_RATIO] = ( @@ -503,11 +511,12 @@ def compute_partials(self, inputs, J): J["delay_distance", Mission.Landing.GLIDE_TO_STALL_RATIO] = ( time_delay * dTasTd_dGlideToStallRatio ) - J["delay_distance", Dynamic.Mission.MASS] = \ + J["delay_distance", Dynamic.Vehicle.MASS] = ( time_delay * dTasTd_dWeight * GRAV_ENGLISH_LBM + ) J["delay_distance", Aircraft.Wing.AREA] = time_delay * dTasTd_dWingArea J["delay_distance", "CL_max"] = time_delay * dTasTd_dClMax - J["delay_distance", Dynamic.Mission.DENSITY] = time_delay * dTasTd_dRhoApp + J["delay_distance", Dynamic.Atmosphere.DENSITY] = time_delay * dTasTd_dRhoApp J["delay_distance", Mission.Landing.BRAKING_DELAY] = TAS_touchdown flare_alt = ( @@ -537,14 +546,15 @@ def compute_partials(self, inputs, J): / (2.0 * G * (landing_flare_load_factor - 1.0)) * dTheta_dRateOfSinkMax ) - J["flare_alt", Dynamic.Mission.MASS] = ( + J["flare_alt", Dynamic.Vehicle.MASS] = ( 1 / (2.0 * G * (landing_flare_load_factor - 1.0)) * ( 2 * TAS_glide * dTasGlide_dWeight * (theta**2 - gamma_touchdown**2) + TAS_glide**2 * (2 * theta * dTheta_dWeight - 2 * gamma_touchdown * dGammaTd_dWeight) - ) * GRAV_ENGLISH_LBM + ) + * GRAV_ENGLISH_LBM ) J["flare_alt", Aircraft.Wing.AREA] = ( 1 @@ -570,7 +580,7 @@ def compute_partials(self, inputs, J): * (2 * theta * dTheta_dClMax - 2 * gamma_touchdown * dGammaTd_dClMax) ) ) - J["flare_alt", Dynamic.Mission.DENSITY] = ( + J["flare_alt", Dynamic.Atmosphere.DENSITY] = ( 1 / (2.0 * G * (landing_flare_load_factor - 1.0)) * ( @@ -643,7 +653,7 @@ def setup(self): "CL_max", val=0.0, units="unitless", desc="CLMX: max CL at approach altitude" ) self.add_input( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=0.0, units="lbm", desc="WL: aircraft mass at start of landing", @@ -667,7 +677,7 @@ def setup(self): "touchdown_CD", "touchdown_CL", "thrust_idle", - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, "CL_max", Mission.Landing.STALL_VELOCITY, "TAS_touchdown", @@ -681,7 +691,7 @@ def setup(self): "touchdown_CD", "touchdown_CL", "thrust_idle", - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, "CL_max", Mission.Landing.STALL_VELOCITY, "TAS_touchdown", @@ -699,7 +709,7 @@ def setup(self): "touchdown_CD", "touchdown_CL", "thrust_idle", - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, "CL_max", Mission.Landing.STALL_VELOCITY, ], @@ -850,7 +860,9 @@ def compute_partials(self, inputs, J): J["ground_roll_distance", "thrust_idle"] = dGRD_dThrustIdle = ( -13.0287 * wing_loading_land * dALN_dThrustIdle / (density_ratio * DLRL) ) - J["ground_roll_distance", Dynamic.Mission.MASS] = dGRD_dWeight * GRAV_ENGLISH_LBM + J["ground_roll_distance", Dynamic.Vehicle.MASS] = ( + dGRD_dWeight * GRAV_ENGLISH_LBM + ) J["ground_roll_distance", "CL_max"] = dGRD_dClMax = ( -13.0287 * wing_loading_land * dALN_dClMax / (density_ratio * DLRL) ) @@ -867,8 +879,9 @@ def compute_partials(self, inputs, J): J[Mission.Landing.GROUND_DISTANCE, "touchdown_CD"] = dGRD_dTouchdownCD J[Mission.Landing.GROUND_DISTANCE, "touchdown_CL"] = dGRD_dTouchdownCL J[Mission.Landing.GROUND_DISTANCE, "thrust_idle"] = dGRD_dThrustIdle - J[Mission.Landing.GROUND_DISTANCE, Dynamic.Mission.MASS] = \ + J[Mission.Landing.GROUND_DISTANCE, Dynamic.Vehicle.MASS] = ( dGRD_dWeight * GRAV_ENGLISH_LBM + ) J[Mission.Landing.GROUND_DISTANCE, "CL_max"] = dGRD_dClMax J[Mission.Landing.GROUND_DISTANCE, Mission.Landing.STALL_VELOCITY] = dGRD_dTasStall @@ -902,10 +915,11 @@ def compute_partials(self, inputs, J): / (ground_roll_distance**2 * 2.0 * G) * dGRD_dThrustIdle ) - J["average_acceleration", Dynamic.Mission.MASS] = ( + J["average_acceleration", Dynamic.Vehicle.MASS] = ( -(TAS_touchdown**2.0) / (ground_roll_distance**2 * 2.0 * G) - * dGRD_dWeight * GRAV_ENGLISH_LBM + * dGRD_dWeight + * GRAV_ENGLISH_LBM ) J["average_acceleration", "CL_max"] = ( -(TAS_touchdown**2.0) diff --git a/aviary/mission/gasp_based/ode/landing_ode.py b/aviary/mission/gasp_based/ode/landing_ode.py index acb3627fd..6c984f03e 100644 --- a/aviary/mission/gasp_based/ode/landing_ode.py +++ b/aviary/mission/gasp_based/ode/landing_ode.py @@ -1,10 +1,14 @@ +import numpy as np + from aviary.subsystems.atmosphere.atmosphere import Atmosphere from aviary.mission.gasp_based.ode.base_ode import BaseODE from aviary.mission.gasp_based.ode.params import ParamPort from aviary.mission.gasp_based.ode.landing_eom import ( - GlideConditionComponent, LandingAltitudeComponent, - LandingGroundRollComponent) + GlideConditionComponent, + LandingAltitudeComponent, + LandingGroundRollComponent, +) from aviary.subsystems.aerodynamics.aerodynamics_builder import AerodynamicsBuilderBase from aviary.subsystems.propulsion.propulsion_builder import PropulsionBuilderBase from aviary.variable_info.enums import SpeedType @@ -38,15 +42,15 @@ def setup(self): subsys=Atmosphere(num_nodes=1, input_speed_type=SpeedType.MACH), promotes_inputs=[ (Dynamic.Mission.ALTITUDE, Mission.Landing.INITIAL_ALTITUDE), - (Dynamic.Mission.MACH, Mission.Landing.INITIAL_MACH), + (Dynamic.Atmosphere.MACH, Mission.Landing.INITIAL_MACH), ], promotes_outputs=[ - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, "viscosity", - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, ], ) @@ -55,21 +59,24 @@ def setup(self): if isinstance(subsystem, AerodynamicsBuilderBase): kwargs = {'method': 'low_speed'} aero_builder = subsystem - aero_system = subsystem.build_mission(num_nodes=1, - aviary_inputs=aviary_options, - **kwargs) + aero_system = subsystem.build_mission( + num_nodes=1, aviary_inputs=aviary_options, **kwargs + ) self.add_subsystem( subsystem.name, aero_system, promotes_inputs=[ "*", - (Dynamic.Mission.ALTITUDE, Mission.Landing.INITIAL_ALTITUDE), - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, + ( + Dynamic.Mission.ALTITUDE, + Mission.Landing.INITIAL_ALTITUDE, + ), + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, "viscosity", ("airport_alt", Mission.Landing.AIRPORT_ALTITUDE), - (Dynamic.Mission.MACH, Mission.Landing.INITIAL_MACH), - Dynamic.Mission.DYNAMIC_PRESSURE, + (Dynamic.Atmosphere.MACH, Mission.Landing.INITIAL_MACH), + Dynamic.Atmosphere.DYNAMIC_PRESSURE, ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_LANDING), ("t_init_flaps", "t_init_flaps_app"), ("t_init_gear", "t_init_gear_app"), @@ -89,20 +96,26 @@ def setup(self): if isinstance(subsystem, PropulsionBuilderBase): propulsion_system = subsystem.build_mission( num_nodes=1, aviary_inputs=aviary_options) - propulsion_mission = self.add_subsystem(subsystem.name, - propulsion_system, - promotes_inputs=[ - "*", (Dynamic.Mission.ALTITUDE, Mission.Landing.INITIAL_ALTITUDE), (Dynamic.Mission.MACH, Mission.Landing.INITIAL_MACH)], - promotes_outputs=[(Dynamic.Mission.THRUST_TOTAL, "thrust_idle")]) - propulsion_mission.set_input_defaults(Dynamic.Mission.THROTTLE, 0.0) + propulsion_mission = self.add_subsystem( + subsystem.name, + propulsion_system, + promotes_inputs=[ + "*", + (Dynamic.Atmosphere.MACH, Mission.Landing.INITIAL_MACH), + ], + promotes_outputs=[ + (Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "thrust_idle")], + ) + propulsion_mission.set_input_defaults( + Dynamic.Vehicle.Propulsion.THROTTLE, 0.0) self.add_subsystem( "glide", GlideConditionComponent(), promotes_inputs=[ - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, Mission.Landing.MAXIMUM_SINK_RATE, - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Aircraft.Wing.AREA, Mission.Landing.GLIDE_TO_STALL_RATIO, "CL_max", @@ -129,22 +142,20 @@ def setup(self): name='atmosphere_td', subsys=Atmosphere(num_nodes=1), promotes_inputs=[ - (Dynamic.Mission.ALTITUDE, Mission.Landing.AIRPORT_ALTITUDE), + Dynamic.Mission.ALTITUDE, (Dynamic.Mission.VELOCITY, "TAS_touchdown"), ], promotes_outputs=[ - (Dynamic.Mission.DENSITY, "rho_td"), - (Dynamic.Mission.SPEED_OF_SOUND, "sos_td"), - (Dynamic.Mission.TEMPERATURE, "T_td"), + (Dynamic.Atmosphere.DENSITY, "rho_td"), + (Dynamic.Atmosphere.SPEED_OF_SOUND, "sos_td"), + (Dynamic.Atmosphere.TEMPERATURE, "T_td"), ("viscosity", "viscosity_td"), - (Dynamic.Mission.DYNAMIC_PRESSURE, "q_td"), - (Dynamic.Mission.MACH, "mach_td"), + (Dynamic.Atmosphere.DYNAMIC_PRESSURE, "q_td"), + (Dynamic.Atmosphere.MACH, "mach_td"), ], ) - kwargs = {'method': 'low_speed', - 'retract_flaps': True, - 'retract_gear': False} + kwargs = {'method': 'low_speed', 'retract_flaps': True, 'retract_gear': False} self.add_subsystem( "aero_td", @@ -153,13 +164,13 @@ def setup(self): ), promotes_inputs=[ "*", - (Dynamic.Mission.ALTITUDE, Mission.Landing.AIRPORT_ALTITUDE), - (Dynamic.Mission.DENSITY, "rho_td"), - (Dynamic.Mission.SPEED_OF_SOUND, "sos_td"), + Dynamic.Mission.ALTITUDE, + (Dynamic.Atmosphere.DENSITY, "rho_td"), + (Dynamic.Atmosphere.SPEED_OF_SOUND, "sos_td"), ("viscosity", "viscosity_td"), ("airport_alt", Mission.Landing.AIRPORT_ALTITUDE), - (Dynamic.Mission.MACH, "mach_td"), - (Dynamic.Mission.DYNAMIC_PRESSURE, "q_td"), + (Dynamic.Atmosphere.MACH, "mach_td"), + (Dynamic.Atmosphere.DYNAMIC_PRESSURE, "q_td"), ("alpha", Aircraft.Wing.INCIDENCE), ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_LANDING), ("CL_max_flaps", Mission.Landing.LIFT_COEFFICIENT_MAX), @@ -194,11 +205,14 @@ def setup(self): "tr_distance", "delay_distance", "CL_max", - Dynamic.Mission.MASS, - 'mission:*' + Dynamic.Vehicle.MASS, + 'mission:*', ], promotes_outputs=[ - "ground_roll_distance", "average_acceleration", 'mission:*'], + "ground_roll_distance", + "average_acceleration", + 'mission:*', + ], ) ParamPort.set_default_vals(self) @@ -208,11 +222,16 @@ def setup(self): # landing doesn't change flap or gear position self.set_input_defaults("t_init_flaps_app", val=1e10) self.set_input_defaults("t_init_gear_app", val=1e10) - self.set_input_defaults( - Mission.Landing.INITIAL_ALTITUDE, val=50, units="ft") - self.set_input_defaults('aero_ramps.flap_factor:final_val', val=1.) - self.set_input_defaults('aero_ramps.gear_factor:final_val', val=1.) - self.set_input_defaults('aero_ramps.flap_factor:initial_val', val=0.) - self.set_input_defaults('aero_ramps.gear_factor:initial_val', val=0.) + self.set_input_defaults(Mission.Landing.INITIAL_ALTITUDE, val=50, units="ft") + self.set_input_defaults('aero_ramps.flap_factor:final_val', val=1.0) + self.set_input_defaults('aero_ramps.gear_factor:final_val', val=1.0) + self.set_input_defaults('aero_ramps.flap_factor:initial_val', val=0.0) + self.set_input_defaults('aero_ramps.gear_factor:initial_val', val=0.0) self.set_input_defaults(Aircraft.Wing.AREA, val=1.0, units="ft**2") + + # Throttle Idle + num_engine_types = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES)) + self.set_input_defaults( + Dynamic.Vehicle.Propulsion.THROTTLE, np.zeros((1, num_engine_types)) + ) diff --git a/aviary/mission/gasp_based/ode/rotation_eom.py b/aviary/mission/gasp_based/ode/rotation_eom.py index 49c3b7400..4c0014546 100644 --- a/aviary/mission/gasp_based/ode/rotation_eom.py +++ b/aviary/mission/gasp_based/ode/rotation_eom.py @@ -19,29 +19,61 @@ def setup(self): nn = self.options["num_nodes"] analysis_scheme = self.options["analysis_scheme"] - self.add_input(Dynamic.Mission.MASS, val=np.ones(nn), - desc="aircraft mass", units="lbm") - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.ones( - nn), desc=Dynamic.Mission.THRUST_TOTAL, units="lbf") - self.add_input(Dynamic.Mission.LIFT, val=np.ones( - nn), desc=Dynamic.Mission.LIFT, units="lbf") - self.add_input(Dynamic.Mission.DRAG, val=np.ones( - nn), desc=Dynamic.Mission.DRAG, units="lbf") - self.add_input(Dynamic.Mission.VELOCITY, val=np.ones(nn), - desc="true air speed", units="ft/s") - self.add_input(Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.ones(nn), - desc="flight path angle", units="rad") + self.add_input( + Dynamic.Vehicle.MASS, val=np.ones(nn), desc="aircraft mass", units="lbm" + ) + self.add_input( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=np.ones(nn), + desc=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.LIFT, + val=np.ones(nn), + desc=Dynamic.Vehicle.LIFT, + units="lbf", + ) + self.add_input( + Dynamic.Vehicle.DRAG, + val=np.ones(nn), + desc=Dynamic.Vehicle.DRAG, + units="lbf", + ) + self.add_input( + Dynamic.Mission.VELOCITY, + val=np.ones(nn), + desc="true air speed", + units="ft/s", + ) + self.add_input( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + val=np.ones(nn), + desc="flight path angle", + units="rad", + ) add_aviary_input(self, Aircraft.Wing.INCIDENCE, val=0.0, units="deg") self.add_input("alpha", val=np.ones(nn), desc="angle of attack", units="deg") - self.add_output(Dynamic.Mission.VELOCITY_RATE, val=np.ones(nn), - desc="TAS rate", units="ft/s**2") self.add_output( - Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, val=np.ones(nn), desc="flight path angle rate", units="rad/s" + Dynamic.Mission.VELOCITY_RATE, + val=np.ones(nn), + desc="TAS rate", + units="ft/s**2", + ) + self.add_output( + Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, + val=np.ones(nn), + desc="flight path angle rate", + units="rad/s", + ) + self.add_output( + Dynamic.Mission.ALTITUDE_RATE, + val=np.ones(nn), + desc="altitude rate", + units="ft/s", ) - self.add_output(Dynamic.Mission.ALTITUDE_RATE, val=np.ones(nn), - desc="altitude rate", units="ft/s") self.add_output( Dynamic.Mission.DISTANCE_RATE, val=np.ones(nn), desc="distance rate", units="ft/s" ) @@ -65,29 +97,49 @@ def setup_partials(self): self.declare_partials(Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, "*") self.declare_partials( Dynamic.Mission.VELOCITY_RATE, - [Dynamic.Mission.THRUST_TOTAL, "alpha", Dynamic.Mission.DRAG, - Dynamic.Mission.MASS, Dynamic.Mission.FLIGHT_PATH_ANGLE, Dynamic.Mission.LIFT], + [ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Dynamic.Vehicle.LIFT, + ], rows=arange, cols=arange, ) self.declare_partials(Dynamic.Mission.VELOCITY_RATE, [Aircraft.Wing.INCIDENCE]) - self.declare_partials(Dynamic.Mission.ALTITUDE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange) self.declare_partials( - Dynamic.Mission.DISTANCE_RATE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], rows=arange, cols=arange + Dynamic.Mission.ALTITUDE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, + ) + self.declare_partials( + Dynamic.Mission.DISTANCE_RATE, + [Dynamic.Mission.VELOCITY, Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=arange, + cols=arange, ) self.declare_partials( "normal_force", - [Dynamic.Mission.MASS, Dynamic.Mission.LIFT, - Dynamic.Mission.THRUST_TOTAL, "alpha"], + [ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.LIFT, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + ], rows=arange, cols=arange, ) self.declare_partials("normal_force", [Aircraft.Wing.INCIDENCE]) self.declare_partials( - "fuselage_pitch", Dynamic.Mission.FLIGHT_PATH_ANGLE, rows=arange, cols=arange, val=180 / np.pi, + "fuselage_pitch", + Dynamic.Mission.FLIGHT_PATH_ANGLE, + rows=arange, + cols=arange, + val=180 / np.pi, ) self.declare_partials("fuselage_pitch", "alpha", rows=arange, cols=arange, val=1) self.declare_partials("fuselage_pitch", Aircraft.Wing.INCIDENCE, val=-1) @@ -95,10 +147,10 @@ def setup_partials(self): def compute(self, inputs, outputs): analysis_scheme = self.options["analysis_scheme"] - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -138,10 +190,10 @@ def compute_partials(self, inputs, J): mu = MU_TAKEOFF - weight = inputs[Dynamic.Mission.MASS] * GRAV_ENGLISH_LBM - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - incremented_lift = inputs[Dynamic.Mission.LIFT] - incremented_drag = inputs[Dynamic.Mission.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * GRAV_ENGLISH_LBM + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + incremented_lift = inputs[Dynamic.Vehicle.LIFT] + incremented_drag = inputs[Dynamic.Vehicle.DRAG] TAS = inputs[Dynamic.Mission.VELOCITY] gamma = inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -178,7 +230,7 @@ def compute_partials(self, inputs, J): dNF_dIwing = -np.ones(nn) * dTAcF_dIwing dNF_dIwing[normal_force < 0] = 0 - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.THRUST_TOTAL] = ( + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( (dTAlF_dThrust - mu * dNF_dThrust) * GRAV_ENGLISH_GASP / weight ) J[Dynamic.Mission.VELOCITY_RATE, "alpha"] = ( @@ -187,9 +239,12 @@ def compute_partials(self, inputs, J): J[Dynamic.Mission.VELOCITY_RATE, Aircraft.Wing.INCIDENCE] = ( (dTAlF_dIwing - mu * dNF_dIwing) * GRAV_ENGLISH_GASP / weight ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.DRAG] = -GRAV_ENGLISH_GASP / weight - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.MASS] = ( - GRAV_ENGLISH_GASP * GRAV_ENGLISH_LBM + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.DRAG] = ( + -GRAV_ENGLISH_GASP / weight + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.MASS] = ( + GRAV_ENGLISH_GASP + * GRAV_ENGLISH_LBM * ( weight * (-np.sin(gamma) - mu * dNF_dWeight) - ( @@ -201,21 +256,25 @@ def compute_partials(self, inputs, J): ) / weight**2 ) - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = - \ - np.cos(gamma) * GRAV_ENGLISH_GASP - J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.LIFT] = GRAV_ENGLISH_GASP * \ - (-mu * dNF_dLift) / weight + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -np.cos(gamma) * GRAV_ENGLISH_GASP + ) + J[Dynamic.Mission.VELOCITY_RATE, Dynamic.Vehicle.LIFT] = ( + GRAV_ENGLISH_GASP * (-mu * dNF_dLift) / weight + ) J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = np.sin(gamma) - J[Dynamic.Mission.ALTITUDE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = TAS * np.cos(gamma) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + TAS * np.cos(gamma) + ) J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.VELOCITY] = np.cos(gamma) - J[Dynamic.Mission.DISTANCE_RATE, - Dynamic.Mission.FLIGHT_PATH_ANGLE] = -TAS * np.sin(gamma) + J[Dynamic.Mission.DISTANCE_RATE, Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -TAS * np.sin(gamma) + ) - J["normal_force", Dynamic.Mission.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM - J["normal_force", Dynamic.Mission.LIFT] = dNF_dLift - J["normal_force", Dynamic.Mission.THRUST_TOTAL] = dNF_dThrust + J["normal_force", Dynamic.Vehicle.MASS] = dNF_dWeight * GRAV_ENGLISH_LBM + J["normal_force", Dynamic.Vehicle.LIFT] = dNF_dLift + J["normal_force", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = dNF_dThrust J["normal_force", "alpha"] = dNF_dAlpha J["normal_force", Aircraft.Wing.INCIDENCE] = dNF_dIwing diff --git a/aviary/mission/gasp_based/ode/rotation_ode.py b/aviary/mission/gasp_based/ode/rotation_ode.py index 64f5eaa68..c4158b6b7 100644 --- a/aviary/mission/gasp_based/ode/rotation_ode.py +++ b/aviary/mission/gasp_based/ode/rotation_ode.py @@ -65,8 +65,9 @@ def setup(self): self.set_input_defaults("t_init_flaps", val=47.5, units='s') self.set_input_defaults("t_init_gear", val=37.3, units='s') self.set_input_defaults("alpha", val=np.ones(nn), units="deg") - self.set_input_defaults(Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units="deg") + self.set_input_defaults( + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units="deg" + ) self.set_input_defaults(Dynamic.Mission.ALTITUDE, val=np.zeros(nn), units="ft") self.set_input_defaults(Dynamic.Mission.VELOCITY, val=np.zeros(nn), units="kn") self.set_input_defaults("t_curr", val=np.zeros(nn), units="s") diff --git a/aviary/mission/gasp_based/ode/taxi_eom.py b/aviary/mission/gasp_based/ode/taxi_eom.py index cd548d7bd..8f4f5d5c0 100644 --- a/aviary/mission/gasp_based/ode/taxi_eom.py +++ b/aviary/mission/gasp_based/ode/taxi_eom.py @@ -18,7 +18,7 @@ def initialize(self): def setup(self): self.add_input( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, val=1.0, units="lbm/s", desc="fuel flow rate", @@ -32,7 +32,7 @@ def setup(self): desc="taxi_fuel_consumed", ) self.add_output( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=175000.0, units="lbm", desc="mass after taxi", @@ -40,22 +40,30 @@ def setup(self): def setup_partials(self): self.declare_partials( - "taxi_fuel_consumed", [ - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL]) - self.declare_partials( - Dynamic.Mission.MASS, Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL) + "taxi_fuel_consumed", + [Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL], + ) self.declare_partials( - Dynamic.Mission.MASS, Mission.Summary.GROSS_MASS, val=1) + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + ) + self.declare_partials(Dynamic.Vehicle.MASS, Mission.Summary.GROSS_MASS, val=1) def compute(self, inputs, outputs): fuelflow, takeoff_mass = inputs.values() dt_taxi = self.options['aviary_options'].get_val(Mission.Taxi.DURATION, 's') outputs["taxi_fuel_consumed"] = -fuelflow * dt_taxi - outputs[Dynamic.Mission.MASS] = takeoff_mass - outputs["taxi_fuel_consumed"] + 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') - J["taxi_fuel_consumed", Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL] = -dt_taxi + J[ + "taxi_fuel_consumed", + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + ] = -dt_taxi - J[Dynamic.Mission.MASS, Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL] = dt_taxi + J[ + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + ] = dt_taxi diff --git a/aviary/mission/gasp_based/ode/taxi_ode.py b/aviary/mission/gasp_based/ode/taxi_ode.py index 0c69e60db..dce4fe403 100644 --- a/aviary/mission/gasp_based/ode/taxi_ode.py +++ b/aviary/mission/gasp_based/ode/taxi_ode.py @@ -1,3 +1,11 @@ +import openmdao.api as om +import numpy as np + +from aviary.subsystems.atmosphere.atmosphere import Atmosphere +from aviary.utils.aviary_values import AviaryValues +from aviary.utils.functions import add_opts2vals, create_opts2vals + +from aviary.variable_info.enums import SpeedType from aviary.mission.gasp_based.ode.base_ode import BaseODE from aviary.mission.gasp_based.ode.params import ParamPort from aviary.mission.gasp_based.ode.taxi_eom import TaxiFuelComponent @@ -5,7 +13,7 @@ from aviary.subsystems.propulsion.propulsion_builder import PropulsionBuilderBase from aviary.utils.aviary_values import AviaryValues from aviary.utils.functions import add_opts2vals, create_opts2vals -from aviary.variable_info.variables import Dynamic, Mission +from aviary.variable_info.variables import Aircraft, Dynamic, Mission class TaxiSegment(BaseODE): @@ -17,33 +25,69 @@ def setup(self): self.add_subsystem("params", ParamPort(), promotes=["*"]) + add_opts2vals(self, create_opts2vals([Mission.Taxi.MACH]), options) + + alias_comp = om.ExecComp( + 'alt=airport_alt', + alt={ + 'val': np.zeros(1), + 'units': 'ft', + }, + airport_alt={'val': np.zeros(1), 'units': 'ft'}, + has_diag_partials=True, + ) + + alias_comp.add_expr( + 'mach=taxi_mach', + mach={'val': np.zeros(1), 'units': 'unitless'}, + taxi_mach={'val': np.zeros(1), 'units': 'unitless'}, + ) + + self.add_subsystem( + 'alias_taxi_phase', + alias_comp, + promotes_inputs=[ + ('airport_alt', Mission.Takeoff.AIRPORT_ALTITUDE), + ('taxi_mach', Mission.Taxi.MACH), + ], + promotes_outputs=[ + ('alt', Dynamic.Mission.ALTITUDE), + ('mach', Dynamic.Atmosphere.MACH), + ], + ) + self.add_subsystem( name='atmosphere', - subsys=Atmosphere(num_nodes=1), + subsys=Atmosphere(num_nodes=1, input_speed_type=SpeedType.MACH), promotes=[ '*', - (Dynamic.Mission.ALTITUDE, Mission.Takeoff.AIRPORT_ALTITUDE), ], ) - add_opts2vals(self, create_opts2vals( - [Mission.Taxi.MACH]), options) - for subsystem in core_subsystems: if isinstance(subsystem, PropulsionBuilderBase): system = subsystem.build_mission(num_nodes=1, aviary_inputs=options) - self.add_subsystem(subsystem.name, - system, - promotes_inputs=['*', (Dynamic.Mission.ALTITUDE, Mission.Takeoff.AIRPORT_ALTITUDE), - (Dynamic.Mission.MACH, Mission.Taxi.MACH)], - promotes_outputs=['*']) + self.add_subsystem( + subsystem.name, + system, + promotes_inputs=[ + '*', + (Dynamic.Mission.ALTITUDE, Mission.Takeoff.AIRPORT_ALTITUDE), + (Dynamic.Atmosphere.MACH, Mission.Taxi.MACH), + ], + promotes_outputs=['*'], + ) - self.add_subsystem("taxifuel", TaxiFuelComponent( - aviary_options=options), promotes=["*"]) + self.add_subsystem( + "taxifuel", TaxiFuelComponent(aviary_options=options), promotes=["*"] + ) ParamPort.set_default_vals(self) self.set_input_defaults(Mission.Taxi.MACH, 0) # Throttle Idle - self.set_input_defaults('throttle', 0.0) + num_engine_types = len(options.get_val(Aircraft.Engine.NUM_ENGINES)) + self.set_input_defaults( + Dynamic.Vehicle.Propulsion.THROTTLE, np.zeros((1, num_engine_types)) + ) diff --git a/aviary/mission/gasp_based/ode/test/test_accel_eom.py b/aviary/mission/gasp_based/ode/test/test_accel_eom.py index bb3d8c5f4..697038fb5 100644 --- a/aviary/mission/gasp_based/ode/test/test_accel_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_accel_eom.py @@ -24,16 +24,19 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([174878, 174878]), units="lbm" + Dynamic.Vehicle.MASS, np.array([174878, 174878]), units="lbm" ) self.prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([2635.225, 2635.225]), units="lbf" + Dynamic.Vehicle.DRAG, np.array([2635.225, 2635.225]), units="lbf" ) # note: this input value is not provided in the GASP data, so an estimation was made based on another similar data point self.prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([32589, 32589]), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + np.array([32589, 32589]), + units="lbf", ) self.prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, np.array([252, 252]), units="kn") + Dynamic.Mission.VELOCITY, np.array([252, 252]), units="kn" + ) self.prob.setup(check=False, force_alloc_complex=True) @@ -43,8 +46,9 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [5.51533958, 5.51533958]), tol + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([5.51533958, 5.51533958]), + tol, # note: this was finite differenced from GASP. The fd value is: np.array([5.2353365, 5.2353365]) ) assert_near_equal( diff --git a/aviary/mission/gasp_based/ode/test/test_accel_ode.py b/aviary/mission/gasp_based/ode/test/test_accel_ode.py index dad78c543..39b25f670 100644 --- a/aviary/mission/gasp_based/ode/test/test_accel_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_accel_ode.py @@ -36,18 +36,22 @@ def test_accel(self): throttle_climb = 0.956 self.prob.set_val(Dynamic.Mission.ALTITUDE, [500, 500], units="ft") self.prob.set_val( - Dynamic.Mission.THROTTLE, [ - throttle_climb, throttle_climb], units='unitless') + Dynamic.Vehicle.Propulsion.THROTTLE, + [throttle_climb, throttle_climb], + units='unitless', + ) self.prob.set_val(Dynamic.Mission.VELOCITY, [185, 252], units="kn") - self.prob.set_val(Dynamic.Mission.MASS, [174974, 174878], units="lbm") + self.prob.set_val(Dynamic.Vehicle.MASS, [174974, 174878], units="lbm") set_params_for_unit_tests(self.prob) self.prob.run_model() testvals = { - Dynamic.Mission.LIFT: [174974, 174878], - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL: [ - -13262.73, -13567.53] # lbm/h + Dynamic.Vehicle.LIFT: [174974, 174878], + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL: [ + -13262.73, + -13567.53, + ], # lbm/h } check_prob_outputs(self.prob, testvals, rtol=1e-6) diff --git a/aviary/mission/gasp_based/ode/test/test_ascent_eom.py b/aviary/mission/gasp_based/ode/test/test_ascent_eom.py index c675b000e..340240369 100644 --- a/aviary/mission/gasp_based/ode/test/test_ascent_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_ascent_eom.py @@ -14,19 +14,23 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("group", AscentEOM(num_nodes=2), promotes=["*"]) self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, val=175400 * np.ones(2), units="lbm" + Dynamic.Vehicle.MASS, val=175400 * np.ones(2), units="lbm" ) self.prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" ) self.prob.model.set_input_defaults( - Dynamic.Mission.LIFT, val=200 * np.ones(2), units="lbf") + Dynamic.Vehicle.LIFT, val=200 * np.ones(2), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.DRAG, val=10000 * np.ones(2), units="lbf") + Dynamic.Vehicle.DRAG, val=10000 * np.ones(2), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s") + Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(2), units="rad") + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(2), units="rad" + ) self.prob.model.set_input_defaults(Aircraft.Wing.INCIDENCE, val=0, units="deg") self.prob.model.set_input_defaults("alpha", val=np.zeros(2), units="deg") @@ -38,12 +42,14 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [2.202965, 2.202965]), tol + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([2.202965, 2.202965]), + tol, ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [-3.216328, -3.216328]), tol + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], + np.array([-3.216328, -3.216328]), + tol, ) partial_data = self.prob.check_partials(out_stream=None, method="cs") @@ -67,15 +73,17 @@ def test_case1(self): prob = om.Problem() prob.model.add_subsystem("group", AscentEOM(num_nodes=2), promotes=["*"]) prob.model.set_input_defaults( - Dynamic.Mission.MASS, val=175400 * np.ones(2), units="lbm" + Dynamic.Vehicle.MASS, val=175400 * np.ones(2), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, val=200 * np.ones(2), units="lbf") + Dynamic.Vehicle.LIFT, val=200 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, val=10000 * np.ones(2), units="lbf") + Dynamic.Vehicle.DRAG, val=10000 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s") prob.model.set_input_defaults( diff --git a/aviary/mission/gasp_based/ode/test/test_ascent_ode.py b/aviary/mission/gasp_based/ode/test/test_ascent_ode.py index 11d85c4ab..ea6c70248 100644 --- a/aviary/mission/gasp_based/ode/test/test_ascent_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_ascent_ode.py @@ -40,14 +40,18 @@ def test_ascent_partials(self): tol = tol = 1e-6 assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [641174.75, 641174.75]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([641174.75, 641174.75]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [2260.644, 2260.644]), tol) + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], + np.array([2260.644, 2260.644]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( [168.781, 168.781]), tol) diff --git a/aviary/mission/gasp_based/ode/test/test_breguet_cruise_eom.py b/aviary/mission/gasp_based/ode/test/test_breguet_cruise_eom.py index b563c2efe..4f79823ee 100644 --- a/aviary/mission/gasp_based/ode/test/test_breguet_cruise_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_breguet_cruise_eom.py @@ -26,7 +26,7 @@ def setUp(self): self.prob.set_val("TAS_cruise", 458.8, units="kn") self.prob.set_val("mass", np.linspace(171481, 171481 - 10000, nn), units="lbm") - self.prob.set_val(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - + self.prob.set_val(Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - 5870 * np.ones(nn,), units="lbm/h") def test_case1(self): @@ -62,7 +62,13 @@ def setUp(self): self.prob.model.set_input_defaults( "mass", np.linspace(171481, 171481 - 10000, nn), units="lbm") self.prob.model.set_input_defaults( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, -5870 * np.ones(nn,), units="lbm/h") + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + -5870 + * np.ones( + nn, + ), + units="lbm/h", + ) self.prob.setup(check=False, force_alloc_complex=True) @@ -109,7 +115,13 @@ def test_partials(self): prob.model.set_input_defaults( "mass", np.linspace(171481, 171481 - 10000, nn), units="lbm") prob.model.set_input_defaults( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, -5870 * np.ones(nn,), units="lbm/h") + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + -5870 + * np.ones( + nn, + ), + units="lbm/h", + ) prob.setup(check=False, force_alloc_complex=True) partial_data = prob.check_partials(out_stream=None, method="cs") @@ -128,8 +140,14 @@ def setUp(self): self.prob.set_val("TAS_cruise", 458.8, units="kn") self.prob.set_val("mass", np.linspace(171481, 171481 - 10000, nn), units="lbm") - self.prob.set_val(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - - 5870 * np.ones(nn,), units="lbm/h") + self.prob.set_val( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + -5870 + * np.ones( + nn, + ), + units="lbm/h", + ) def test_results(self): self.prob.run_model() @@ -138,9 +156,9 @@ def test_results(self): V = self.prob.get_val("TAS_cruise", units="kn") r = self.prob.get_val("cruise_range", units="NM") t = self.prob.get_val("cruise_time", units="h") - fuel_flow = - \ - self.prob.get_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units="lbm/h") + fuel_flow = -self.prob.get_val( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units="lbm/h" + ) v_avg = (V[:-1] + V[1:])/2 fuel_flow_avg = (fuel_flow[:-1] + fuel_flow[1:])/2 diff --git a/aviary/mission/gasp_based/ode/test/test_breguet_cruise_ode.py b/aviary/mission/gasp_based/ode/test/test_breguet_cruise_ode.py index faf6ff3be..23e79bc82 100644 --- a/aviary/mission/gasp_based/ode/test/test_breguet_cruise_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_breguet_cruise_ode.py @@ -19,22 +19,24 @@ def setUp(self): aviary_options = get_option_defaults() aviary_options.set_val(Aircraft.Engine.GLOBAL_THROTTLE, True) default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(aviary_options)) + 'GASP', build_engine_deck(aviary_options) + ) self.prob.model = BreguetCruiseODESolution( num_nodes=2, aviary_options=aviary_options, - core_subsystems=default_mission_subsystems) + core_subsystems=default_mission_subsystems, + ) self.prob.model.set_input_defaults( - Dynamic.Mission.MACH, np.array([0, 0]), units="unitless" + Dynamic.Atmosphere.MACH, np.array([0, 0]), units="unitless" ) def test_cruise(self): # test partial derivatives self.prob.setup(check=False, force_alloc_complex=True) - self.prob.set_val(Dynamic.Mission.MACH, [0.7, 0.7], units="unitless") + self.prob.set_val(Dynamic.Atmosphere.MACH, [0.7, 0.7], units="unitless") self.prob.set_val("interference_independent_of_shielded_area", 1.89927266) self.prob.set_val("drag_loss_due_to_shielded_wing_area", 68.02065834) @@ -44,20 +46,22 @@ def test_cruise(self): tol = tol = 1e-6 assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [1.0, 1.0]), tol) - assert_near_equal( - self.prob[Dynamic.Mission.DISTANCE], np.array( - [0.0, 881.8116]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], np.array([1.0, 1.0]), tol + ) assert_near_equal( - self.prob["time"], np.array( - [0, 7906.83]), tol) + self.prob[Dynamic.Mission.DISTANCE], np.array([0.0, 882.5769]), tol + ) + assert_near_equal(self.prob["time"], np.array([0, 7913.69]), tol) assert_near_equal( - self.prob[Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS], np.array( - [3.429719, 4.433518]), tol) + self.prob[Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS], + np.array([3.439203, 4.440962]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE_MAX], np.array( - [-17.63194, -16.62814]), tol) + self.prob[Dynamic.Mission.ALTITUDE_RATE_MAX], + np.array([-17.622456, -16.62070]), + tol, + ) partial_data = self.prob.check_partials( out_stream=None, method="cs", excludes=["*USatm*", "*params*", "*aero*"] diff --git a/aviary/mission/gasp_based/ode/test/test_climb_eom.py b/aviary/mission/gasp_based/ode/test/test_climb_eom.py index ec9f04da5..0335b62f8 100644 --- a/aviary/mission/gasp_based/ode/test/test_climb_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_climb_eom.py @@ -21,15 +21,18 @@ def setUp(self): self.prob.model.add_subsystem("group", ClimbRates(num_nodes=2), promotes=["*"]) self.prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, np.array([459, 459]), units="kn") + Dynamic.Mission.VELOCITY, np.array([459, 459]), units="kn" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([10473, 10473]), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + np.array([10473, 10473]), + units="lbf", ) self.prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([9091.517, 9091.517]), units="lbf" + Dynamic.Vehicle.DRAG, np.array([9091.517, 9091.517]), units="lbf" ) self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([171481, 171481]), units="lbm" + Dynamic.Vehicle.MASS, np.array([171481, 171481]), units="lbm" ) self.prob.setup(check=False, force_alloc_complex=True) @@ -40,8 +43,9 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [6.24116612, 6.24116612]), tol + self.prob[Dynamic.Mission.ALTITUDE_RATE], + np.array([6.24116612, 6.24116612]), + tol, ) # note: values from GASP are: np.array([5.9667, 5.9667]) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( @@ -54,8 +58,9 @@ def test_case1(self): tol, ) # note: values from GASP are: np.array([170316.2, 170316.2]) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE], np.array( - [0.00805627, 0.00805627]), tol + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE], + np.array([0.00805627, 0.00805627]), + tol, ) # note: values from GASP are:np.array([.0076794487, .0076794487]) partial_data = self.prob.check_partials(out_stream=None, method="cs") @@ -81,13 +86,15 @@ def test_case1(self): prob.model.set_input_defaults( Dynamic.Mission.VELOCITY, np.array([459, 459]), units="kn") prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([10473, 10473]), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + np.array([10473, 10473]), + units="lbf", ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([9091.517, 9091.517]), units="lbf" + Dynamic.Vehicle.DRAG, np.array([9091.517, 9091.517]), units="lbf" ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([171481, 171481]), units="lbm" + Dynamic.Vehicle.MASS, np.array([171481, 171481]), units="lbm" ) prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/mission/gasp_based/ode/test/test_climb_ode.py b/aviary/mission/gasp_based/ode/test/test_climb_ode.py index 3448cd65e..2df625238 100644 --- a/aviary/mission/gasp_based/ode/test/test_climb_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_climb_ode.py @@ -9,6 +9,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.enums import Verbosity from aviary.variable_info.options import get_option_defaults from aviary.variable_info.variables import Aircraft, Dynamic @@ -22,17 +23,19 @@ def setUp(self): self.prob = om.Problem() aviary_options = get_option_defaults() + aviary_options.set_val('verbosity', Verbosity.QUIET) aviary_options.set_val(Aircraft.Engine.GLOBAL_THROTTLE, True) default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(aviary_options)) + 'GASP', build_engine_deck(aviary_options) + ) self.sys = self.prob.model = ClimbODE( num_nodes=1, EAS_target=250, mach_cruise=0.8, aviary_options=aviary_options, - core_subsystems=default_mission_subsystems + core_subsystems=default_mission_subsystems, ) def test_start_of_climb(self): @@ -43,9 +46,10 @@ def test_start_of_climb(self): throttle_climb = 0.956 self.prob.set_val( - Dynamic.Mission.THROTTLE, throttle_climb, units='unitless') + Dynamic.Vehicle.Propulsion.THROTTLE, throttle_climb, units='unitless' + ) self.prob.set_val(Dynamic.Mission.ALTITUDE, 1000, units="ft") - self.prob.set_val(Dynamic.Mission.MASS, 174845, units="lbm") + self.prob.set_val(Dynamic.Vehicle.MASS, 174845, units="lbm") self.prob.set_val("EAS", 250, units="kn") # slightly greater than zero to help check partials self.prob.set_val(Aircraft.Wing.INCIDENCE, 0.0000001, units="deg") @@ -60,11 +64,12 @@ def test_start_of_climb(self): "alpha": 5.16398, "CL": 0.59766664, "CD": 0.03070836, - Dynamic.Mission.ALTITUDE_RATE: 3414.63 / 60, # ft/s - # TAS (kts -> ft/s) * cos(gamma), 253.6827 * 1.68781 * cos(0.13331060446181708) + Dynamic.Mission.ALTITUDE_RATE: 3414.624 / 60, # ft/s + # TAS (kts -> ft/s) * cos(gamma), 253.6827 * 1.68781 * + # cos(0.13331060446181708) Dynamic.Mission.DISTANCE_RATE: 424.36918705874785, # ft/s - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL: -13448.29, # lbm/h - "theta": 0.22343879616956605, # rad (12.8021 deg) + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL: -13448.29, # lbm/h + "theta": 0.22343906, # rad (12.8021 deg) Dynamic.Mission.FLIGHT_PATH_ANGLE: 0.13331060446181708, # rad (7.638135 deg) } check_prob_outputs(self.prob, testvals, rtol=1e-6) @@ -84,10 +89,14 @@ def test_end_of_climb(self): throttle_climb = 0.956 self.prob.set_val( - Dynamic.Mission.THROTTLE, np.array([ - throttle_climb, throttle_climb]), units='unitless') - self.prob.set_val(Dynamic.Mission.ALTITUDE, np.array([11000, 37000]), units="ft") - self.prob.set_val(Dynamic.Mission.MASS, np.array([174149, 171592]), units="lbm") + Dynamic.Vehicle.Propulsion.THROTTLE, + np.array([throttle_climb, throttle_climb]), + units='unitless', + ) + self.prob.set_val( + Dynamic.Mission.ALTITUDE, np.array([11000, 37000]), units="ft" + ) + self.prob.set_val(Dynamic.Vehicle.MASS, np.array([174149, 171592]), units="lbm") self.prob.set_val("EAS", np.array([270, 270]), units="kn") self.prob.set_val("interference_independent_of_shielded_area", 1.89927266) self.prob.set_val("drag_loss_due_to_shielded_wing_area", 68.02065834) @@ -97,16 +106,19 @@ def test_end_of_climb(self): self.prob.run_model() testvals = { - "alpha": [4.05559, 4.08245], - "CL": [0.512629, 0.617725], - "CD": [0.02692764, 0.03311237], - Dynamic.Mission.ALTITUDE_RATE: [3053.754 / 60, 429.665 / 60], # ft/s + "alpha": [4.0557, 4.06615], + "CL": [0.512628, 0.615819], + "CD": [0.02692759, 0.03299578], + Dynamic.Mission.ALTITUDE_RATE: [3053.64 / 60, 430.746 / 60], # ft/s # TAS (kts -> ft/s) * cos(gamma), [319, 459] kts - Dynamic.Mission.DISTANCE_RATE: [536.2835, 774.4118], # ft/s - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL: [-11420.05, -6050.26], - "theta": [0.16540479, 0.08049912], # rad ([9.47699, 4.61226] deg), - Dynamic.Mission.FLIGHT_PATH_ANGLE: [0.09462135, 0.00924686], # rad, gamma - Dynamic.Mission.THRUST_TOTAL: [25560.51, 10784.25], + Dynamic.Mission.DISTANCE_RATE: [536.23446, 774.40085], # ft/s + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL: [ + -11419.94, + -6050.26, + ], + "theta": [0.16541191, 0.08023799], # rad ([9.47740, 4.59730] deg), + Dynamic.Mission.FLIGHT_PATH_ANGLE: [0.09462652, 0.00927027], # rad, gamma + Dynamic.Vehicle.Propulsion.THRUST_TOTAL: [25561.393, 10784.245], } check_prob_outputs(self.prob, testvals, 1e-6) diff --git a/aviary/mission/gasp_based/ode/test/test_descent_eom.py b/aviary/mission/gasp_based/ode/test/test_descent_eom.py index 414a6ebc4..baef579ee 100644 --- a/aviary/mission/gasp_based/ode/test/test_descent_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_descent_eom.py @@ -23,14 +23,16 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, np.array([459, 459]), units="kn") + Dynamic.Mission.VELOCITY, np.array([459, 459]), units="kn" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([452, 452]), units="lbf") + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([452, 452]), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([7966.927, 7966.927]), units="lbf" + Dynamic.Vehicle.DRAG, np.array([7966.927, 7966.927]), units="lbf" ) # estimated from GASP values self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([147661, 147661]), units="lbm" + Dynamic.Vehicle.MASS, np.array([147661, 147661]), units="lbm" ) self.prob.model.set_input_defaults("alpha", np.array([3.2, 3.2]), units="deg") @@ -42,8 +44,9 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [-39.41011217, -39.41011217]), tol + self.prob[Dynamic.Mission.ALTITUDE_RATE], + np.array([-39.41011217, -39.41011217]), + tol, ) # note: values from GASP are: np.array([-39.75, -39.75]) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( @@ -54,10 +57,12 @@ def test_case1(self): self.prob["required_lift"], np.array([147444.58096139, 147444.58096139]), tol, - ) # note: values from GASP are: np.array([146288.8, 146288.8]) (estimated based on GASP values) + # note: values from GASP are: np.array([146288.8, 146288.8]) (estimated based on GASP values) + ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE], np.array( - [-0.05089311, -0.05089311]), tol + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE], + np.array([-0.05089311, -0.05089311]), + tol, ) # note: values from GASP are: np.array([-.0513127, -.0513127]) partial_data = self.prob.check_partials(out_stream=None, method="cs") @@ -85,12 +90,13 @@ def test_case1(self): prob.model.set_input_defaults( Dynamic.Mission.VELOCITY, np.array([459, 459]), units="kn") prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, np.array([452, 452]), units="lbf") + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, np.array([452, 452]), units="lbf" + ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, np.array([7966.927, 7966.927]), units="lbf" + Dynamic.Vehicle.DRAG, np.array([7966.927, 7966.927]), units="lbf" ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, np.array([147661, 147661]), units="lbm" + Dynamic.Vehicle.MASS, np.array([147661, 147661]), units="lbm" ) prob.model.set_input_defaults("alpha", np.array([3.2, 3.2]), units="deg") prob.setup(check=False, force_alloc_complex=True) diff --git a/aviary/mission/gasp_based/ode/test/test_descent_ode.py b/aviary/mission/gasp_based/ode/test/test_descent_ode.py index 1fa46aea7..2b823203a 100644 --- a/aviary/mission/gasp_based/ode/test/test_descent_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_descent_ode.py @@ -26,14 +26,20 @@ def setUp(self): aviary_options = get_option_defaults() default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(aviary_options)) + 'GASP', build_engine_deck(aviary_options) + ) - self.sys = self.prob.model = DescentODE(num_nodes=1, - mach_cruise=0.8, - aviary_options=get_option_defaults(), - core_subsystems=default_mission_subsystems) + self.sys = self.prob.model = DescentODE( + num_nodes=1, + mach_cruise=0.8, + aviary_options=get_option_defaults(), + core_subsystems=default_mission_subsystems + ) - @unittest.skipIf(version.parse(openmdao.__version__) < version.parse("3.26"), "Skipping due to OpenMDAO version being too low (<3.26)") + @unittest.skipIf( + version.parse(openmdao.__version__) < version.parse("3.26"), + "Skipping due to OpenMDAO version being too low (<3.26)", + ) def test_high_alt(self): # Test descent above 10k ft with Mach under and over the EAS limit self.sys.options["num_nodes"] = 2 @@ -43,10 +49,12 @@ def test_high_alt(self): self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_val( - Dynamic.Mission.THROTTLE, np.array([ - 0, 0]), units='unitless') - self.prob.set_val(Dynamic.Mission.ALTITUDE, np.array([36500, 14500]), units="ft") - self.prob.set_val(Dynamic.Mission.MASS, np.array([147661, 147572]), units="lbm") + Dynamic.Vehicle.Propulsion.THROTTLE, np.array([0, 0]), units='unitless' + ) + self.prob.set_val( + Dynamic.Mission.ALTITUDE, np.array([36500, 14500]), units="ft" + ) + self.prob.set_val(Dynamic.Vehicle.MASS, np.array([147661, 147572]), units="lbm") self.prob.set_val("interference_independent_of_shielded_area", 1.89927266) self.prob.set_val("drag_loss_due_to_shielded_wing_area", 68.02065834) @@ -55,19 +63,21 @@ def test_high_alt(self): self.prob.run_model() testvals = { - "alpha": np.array([3.23388, 1.203234]), - "CL": np.array([0.51849367, 0.25908653]), - "CD": np.array([0.02794324, 0.01862946]), + "alpha": np.array([3.22047, 1.20346]), + "CL": np.array([0.5169255, 0.25908651]), + "CD": np.array([0.02786507, 0.01862951]), # ft/s - Dynamic.Mission.ALTITUDE_RATE: np.array([-2356.7705, -2877.9606]) / 60, + Dynamic.Mission.ALTITUDE_RATE: np.array([-39.28806432, -47.9587925]), # TAS (ft/s) * cos(gamma), [458.67774, 437.62297] kts - Dynamic.Mission.DISTANCE_RATE: [773.1637, 737.0653], # ft/s + Dynamic.Mission.DISTANCE_RATE: [773.1451, 736.9446], # ft/s # lbm/h - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL: np.array([-451.0239, -997.1514]), - "EAS": [417.87419406, 590.73344937], # ft/s ([247.58367, 349.99997] kts) - Dynamic.Mission.MACH: [0.8, 0.697266], + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL: np.array( + [-451.02392, -997.0488] + ), + "EAS": [418.50757579, 590.73344999], # ft/s ([247.95894, 349.99997] kts) + Dynamic.Atmosphere.MACH: [0.8, 0.697125], # gamma, rad ([-2.908332, -3.723388] deg) - Dynamic.Mission.FLIGHT_PATH_ANGLE: [-0.05075997, -0.06498538], + Dynamic.Mission.FLIGHT_PATH_ANGLE: [-0.05077223, -0.06498624], } check_prob_outputs(self.prob, testvals, rtol=1e-6) @@ -83,9 +93,9 @@ def test_low_alt(self): self.prob.setup(check=False, force_alloc_complex=True) - self.prob.set_val(Dynamic.Mission.THROTTLE, 0, units='unitless') + self.prob.set_val(Dynamic.Vehicle.Propulsion.THROTTLE, 0, units='unitless') self.prob.set_val(Dynamic.Mission.ALTITUDE, 1500, units="ft") - self.prob.set_val(Dynamic.Mission.MASS, 147410, units="lbm") + self.prob.set_val(Dynamic.Vehicle.MASS, 147410, units="lbm") self.prob.set_val("EAS", 250, units="kn") self.prob.set_val("interference_independent_of_shielded_area", 1.89927266) self.prob.set_val("drag_loss_due_to_shielded_wing_area", 68.02065834) @@ -98,10 +108,10 @@ def test_low_alt(self): "alpha": 4.19956, "CL": 0.507578, "CD": 0.0268404, - Dynamic.Mission.ALTITUDE_RATE: -1138.583 / 60, + Dynamic.Mission.ALTITUDE_RATE: -18.97635475, # TAS (ft/s) * cos(gamma) = 255.5613 * 1.68781 * cos(-0.0440083) - Dynamic.Mission.DISTANCE_RATE: 430.9213, - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL: -1295.11, + Dynamic.Mission.DISTANCE_RATE: 430.92063193, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL: -1295.11, Dynamic.Mission.FLIGHT_PATH_ANGLE: -0.0440083, # rad (-2.52149 deg) } check_prob_outputs(self.prob, testvals, rtol=1e-6) diff --git a/aviary/mission/gasp_based/ode/test/test_flight_path_eom.py b/aviary/mission/gasp_based/ode/test/test_flight_path_eom.py index 289e353e1..3a8d25203 100644 --- a/aviary/mission/gasp_based/ode/test/test_flight_path_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_flight_path_eom.py @@ -24,8 +24,10 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [-27.10027, -27.10027]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([-27.10027, -27.10027]), + tol, + ) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( [0.5403023, 0.5403023]), tol) @@ -39,11 +41,15 @@ def test_case1(self): self.prob["load_factor"], np.array( [1.883117, 1.883117]), tol) assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [0.841471, 0.841471]), tol) + self.prob[Dynamic.Mission.ALTITUDE_RATE], + np.array([0.841471, 0.841471]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [15.36423, 15.36423]), tol) + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], + np.array([15.36423, 15.36423]), + tol, + ) partial_data = self.prob.check_partials(out_stream=None, method="cs") assert_check_partials(partial_data, atol=1e-12, rtol=1e-12) @@ -59,8 +65,10 @@ def test_case2(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [-27.09537, -27.09537]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([-27.09537, -27.09537]), + tol, + ) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( [0.5403023, 0.5403023]), tol) diff --git a/aviary/mission/gasp_based/ode/test/test_flight_path_ode.py b/aviary/mission/gasp_based/ode/test/test_flight_path_ode.py index 4c043351d..e1889e16e 100644 --- a/aviary/mission/gasp_based/ode/test/test_flight_path_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_flight_path_ode.py @@ -24,11 +24,14 @@ def setUp(self): aviary_options = get_option_defaults() aviary_options.set_val(Aircraft.Engine.GLOBAL_THROTTLE, True) default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(aviary_options)) + 'GASP', build_engine_deck(aviary_options) + ) - self.fp = self.prob.model = FlightPathODE(num_nodes=2, - aviary_options=get_option_defaults(), - core_subsystems=default_mission_subsystems) + self.fp = self.prob.model = FlightPathODE( + num_nodes=2, + aviary_options=get_option_defaults(), + core_subsystems=default_mission_subsystems, + ) def test_case1(self): # ground_roll = False (the aircraft is not confined to the ground) @@ -38,7 +41,7 @@ def test_case1(self): set_params_for_unit_tests(self.prob) self.prob.set_val(Dynamic.Mission.VELOCITY, [100, 100], units="kn") - self.prob.set_val(Dynamic.Mission.MASS, [100000, 100000], units="lbm") + self.prob.set_val(Dynamic.Vehicle.MASS, [100000, 100000], units="lbm") self.prob.set_val(Dynamic.Mission.ALTITUDE, [500, 500], units="ft") self.prob.set_val("interference_independent_of_shielded_area", 1.89927266) self.prob.set_val("drag_loss_due_to_shielded_wing_area", 68.02065834) @@ -59,8 +62,7 @@ def test_case1(self): tol = 1e-6 assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [0, 0]), tol + self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array([0, 0]), tol ) partial_data = self.prob.check_partials( @@ -77,7 +79,7 @@ def test_case2(self): set_params_for_unit_tests(self.prob) self.prob.set_val(Dynamic.Mission.VELOCITY, [100, 100], units="kn") - self.prob.set_val(Dynamic.Mission.MASS, [100000, 100000], units="lbm") + self.prob.set_val(Dynamic.Vehicle.MASS, [100000, 100000], units="lbm") self.prob.set_val(Dynamic.Mission.ALTITUDE, [500, 500], units="ft") self.prob.set_val("interference_independent_of_shielded_area", 1.89927266) self.prob.set_val("drag_loss_due_to_shielded_wing_area", 68.02065834) diff --git a/aviary/mission/gasp_based/ode/test/test_groundroll_eom.py b/aviary/mission/gasp_based/ode/test/test_groundroll_eom.py index a1eaf3a25..30ec303ef 100644 --- a/aviary/mission/gasp_based/ode/test/test_groundroll_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_groundroll_eom.py @@ -16,19 +16,23 @@ def setUp(self): "group", GroundrollEOM(num_nodes=2), promotes=["*"] ) self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, val=175400 * np.ones(2), units="lbm" + Dynamic.Vehicle.MASS, val=175400 * np.ones(2), units="lbm" ) self.prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" ) self.prob.model.set_input_defaults( - Dynamic.Mission.LIFT, val=200 * np.ones(2), units="lbf") + Dynamic.Vehicle.LIFT, val=200 * np.ones(2), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.DRAG, val=10000 * np.ones(2), units="lbf") + Dynamic.Vehicle.DRAG, val=10000 * np.ones(2), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s") + Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(2), units="rad") + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(2), units="rad" + ) self.prob.model.set_input_defaults(Aircraft.Wing.INCIDENCE, val=0, units="deg") self.prob.model.set_input_defaults("alpha", val=np.zeros(2), units="deg") @@ -40,14 +44,16 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [1.5597, 1.5597]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([1.5597, 1.5597]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( [10.0, 10.0]), tol) @@ -80,15 +86,17 @@ def test_case1(self): "group", GroundrollEOM(num_nodes=2), promotes=["*"] ) prob.model.set_input_defaults( - Dynamic.Mission.MASS, val=175400 * np.ones(2), units="lbm" + Dynamic.Vehicle.MASS, val=175400 * np.ones(2), units="lbm" ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, val=200 * np.ones(2), units="lbf") + Dynamic.Vehicle.LIFT, val=200 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, val=10000 * np.ones(2), units="lbf") + Dynamic.Vehicle.DRAG, val=10000 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s") prob.model.set_input_defaults( diff --git a/aviary/mission/gasp_based/ode/test/test_groundroll_ode.py b/aviary/mission/gasp_based/ode/test/test_groundroll_ode.py index 580295777..66bb7c08b 100644 --- a/aviary/mission/gasp_based/ode/test/test_groundroll_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_groundroll_ode.py @@ -23,11 +23,14 @@ def setUp(self): aviary_options = get_option_defaults() aviary_options.set_val(Aircraft.Engine.GLOBAL_THROTTLE, True) default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(aviary_options)) + 'GASP', build_engine_deck(aviary_options) + ) - self.prob.model = GroundrollODE(num_nodes=2, - aviary_options=get_option_defaults(), - core_subsystems=default_mission_subsystems) + self.prob.model = GroundrollODE( + num_nodes=2, + aviary_options=get_option_defaults(), + core_subsystems=default_mission_subsystems, + ) def test_groundroll_partials(self): # Check partial derivatives diff --git a/aviary/mission/gasp_based/ode/test/test_landing_eom.py b/aviary/mission/gasp_based/ode/test/test_landing_eom.py index 15723113f..8ae2830df 100644 --- a/aviary/mission/gasp_based/ode/test/test_landing_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_landing_eom.py @@ -55,7 +55,7 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" + Dynamic.Atmosphere.DENSITY, RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" ) # value from online calculator self.prob.model.set_input_defaults( @@ -137,7 +137,7 @@ def test_case1(self): prob.model.add_subsystem( "group", GlideConditionComponent(), promotes=["*"]) prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" + Dynamic.Atmosphere.DENSITY, RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" ) prob.model.set_input_defaults( Mission.Landing.MAXIMUM_SINK_RATE, 900, units="ft/min") 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 08dfe2154..d22520f6c 100644 --- a/aviary/mission/gasp_based/ode/test/test_landing_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_landing_ode.py @@ -48,7 +48,7 @@ def test_dland(self): self.prob.set_val(Mission.Landing.TOUCHDOWN_SINK_RATE, 5, units="ft/s") self.prob.set_val(Mission.Landing.BRAKING_DELAY, 1, units="s") self.prob.set_val("mass", 165279, units="lbm") - self.prob.set_val(Dynamic.Mission.THROTTLE, 0.0, units='unitless') + self.prob.set_val(Dynamic.Vehicle.Propulsion.THROTTLE, 0.0, units='unitless') self.prob.run_model() diff --git a/aviary/mission/gasp_based/ode/test/test_rotation_eom.py b/aviary/mission/gasp_based/ode/test/test_rotation_eom.py index 13fdf4c28..ddf48c369 100644 --- a/aviary/mission/gasp_based/ode/test/test_rotation_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_rotation_eom.py @@ -14,19 +14,23 @@ def setUp(self): self.prob = om.Problem() self.prob.model.add_subsystem("group", RotationEOM(num_nodes=2), promotes=["*"]) self.prob.model.set_input_defaults( - Dynamic.Mission.MASS, val=175400 * np.ones(2), units="lbm" + Dynamic.Vehicle.MASS, val=175400 * np.ones(2), units="lbm" ) self.prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" ) self.prob.model.set_input_defaults( - Dynamic.Mission.LIFT, val=200 * np.ones(2), units="lbf") + Dynamic.Vehicle.LIFT, val=200 * np.ones(2), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.DRAG, val=10000 * np.ones(2), units="lbf") + Dynamic.Vehicle.DRAG, val=10000 * np.ones(2), units="lbf" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s") + Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s" + ) self.prob.model.set_input_defaults( - Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(2), units="rad") + Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(2), units="rad" + ) self.prob.model.set_input_defaults(Aircraft.Wing.INCIDENCE, val=0, units="deg") self.prob.model.set_input_defaults("alpha", val=np.zeros(2), units="deg") @@ -38,14 +42,16 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [1.5597, 1.5597]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([1.5597, 1.5597]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( [10., 10.]), tol) @@ -77,13 +83,17 @@ def test_case1(self): prob = om.Problem() prob.model.add_subsystem("group", RotationEOM(num_nodes=2), promotes=["*"]) prob.model.set_input_defaults( - Dynamic.Mission.MASS, val=175400 * np.ones(2), units="lbm") + Dynamic.Vehicle.MASS, val=175400 * np.ones(2), units="lbm" + ) prob.model.set_input_defaults( - Dynamic.Mission.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf") + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=22000 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( - Dynamic.Mission.LIFT, val=200 * np.ones(2), units="lbf") + Dynamic.Vehicle.LIFT, val=200 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( - Dynamic.Mission.DRAG, val=10000 * np.ones(2), units="lbf") + Dynamic.Vehicle.DRAG, val=10000 * np.ones(2), units="lbf" + ) prob.model.set_input_defaults( Dynamic.Mission.VELOCITY, val=10 * np.ones(2), units="ft/s") prob.model.set_input_defaults( diff --git a/aviary/mission/gasp_based/ode/test/test_rotation_ode.py b/aviary/mission/gasp_based/ode/test/test_rotation_ode.py index 8df6f9d19..5fdec7b11 100644 --- a/aviary/mission/gasp_based/ode/test/test_rotation_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_rotation_ode.py @@ -34,7 +34,7 @@ def test_rotation_partials(self): self.prob.setup(check=False, force_alloc_complex=True) self.prob.set_val(Aircraft.Wing.INCIDENCE, 1.5, units="deg") - self.prob.set_val(Dynamic.Mission.MASS, [100000, 100000], units="lbm") + self.prob.set_val(Dynamic.Vehicle.MASS, [100000, 100000], units="lbm") self.prob.set_val("alpha", [1.5, 1.5], units="deg") self.prob.set_val(Dynamic.Mission.VELOCITY, [100, 100], units="kn") self.prob.set_val("t_curr", [1, 2], units="s") @@ -47,14 +47,16 @@ def test_rotation_partials(self): tol = 1e-6 assert_near_equal( - self.prob[Dynamic.Mission.VELOCITY_RATE], np.array( - [13.66655, 13.66655]), tol) + self.prob[Dynamic.Mission.VELOCITY_RATE], + np.array([13.66655, 13.66655]), + tol, + ) assert_near_equal( - self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( - self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array( - [0.0, 0.0]), tol) + self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array([0.0, 0.0]), tol + ) assert_near_equal( self.prob[Dynamic.Mission.DISTANCE_RATE], np.array( [168.781, 168.781]), tol) 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 d4f1c968f..5afa6a3cd 100644 --- a/aviary/mission/gasp_based/ode/test/test_taxi_eom.py +++ b/aviary/mission/gasp_based/ode/test/test_taxi_eom.py @@ -26,8 +26,11 @@ def setUp(self): def test_fuel_consumed(self): self.prob.setup(force_alloc_complex=True) - self.prob.set_val(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - -1512, units="lbm/h") + self.prob.set_val( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + -1512, + units="lbm/h", + ) self.prob.set_val(Mission.Summary.GROSS_MASS, 175400.0, units="lbm") self.prob.run_model() 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 0c595da1a..95825f8db 100644 --- a/aviary/mission/gasp_based/ode/test/test_taxi_ode.py +++ b/aviary/mission/gasp_based/ode/test/test_taxi_ode.py @@ -26,12 +26,22 @@ def setUp(self): options = get_option_defaults() options.set_val(Mission.Taxi.DURATION, 0.1677, units="h") default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(options)) + 'GASP', build_engine_deck(options) + ) self.prob.model = TaxiSegment( - aviary_options=options, core_subsystems=default_mission_subsystems) + aviary_options=options, core_subsystems=default_mission_subsystems + ) - @unittest.skipIf(version.parse(openmdao.__version__) < version.parse("3.26"), "Skipping due to OpenMDAO version being too low (<3.26)") + self.prob.model.set_input_defaults( + Mission.Takeoff.AIRPORT_ALTITUDE, + 0.0, + ) + + @unittest.skipIf( + version.parse(openmdao.__version__) < version.parse("3.26"), + "Skipping due to OpenMDAO version being too low (<3.26)", + ) def test_taxi(self): self.prob.setup(check=False, force_alloc_complex=True) @@ -40,12 +50,15 @@ def test_taxi(self): self.prob.set_val(Mission.Takeoff.AIRPORT_ALTITUDE, 0, units="ft") self.prob.set_val(Mission.Taxi.MACH, 0.1, units="unitless") self.prob.set_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, -1512, units="lbm/h") + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + -1512, + units="lbm/h", + ) self.prob.run_model() testvals = { - Dynamic.Mission.MASS: 175190.3, # lbm + Dynamic.Vehicle.MASS: 175190.3, # lbm } check_prob_outputs(self.prob, testvals, rtol=1e-6) diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/gamma_comp.py b/aviary/mission/gasp_based/ode/unsteady_solved/gamma_comp.py index 84b35f540..07a5f7b91 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/gamma_comp.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/gamma_comp.py @@ -24,8 +24,12 @@ def setup(self): self.add_input("d2h_dr2", shape=nn, units="m/distance_units**2", desc="second derivative of altitude wrt range") - self.add_output(Dynamic.Mission.FLIGHT_PATH_ANGLE, shape=nn, units="rad", - desc="flight path angle") + self.add_output( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + shape=nn, + units="rad", + desc="flight path angle", + ) self.add_output("dgam_dr", shape=nn, units="rad/distance_units", desc="change in flight path angle per unit range traversed") @@ -34,8 +38,9 @@ def setup_partials(self): nn = self.options["num_nodes"] ar = np.arange(nn, dtype=int) - self.declare_partials(of=Dynamic.Mission.FLIGHT_PATH_ANGLE, - wrt="dh_dr", rows=ar, cols=ar) + self.declare_partials( + of=Dynamic.Mission.FLIGHT_PATH_ANGLE, wrt="dh_dr", rows=ar, cols=ar + ) self.declare_partials(of="dgam_dr", wrt=["dh_dr", "d2h_dr2"], rows=ar, cols=ar) def compute(self, inputs, outputs): @@ -49,6 +54,6 @@ def compute_partials(self, inputs, partials): dh_dr = inputs["dh_dr"] d2h_dr2 = inputs["d2h_dr2"] - partials[Dynamic.Mission.FLIGHT_PATH_ANGLE, "dh_dr"] = 1. / (dh_dr**2 + 1) + partials[Dynamic.Mission.FLIGHT_PATH_ANGLE, "dh_dr"] = 1.0 / (dh_dr**2 + 1) partials["dgam_dr", "dh_dr"] = -d2h_dr2 * dh_dr * 2 / (dh_dr**2 + 1)**2 partials["dgam_dr", "d2h_dr2"] = 1. / (dh_dr**2 + 1) diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_gamma_comp.py b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_gamma_comp.py index 6290cbc5e..5de32444d 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_gamma_comp.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_gamma_comp.py @@ -28,10 +28,10 @@ def _test_unsteady_flight_eom(self, ground_roll=False): p.setup(force_alloc_complex=True) p.set_val(Dynamic.Mission.VELOCITY, 250, units="kn") - p.set_val(Dynamic.Mission.MASS, 175_000, units="lbm") - p.set_val(Dynamic.Mission.THRUST_TOTAL, 20_000, units="lbf") - p.set_val(Dynamic.Mission.LIFT, 175_000, units="lbf") - p.set_val(Dynamic.Mission.DRAG, 20_000, units="lbf") + p.set_val(Dynamic.Vehicle.MASS, 175_000, units="lbm") + p.set_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, 20_000, units="lbf") + p.set_val(Dynamic.Vehicle.LIFT, 175_000, units="lbf") + p.set_val(Dynamic.Vehicle.DRAG, 20_000, units="lbf") p.set_val(Aircraft.Wing.INCIDENCE, 0.0, units="deg") if not ground_roll: @@ -71,17 +71,25 @@ def _test_unsteady_flight_eom(self, ground_roll=False): assert_near_equal(dgam_dt_approx, np.zeros(nn), tolerance=1.0E-12) p.set_val(Dynamic.Mission.VELOCITY, 250 + 10 * np.random.rand(nn), units="kn") - p.set_val(Dynamic.Mission.MASS, 175_000 + 1000 * np.random.rand(nn), units="lbm") - p.set_val(Dynamic.Mission.THRUST_TOTAL, 20_000 + - 100 * np.random.rand(nn), units="lbf") - p.set_val(Dynamic.Mission.LIFT, 175_000 + 1000 * np.random.rand(nn), units="lbf") - p.set_val(Dynamic.Mission.DRAG, 20_000 + 100 * np.random.rand(nn), units="lbf") + p.set_val( + Dynamic.Vehicle.MASS, 175_000 + 1000 * np.random.rand(nn), units="lbm" + ) + p.set_val( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + 20_000 + 100 * np.random.rand(nn), + units="lbf", + ) + p.set_val( + Dynamic.Vehicle.LIFT, 175_000 + 1000 * np.random.rand(nn), units="lbf" + ) + p.set_val(Dynamic.Vehicle.DRAG, 20_000 + 100 * np.random.rand(nn), units="lbf") p.set_val(Aircraft.Wing.INCIDENCE, np.random.rand(1), units="deg") if not ground_roll: p.set_val("alpha", 5 * np.random.rand(nn), units="deg") - p.set_val(Dynamic.Mission.FLIGHT_PATH_ANGLE, - 5 * np.random.rand(nn), units="deg") + p.set_val( + Dynamic.Mission.FLIGHT_PATH_ANGLE, 5 * np.random.rand(nn), units="deg" + ) p.set_val("dh_dr", 0.1 * np.random.rand(nn), units=None) p.set_val("d2h_dr2", 0.01 * np.random.rand(nn), units="1/m") @@ -100,20 +108,20 @@ def test_gamma_comp(self): nn = 2 p = om.Problem() - p.model.add_subsystem("gamma", - GammaComp(num_nodes=nn), - promotes_inputs=[ - "dh_dr", - "d2h_dr2"], - promotes_outputs=[ - Dynamic.Mission.FLIGHT_PATH_ANGLE, - "dgam_dr"]) + p.model.add_subsystem( + "gamma", + GammaComp(num_nodes=nn), + promotes_inputs=["dh_dr", "d2h_dr2"], + promotes_outputs=[Dynamic.Mission.FLIGHT_PATH_ANGLE, "dgam_dr"], + ) p.setup(force_alloc_complex=True) p.run_model() assert_near_equal( - p[Dynamic.Mission.FLIGHT_PATH_ANGLE], [0.78539816, 0.78539816], - tolerance=1.0E-6) + p[Dynamic.Mission.FLIGHT_PATH_ANGLE], + [0.78539816, 0.78539816], + tolerance=1.0e-6, + ) assert_near_equal( p["dgam_dr"], [0.5, 0.5], tolerance=1.0E-6) 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 2c6653816..b59740665 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 @@ -58,9 +58,11 @@ def _test_unsteady_alpha_thrust_iter_group(self, ground_roll=False): p.final_setup() - p.set_val(Dynamic.Mission.SPEED_OF_SOUND, 968.076 * np.ones(nn), units="ft/s") p.set_val( - Dynamic.Mission.DENSITY, 0.000659904 * np.ones(nn), units="slug/ft**3" + Dynamic.Atmosphere.SPEED_OF_SOUND, 968.076 * np.ones(nn), units="ft/s" + ) + p.set_val( + Dynamic.Atmosphere.DENSITY, 0.000659904 * np.ones(nn), units="slug/ft**3" ) p.set_val(Dynamic.Mission.VELOCITY, 487 * np.ones(nn), units="kn") p.set_val("mass", 170_000 * np.ones(nn), units="lbm") @@ -76,11 +78,14 @@ def _test_unsteady_alpha_thrust_iter_group(self, ground_roll=False): p.run_model() - drag = p.model.get_val(Dynamic.Mission.DRAG, units="lbf") - lift = p.model.get_val(Dynamic.Mission.LIFT, units="lbf") + drag = p.model.get_val(Dynamic.Vehicle.DRAG, units="lbf") + lift = p.model.get_val(Dynamic.Vehicle.LIFT, units="lbf") thrust_req = p.model.get_val("thrust_req", units="lbf") - gamma = 0 if ground_roll else p.model.get_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, units="deg") + gamma = ( + 0 + if ground_roll + else p.model.get_val(Dynamic.Mission.FLIGHT_PATH_ANGLE, units="deg") + ) weight = p.model.get_val("mass", units="lbm") * GRAV_ENGLISH_LBM iwing = p.model.get_val(Aircraft.Wing.INCIDENCE, units="deg") alpha = iwing if ground_roll else p.model.get_val("alpha", units="deg") diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_flight_conditions.py b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_flight_conditions.py index 3a2fb66c6..575359d02 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_flight_conditions.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_flight_conditions.py @@ -28,10 +28,10 @@ def _test_unsteady_flight_conditions(self, ground_roll=False, input_speed_type=S subsys=Atmosphere(num_nodes=nn, output_dsos_dh=True), promotes_inputs=[Dynamic.Mission.ALTITUDE], promotes_outputs=[ - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, "viscosity", "drhos_dh", "dsos_dh", @@ -59,16 +59,16 @@ def _test_unsteady_flight_conditions(self, ground_roll=False, input_speed_type=S p.set_val("dEAS_dr", np.zeros(nn), units="kn/km") else: p.set_val(Dynamic.Mission.ALTITUDE, 37500, units="ft") - p.set_val(Dynamic.Mission.MACH, 0.78, units="unitless") + p.set_val(Dynamic.Atmosphere.MACH, 0.78, units="unitless") p.set_val("dmach_dr", np.zeros(nn), units="unitless/km") p.run_model() - mach = p.get_val(Dynamic.Mission.MACH) + mach = p.get_val(Dynamic.Atmosphere.MACH) eas = p.get_val("EAS") tas = p.get_val(Dynamic.Mission.VELOCITY, units="m/s") - sos = p.get_val(Dynamic.Mission.SPEED_OF_SOUND, units="m/s") - rho = p.get_val(Dynamic.Mission.DENSITY, units="kg/m**3") + sos = p.get_val(Dynamic.Atmosphere.SPEED_OF_SOUND, units="m/s") + rho = p.get_val(Dynamic.Atmosphere.DENSITY, units="kg/m**3") rho_sl = RHO_SEA_LEVEL_METRIC dTAS_dt_approx = p.get_val("dTAS_dt_approx") diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_eom.py b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_eom.py index 30bab8230..fd08c80be 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_eom.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_eom.py @@ -28,9 +28,9 @@ def _test_unsteady_solved_eom(self, ground_roll=False): p.set_val(Dynamic.Mission.VELOCITY, 250, units="kn") p.set_val("mass", 175_000, units="lbm") - p.set_val(Dynamic.Mission.THRUST_TOTAL, 20_000, units="lbf") - p.set_val(Dynamic.Mission.LIFT, 175_000, units="lbf") - p.set_val(Dynamic.Mission.DRAG, 20_000, units="lbf") + p.set_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, 20_000, units="lbf") + p.set_val(Dynamic.Vehicle.LIFT, 175_000, units="lbf") + p.set_val(Dynamic.Vehicle.DRAG, 20_000, units="lbf") p.set_val(Aircraft.Wing.INCIDENCE, 0.0, units="deg") if not ground_roll: @@ -71,16 +71,20 @@ def _test_unsteady_solved_eom(self, ground_roll=False): p.set_val(Dynamic.Mission.VELOCITY, 250 + 10 * np.random.rand(nn), units="kn") p.set_val("mass", 175_000 + 1000 * np.random.rand(nn), units="lbm") - p.set_val(Dynamic.Mission.THRUST_TOTAL, 20_000 + - 100 * np.random.rand(nn), units="lbf") - p.set_val(Dynamic.Mission.LIFT, 175_000 + 1000 * np.random.rand(nn), units="lbf") - p.set_val(Dynamic.Mission.DRAG, 20_000 + 100 * np.random.rand(nn), units="lbf") + p.set_val( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + 20_000 + 100 * np.random.rand(nn), + units="lbf", + ) + p.set_val(Dynamic.Vehicle.LIFT, 175_000 + 1000 * np.random.rand(nn), units="lbf") + p.set_val(Dynamic.Vehicle.DRAG, 20_000 + 100 * np.random.rand(nn), units="lbf") p.set_val(Aircraft.Wing.INCIDENCE, np.random.rand(1), units="deg") if not ground_roll: p.set_val("alpha", 5 * np.random.rand(nn), units="deg") - p.set_val(Dynamic.Mission.FLIGHT_PATH_ANGLE, - 5 * np.random.rand(nn), units="deg") + p.set_val( + Dynamic.Mission.FLIGHT_PATH_ANGLE, 5 * np.random.rand(nn), units="deg" + ) p.set_val("dh_dr", 0.1 * np.random.rand(nn), units=None) p.set_val("d2h_dr2", 0.01 * np.random.rand(nn), units="1/m") @@ -121,10 +125,15 @@ def _test_unsteady_solved_eom(self, ground_roll=False): p.set_val(Dynamic.Mission.VELOCITY, 250 + 10 * np.random.rand(nn), units="kn") p.set_val("mass", 175_000 + 1000 * np.random.rand(nn), units="lbm") - p.set_val(Dynamic.Mission.THRUST_TOTAL, 20_000 + - 100 * np.random.rand(nn), units="lbf") - p.set_val(Dynamic.Mission.LIFT, 175_000 + 1000 * np.random.rand(nn), units="lbf") - p.set_val(Dynamic.Mission.DRAG, 20_000 + 100 * np.random.rand(nn), units="lbf") + p.set_val( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + 20_000 + 100 * np.random.rand(nn), + units="lbf", + ) + p.set_val( + Dynamic.Vehicle.LIFT, 175_000 + 1000 * np.random.rand(nn), units="lbf" + ) + p.set_val(Dynamic.Vehicle.DRAG, 20_000 + 100 * np.random.rand(nn), units="lbf") p.set_val(Aircraft.Wing.INCIDENCE, np.random.rand(1), units="deg") if not ground_roll: diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_ode.py b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_ode.py index a873b68c1..194e2f40c 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_ode.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/test/test_unsteady_solved_ode.py @@ -7,8 +7,12 @@ from aviary.constants import GRAV_ENGLISH_LBM from aviary.mission.gasp_based.ode.params import set_params_for_unit_tests -from aviary.mission.gasp_based.ode.unsteady_solved.unsteady_solved_ode import \ - UnsteadySolvedODE +from aviary.mission.gasp_based.ode.unsteady_solved.unsteady_solved_ode import ( + UnsteadySolvedODE, +) +from aviary.variable_info.options import get_option_defaults +from aviary.variable_info.enums import SpeedType +from aviary.variable_info.variables import Aircraft, Dynamic, Mission from aviary.subsystems.propulsion.utils import build_engine_deck from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems from aviary.variable_info.enums import SpeedType @@ -17,29 +21,34 @@ class TestUnsteadySolvedODE(unittest.TestCase): - """ Test the unsteady solved ODE in steady level flight. """ + """Test the unsteady solved ODE in steady level flight.""" - def _test_unsteady_solved_ode(self, ground_roll=False, input_speed_type=SpeedType.MACH, clean=True): + def _test_unsteady_solved_ode( + self, ground_roll=False, input_speed_type=SpeedType.MACH, clean=True + ): nn = 5 p = om.Problem() aviary_options = get_option_defaults() default_mission_subsystems = get_default_mission_subsystems( - 'GASP', build_engine_deck(aviary_options)) + 'GASP', build_engine_deck(aviary_options) + ) - ode = UnsteadySolvedODE(num_nodes=nn, - input_speed_type=input_speed_type, - clean=clean, - ground_roll=ground_roll, - aviary_options=aviary_options, - core_subsystems=default_mission_subsystems) + ode = UnsteadySolvedODE( + num_nodes=nn, + input_speed_type=input_speed_type, + clean=clean, + ground_roll=ground_roll, + aviary_options=aviary_options, + core_subsystems=default_mission_subsystems, + ) p.model.add_subsystem("ode", ode, promotes=["*"]) - p.model.set_input_defaults(Dynamic.Mission.MACH, 0.8 * np.ones(nn)) + p.model.set_input_defaults(Dynamic.Atmosphere.MACH, 0.8 * np.ones(nn)) if ground_roll: - p.model.set_input_defaults(Dynamic.Mission.MACH, 0.1 * np.ones(nn)) + p.model.set_input_defaults(Dynamic.Atmosphere.MACH, 0.1 * np.ones(nn)) ode.set_input_defaults("alpha", np.zeros(nn), units="deg") p.setup(force_alloc_complex=True) @@ -48,9 +57,11 @@ def _test_unsteady_solved_ode(self, ground_roll=False, input_speed_type=SpeedTyp p.final_setup() - p.set_val(Dynamic.Mission.SPEED_OF_SOUND, 968.076 * np.ones(nn), units="ft/s") p.set_val( - Dynamic.Mission.DENSITY, 0.000659904 * np.ones(nn), units="slug/ft**3" + Dynamic.Atmosphere.SPEED_OF_SOUND, 968.076 * np.ones(nn), units="ft/s" + ) + p.set_val( + Dynamic.Atmosphere.DENSITY, 0.000659904 * np.ones(nn), units="slug/ft**3" ) p.set_val("mach", 0.8 * np.ones(nn), units="unitless") p.set_val("mass", 170_000 * np.ones(nn), units="lbm") @@ -65,14 +76,18 @@ def _test_unsteady_solved_ode(self, ground_roll=False, input_speed_type=SpeedTyp p.run_model() - drag = p.model.get_val(Dynamic.Mission.DRAG, units="lbf") - lift = p.model.get_val(Dynamic.Mission.LIFT, units="lbf") + drag = p.model.get_val(Dynamic.Vehicle.DRAG, units="lbf") + lift = p.model.get_val(Dynamic.Vehicle.LIFT, units="lbf") thrust_req = p.model.get_val("thrust_req", units="lbf") - gamma = 0 if ground_roll else p.model.get_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, units="deg") + gamma = ( + 0 + if ground_roll + else p.model.get_val(Dynamic.Mission.FLIGHT_PATH_ANGLE, units="deg") + ) weight = p.model.get_val("mass", units="lbm") * GRAV_ENGLISH_LBM fuelflow = p.model.get_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units="lbm/s") + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units="lbm/s" + ) dmass_dr = p.model.get_val("dmass_dr", units="lbm/ft") dt_dr = p.model.get_val("dt_dr", units="s/ft") tas = p.model.get_val(Dynamic.Mission.VELOCITY, units="ft/s") @@ -86,24 +101,27 @@ def _test_unsteady_solved_ode(self, ground_roll=False, input_speed_type=SpeedTyp s_gamma = np.sin(np.radians(gamma)) # 1. Test that forces balance along the velocity axis - assert_near_equal(drag + thrust_req * s_gamma, - thrust_req * c_alphai, tolerance=1.0E-12) + assert_near_equal( + drag + thrust_req * s_gamma, thrust_req * c_alphai, tolerance=1.0e-12 + ) # 2. Test that forces balance normal to the velocity axis - assert_near_equal(lift + thrust_req * s_alphai, - weight * c_gamma, tolerance=1.0E-12) + assert_near_equal( + lift + thrust_req * s_alphai, weight * c_gamma, tolerance=1.0e-12 + ) # 3. Test that dt_dr is the inverse of true airspeed - assert_near_equal(tas, 1/dt_dr, tolerance=1.0E-12) + assert_near_equal(tas, 1 / dt_dr, tolerance=1.0e-12) # 4. Test that the inverse of dt_dr is true airspeed - assert_near_equal(tas, 1/dt_dr, tolerance=1.0E-12) + assert_near_equal(tas, 1 / dt_dr, tolerance=1.0e-12) # 5. Test that fuelflow (lbf/s) * dt_dr (s/ft) is equal to dmass_dr - assert_near_equal(fuelflow * dt_dr, dmass_dr, tolerance=1.0E-12) + assert_near_equal(fuelflow * dt_dr, dmass_dr, tolerance=1.0e-12) - cpd = p.check_partials(out_stream=None, method="cs", - excludes=["*params*", "*aero*"]) + cpd = p.check_partials( + out_stream=None, method="cs", excludes=["*params*", "*aero*"] + ) # issue #495 # dTAS_dt_approx wrt flight_path_angle | abs | fwd-fd | 1.8689625335382314 # dTAS_dt_approx wrt flight_path_angle | rel | fwd-fd | 1.0 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 2df7762bd..d8221697b 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 @@ -61,10 +61,15 @@ def setup(self): eom_comp = UnsteadySolvedEOM(num_nodes=nn, ground_roll=ground_roll) - self.add_subsystem("eom", subsys=eom_comp, - promotes_inputs=["*", - (Dynamic.Mission.THRUST_TOTAL, "thrust_req")], - promotes_outputs=["*"]) + self.add_subsystem( + "eom", + subsys=eom_comp, + promotes_inputs=[ + "*", + (Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "thrust_req"), + ], + promotes_outputs=["*"], + ) thrust_alpha_bal = om.BalanceComp() if not self.options['ground_roll']: @@ -97,17 +102,17 @@ def setup(self): # Set common default values for promoted inputs onn = np.ones(nn) self.set_input_defaults( - name=Dynamic.Mission.DENSITY, + name=Dynamic.Atmosphere.DENSITY, val=RHO_SEA_LEVEL_ENGLISH * onn, units="slug/ft**3", ) self.set_input_defaults( - name=Dynamic.Mission.SPEED_OF_SOUND, - val=1116.4 * onn, - units="ft/s") + name=Dynamic.Atmosphere.SPEED_OF_SOUND, val=1116.4 * onn, units="ft/s" + ) if not self.options['ground_roll']: - self.set_input_defaults(name=Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=0.0 * onn, units="rad") + self.set_input_defaults( + name=Dynamic.Mission.FLIGHT_PATH_ANGLE, val=0.0 * onn, units="rad" + ) self.set_input_defaults( name=Dynamic.Mission.VELOCITY, val=250.0 * onn, units="kn" ) diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_eom.py b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_eom.py index 257e12db5..24a86ce07 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_eom.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_eom.py @@ -40,19 +40,27 @@ def setup(self): # is really a mass. This should be resolved with an adapter component that # uses gravity. self.add_input("mass", shape=nn, desc="aircraft mass", units="lbm") - self.add_input(Dynamic.Mission.THRUST_TOTAL, shape=nn, - desc=Dynamic.Mission.THRUST_TOTAL, units="N") - self.add_input(Dynamic.Mission.LIFT, shape=nn, - desc=Dynamic.Mission.LIFT, units="N") - self.add_input(Dynamic.Mission.DRAG, shape=nn, - desc=Dynamic.Mission.DRAG, units="N") + self.add_input( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + shape=nn, + desc=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="N", + ) + self.add_input(Dynamic.Vehicle.LIFT, shape=nn, + desc=Dynamic.Vehicle.LIFT, units="N") + self.add_input(Dynamic.Vehicle.DRAG, shape=nn, + desc=Dynamic.Vehicle.DRAG, units="N") add_aviary_input(self, Aircraft.Wing.INCIDENCE, val=0, units="rad") self.add_input("alpha", val=np.zeros( nn), desc="angle of attack", units="rad") if not self.options["ground_roll"]: - self.add_input(Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros( - nn), desc="flight path angle", units="rad") + self.add_input( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + val=np.zeros(nn), + desc="flight path angle", + units="rad", + ) self.add_input("dh_dr", val=np.zeros( nn), desc="d(alt)/d(range)", units="m/distance_units") self.add_input("d2h_dr2", val=np.zeros( @@ -87,19 +95,30 @@ def setup_partials(self): of="dt_dr", wrt=Dynamic.Mission.VELOCITY, rows=ar, cols=ar ) - self.declare_partials(of=["normal_force", "dTAS_dt"], - wrt=[Dynamic.Mission.THRUST_TOTAL, Dynamic.Mission.DRAG, - "mass", Dynamic.Mission.LIFT], - rows=ar, cols=ar) + self.declare_partials( + of=["normal_force", "dTAS_dt"], + wrt=[ + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + "mass", + Dynamic.Vehicle.LIFT, + ], + rows=ar, + cols=ar, + ) self.declare_partials(of="normal_force", wrt="mass", rows=ar, cols=ar, val=LBF_TO_N * GRAV_ENGLISH_LBM) - self.declare_partials(of="normal_force", wrt=Dynamic.Mission.LIFT, + self.declare_partials(of="normal_force", wrt=Dynamic.Vehicle.LIFT, rows=ar, cols=ar, val=-1.0) - self.declare_partials(of="load_factor", wrt=[Dynamic.Mission.LIFT, "mass", Dynamic.Mission.THRUST_TOTAL], - rows=ar, cols=ar) + self.declare_partials( + of="load_factor", + wrt=[Dynamic.Vehicle.LIFT, "mass", Dynamic.Vehicle.Propulsion.THRUST_TOTAL], + rows=ar, + cols=ar, + ) self.declare_partials(of=["dTAS_dt", "normal_force", "load_factor"], wrt=[Aircraft.Wing.INCIDENCE]) @@ -120,33 +139,62 @@ def setup_partials(self): rows=ar, cols=ar) if not ground_roll: - self.declare_partials(of="dt_dr", wrt=Dynamic.Mission.FLIGHT_PATH_ANGLE, - rows=ar, cols=ar) + self.declare_partials( + of="dt_dr", wrt=Dynamic.Mission.FLIGHT_PATH_ANGLE, rows=ar, cols=ar + ) - self.declare_partials(of=["dgam_dt", "dgam_dt_approx"], - wrt=[Dynamic.Mission.LIFT, "mass", Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG, "alpha", Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar) + self.declare_partials( + of=["dgam_dt", "dgam_dt_approx"], + wrt=[ + Dynamic.Vehicle.LIFT, + "mass", + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + "alpha", + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ], + rows=ar, + cols=ar, + ) - self.declare_partials(of=["normal_force", "dTAS_dt"], - wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar) + self.declare_partials( + of=["normal_force", "dTAS_dt"], + wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=ar, + cols=ar, + ) self.declare_partials( of=["dgam_dt"], wrt=[Dynamic.Mission.VELOCITY], rows=ar, cols=ar ) - self.declare_partials(of="load_factor", wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar) + self.declare_partials( + of="load_factor", + wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=ar, + cols=ar, + ) - self.declare_partials(of=["dgam_dt", "dgam_dt_approx"], - wrt=[Dynamic.Mission.LIFT, "mass", - Dynamic.Mission.THRUST_TOTAL, "alpha", Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar) + self.declare_partials( + of=["dgam_dt", "dgam_dt_approx"], + wrt=[ + Dynamic.Vehicle.LIFT, + "mass", + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + "alpha", + Dynamic.Mission.FLIGHT_PATH_ANGLE, + ], + rows=ar, + cols=ar, + ) - self.declare_partials(of="fuselage_pitch", - wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar, val=1.0) + self.declare_partials( + of="fuselage_pitch", + wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=ar, + cols=ar, + val=1.0, + ) self.declare_partials( of=["dgam_dt_approx"], @@ -160,11 +208,11 @@ def setup_partials(self): def compute(self, inputs, outputs): tas = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] # convert to newtons # TODO: change this to use the units conversion weight = inputs["mass"] * GRAV_ENGLISH_LBM * LBF_TO_N - drag = inputs[Dynamic.Mission.DRAG] - lift = inputs[Dynamic.Mission.LIFT] + drag = inputs[Dynamic.Vehicle.DRAG] + lift = inputs[Dynamic.Vehicle.LIFT] alpha = inputs["alpha"] i_wing = inputs[Aircraft.Wing.INCIDENCE] @@ -217,11 +265,11 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, partials): ground_roll = self.options["ground_roll"] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] # convert to newtons # TODO: change this to use the units conversion weight = inputs["mass"] * GRAV_ENGLISH_LBM * LBF_TO_N - drag = inputs[Dynamic.Mission.DRAG] - lift = inputs[Dynamic.Mission.LIFT] + drag = inputs[Dynamic.Vehicle.DRAG] + lift = inputs[Dynamic.Vehicle.LIFT] tas = inputs[Dynamic.Mission.VELOCITY] i_wing = inputs[Aircraft.Wing.INCIDENCE] alpha = inputs["alpha"] @@ -261,22 +309,24 @@ def compute_partials(self, inputs, partials): partials["dt_dr", Dynamic.Mission.VELOCITY] = -cgam / dr_dt**2 - partials["dTAS_dt", Dynamic.Mission.THRUST_TOTAL] = calpha_i / \ - m + salpha_i / m * mu - partials["dTAS_dt", Dynamic.Mission.DRAG] = -1. / m + partials["dTAS_dt", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + calpha_i / m + salpha_i / m * mu + ) + partials["dTAS_dt", Dynamic.Vehicle.DRAG] = -1. / m partials["dTAS_dt", "mass"] = \ GRAV_ENGLISH_LBM * (LBF_TO_N * (-sgam - mu) / m - _f / (weight/LBF_TO_N * m)) - partials["dTAS_dt", Dynamic.Mission.LIFT] = mu / m + partials["dTAS_dt", Dynamic.Vehicle.LIFT] = mu / m partials["dTAS_dt", "alpha"] = -tsai / m + mu * tcai / m partials["dTAS_dt", Aircraft.Wing.INCIDENCE] = tsai / m - mu * tcai / m - partials["normal_force", Dynamic.Mission.THRUST_TOTAL] = -salpha_i + partials["normal_force", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = -salpha_i - partials["load_factor", Dynamic.Mission.LIFT] = 1 / (weight * cgam) - partials["load_factor", Dynamic.Mission.THRUST_TOTAL] = salpha_i / \ - (weight * cgam) + partials["load_factor", Dynamic.Vehicle.LIFT] = 1 / (weight * cgam) + partials["load_factor", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = salpha_i / ( + weight * cgam + ) partials["load_factor", "mass"] = \ - (lift + tsai) / (weight**2/LBF_TO_N * cgam) * GRAV_ENGLISH_LBM @@ -287,17 +337,22 @@ def compute_partials(self, inputs, partials): partials["load_factor", "alpha"] = tcai / (weight * cgam) if not ground_roll: - partials["dt_dr", Dynamic.Mission.FLIGHT_PATH_ANGLE] = -drdot_dgam / dr_dt**2 + partials["dt_dr", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -drdot_dgam / dr_dt**2 + ) partials["dTAS_dt", Dynamic.Mission.FLIGHT_PATH_ANGLE] = -weight * cgam / m - partials["dgam_dt", Dynamic.Mission.THRUST_TOTAL] = salpha_i / mtas - partials["dgam_dt", Dynamic.Mission.LIFT] = 1. / mtas + partials["dgam_dt", Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = ( + salpha_i / mtas + ) + partials["dgam_dt", Dynamic.Vehicle.LIFT] = 1. / mtas partials["dgam_dt", "mass"] = \ GRAV_ENGLISH_LBM * (LBF_TO_N*cgam / (mtas) - (tsai + lift + weight*cgam)/(weight**2 / LBF_TO_N/g * tas)) - partials["dgam_dt", Dynamic.Mission.FLIGHT_PATH_ANGLE] = m * \ - tas * weight * sgam / mtas2 + partials["dgam_dt", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + m * tas * weight * sgam / mtas2 + ) partials["dgam_dt", "alpha"] = m * tas * tcai / mtas2 partials["dgam_dt", Dynamic.Mission.VELOCITY] = ( -m * (tsai + lift - weight * cgam) / mtas2 @@ -311,7 +366,9 @@ def compute_partials(self, inputs, partials): partials["dgam_dt_approx", "dh_dr"] = dr_dt * ddgam_dr_ddh_dr partials["dgam_dt_approx", "d2h_dr2"] = dr_dt * ddgam_dr_dd2h_dr2 partials["dgam_dt_approx", Dynamic.Mission.VELOCITY] = dgam_dr * drdot_dtas - partials["dgam_dt_approx", - Dynamic.Mission.FLIGHT_PATH_ANGLE] = dgam_dr * drdot_dgam + partials["dgam_dt_approx", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + dgam_dr * drdot_dgam + ) partials["load_factor", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( - lift + tsai) / (weight * cgam**2) * sgam + (lift + tsai) / (weight * cgam**2) * sgam + ) diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_flight_conditions.py b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_flight_conditions.py index 08c1868ba..af2b8bdea 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_flight_conditions.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_flight_conditions.py @@ -11,7 +11,7 @@ class UnsteadySolvedFlightConditions(om.ExplicitComponent): Cross-compute TAS, EAS, and Mach regardless of the input speed type. Inputs: - Dynamic.Mission.DENSITY : local atmospheric density + Dynamic.Atmosphere.DENSITY : local atmospheric density Dynamic.Mission.SPEED_OF_SOUND : local speed of sound Additional inputs if ground_roll = False: @@ -26,20 +26,20 @@ class UnsteadySolvedFlightConditions(om.ExplicitComponent): dEAS_dr : approximate rate of change of equivalent airspeed per unit range Additional inputs when input_speed_type = SpeedType.MACH: - Dynamic.Mission.MACH : Mach number + Dynamic.Atmosphere.MACH : Mach number dmach_dr : approximate rate of change of Mach number per unit range Outputs always provided: - Dynamic.Mission.DYNAMIC_PRESSURE : dynamic pressure + Dynamic.Atmosphere.DYNAMIC_PRESSURE : dynamic pressure dTAS_dt_approx : approximate time derivative of TAS based on control rates. Additional outputs when input_speed_type = SpeedType.TAS EAS : equivalent airspeed - Dynamic.Mission.MACH : Mach number + Dynamic.Atmosphere.MACH : Mach number Outputs provided when input_speed_type = SpeedType.EAS: TAS : true airspeed - Dynamic.Mission.MACH : Mach number + Dynamic.Atmosphere.MACH : Mach number """ def initialize(self): @@ -62,20 +62,20 @@ def setup(self): ar = np.arange(self.options["num_nodes"]) self.add_input( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=np.zeros(nn), units="kg/m**3", desc="density of air", ) self.add_input( - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.SPEED_OF_SOUND, val=np.zeros(nn), units="m/s", desc="speed of sound", ) self.add_output( - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, val=np.zeros(nn), units="N/m**2", desc="dynamic pressure", @@ -118,27 +118,27 @@ def setup(self): desc="equivalent air speed", ) self.add_output( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless", desc="mach number", ) self.declare_partials( - of=Dynamic.Mission.DYNAMIC_PRESSURE, - wrt=[Dynamic.Mission.DENSITY, Dynamic.Mission.VELOCITY], + of=Dynamic.Atmosphere.DYNAMIC_PRESSURE, + wrt=[Dynamic.Atmosphere.DENSITY, Dynamic.Mission.VELOCITY], rows=ar, cols=ar, ) self.declare_partials( - of=Dynamic.Mission.MACH, - wrt=[Dynamic.Mission.SPEED_OF_SOUND, Dynamic.Mission.VELOCITY], + of=Dynamic.Atmosphere.MACH, + wrt=[Dynamic.Atmosphere.SPEED_OF_SOUND, Dynamic.Mission.VELOCITY], rows=ar, cols=ar, ) self.declare_partials( of="EAS", - wrt=[Dynamic.Mission.VELOCITY, Dynamic.Mission.DENSITY], + wrt=[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.DENSITY], rows=ar, cols=ar, ) @@ -150,9 +150,12 @@ def setup(self): ) if not ground_roll: - self.declare_partials(of="dTAS_dt_approx", - wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar) + self.declare_partials( + of="dTAS_dt_approx", + wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=ar, + cols=ar, + ) elif in_type is SpeedType.EAS: self.add_input( @@ -181,45 +184,52 @@ def setup(self): desc="true air speed", ) self.add_output( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless", desc="mach number", ) self.declare_partials( - of=Dynamic.Mission.DYNAMIC_PRESSURE, - wrt=[Dynamic.Mission.DENSITY, "EAS"], + of=Dynamic.Atmosphere.DYNAMIC_PRESSURE, + wrt=[Dynamic.Atmosphere.DENSITY, "EAS"], rows=ar, cols=ar, ) self.declare_partials( - of=Dynamic.Mission.MACH, - wrt=[Dynamic.Mission.SPEED_OF_SOUND, "EAS", Dynamic.Mission.DENSITY], + of=Dynamic.Atmosphere.MACH, + wrt=[ + Dynamic.Atmosphere.SPEED_OF_SOUND, + "EAS", + Dynamic.Atmosphere.DENSITY, + ], rows=ar, cols=ar, ) self.declare_partials( of=Dynamic.Mission.VELOCITY, - wrt=[Dynamic.Mission.DENSITY, "EAS"], + wrt=[Dynamic.Atmosphere.DENSITY, "EAS"], rows=ar, cols=ar, ) self.declare_partials( of="dTAS_dt_approx", - wrt=["drho_dh", Dynamic.Mission.DENSITY, "EAS", "dEAS_dr"], + wrt=["drho_dh", Dynamic.Atmosphere.DENSITY, "EAS", "dEAS_dr"], rows=ar, cols=ar, ) if not ground_roll: - self.declare_partials(of="dTAS_dt_approx", - wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], - rows=ar, cols=ar) + self.declare_partials( + of="dTAS_dt_approx", + wrt=[Dynamic.Mission.FLIGHT_PATH_ANGLE], + rows=ar, + cols=ar, + ) else: self.add_input( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless", desc="mach number", @@ -251,11 +261,11 @@ def setup(self): ) self.declare_partials( - of=Dynamic.Mission.DYNAMIC_PRESSURE, + of=Dynamic.Atmosphere.DYNAMIC_PRESSURE, wrt=[ - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.MACH, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DENSITY, ], rows=ar, cols=ar, @@ -263,7 +273,7 @@ def setup(self): self.declare_partials( of=Dynamic.Mission.VELOCITY, - wrt=[Dynamic.Mission.SPEED_OF_SOUND, Dynamic.Mission.MACH], + wrt=[Dynamic.Atmosphere.SPEED_OF_SOUND, Dynamic.Atmosphere.MACH], rows=ar, cols=ar, ) @@ -271,9 +281,9 @@ def setup(self): self.declare_partials( of="EAS", wrt=[ - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.MACH, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DENSITY, ], rows=ar, cols=ar, @@ -287,10 +297,10 @@ def compute(self, inputs, outputs): in_type = self.options["input_speed_type"] ground_roll = self.options["ground_roll"] - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] rho_sl = constants.RHO_SEA_LEVEL_METRIC sqrt_rho_rho_sl = np.sqrt(rho / rho_sl) - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] cgam = 1.0 if ground_roll else np.cos(inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE]) sgam = 0.0 if ground_roll else np.sin(inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE]) @@ -298,7 +308,7 @@ def compute(self, inputs, outputs): if in_type is SpeedType.TAS: tas = inputs[Dynamic.Mission.VELOCITY] dtas_dr = inputs["dTAS_dr"] - outputs[Dynamic.Mission.MACH] = tas / sos + outputs[Dynamic.Atmosphere.MACH] = tas / sos outputs["EAS"] = tas * sqrt_rho_rho_sl outputs["dTAS_dt_approx"] = dtas_dr * tas * cgam @@ -307,14 +317,14 @@ def compute(self, inputs, outputs): drho_dh = inputs["drho_dh"] deas_dr = inputs["dEAS_dr"] outputs[Dynamic.Mission.VELOCITY] = tas = eas / sqrt_rho_rho_sl - outputs[Dynamic.Mission.MACH] = tas / sos + outputs[Dynamic.Atmosphere.MACH] = tas / sos drho_dt_approx = drho_dh * tas * sgam deas_dt_approx = deas_dr * tas * cgam outputs["dTAS_dt_approx"] = deas_dt_approx * (rho_sl / rho)**1.5 \ - 0.5 * eas * drho_dt_approx * rho_sl**1.5 / rho_sl**2.5 else: - mach = inputs[Dynamic.Mission.MACH] + mach = inputs[Dynamic.Atmosphere.MACH] dmach_dr = inputs["dmach_dr"] outputs[Dynamic.Mission.VELOCITY] = tas = sos * mach outputs["EAS"] = tas * sqrt_rho_rho_sl @@ -323,17 +333,17 @@ def compute(self, inputs, outputs): outputs["dTAS_dt_approx"] = dmach_dt_approx * sos \ + dsos_dt_approx * tas / sos - outputs[Dynamic.Mission.DYNAMIC_PRESSURE] = 0.5 * rho * tas**2 + outputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] = 0.5 * rho * tas**2 def compute_partials(self, inputs, partials): in_type = self.options["input_speed_type"] ground_roll = self.options["ground_roll"] - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] rho_sl = constants.RHO_SEA_LEVEL_METRIC sqrt_rho_rho_sl = np.sqrt(rho / rho_sl) dsqrt_rho_rho_sl_drho = 0.5 / sqrt_rho_rho_sl / rho_sl - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] cgam = 1.0 if ground_roll else np.cos(inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE]) sgam = 0.0 if ground_roll else np.sin(inputs[Dynamic.Mission.FLIGHT_PATH_ANGLE]) @@ -344,26 +354,28 @@ def compute_partials(self, inputs, partials): tas = inputs[Dynamic.Mission.VELOCITY] dTAS_dr = inputs["dTAS_dr"] - partials[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.VELOCITY] = ( + partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Mission.VELOCITY] = ( rho * TAS ) - partials[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.DENSITY] = ( - 0.5 * TAS**2 - ) + partials[ + Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.DENSITY + ] = (0.5 * TAS**2) - partials[Dynamic.Mission.MACH, Dynamic.Mission.VELOCITY] = 1 / sos - partials[Dynamic.Mission.MACH, - Dynamic.Mission.SPEED_OF_SOUND] = -TAS / sos ** 2 + partials[Dynamic.Atmosphere.MACH, Dynamic.Mission.VELOCITY] = 1 / sos + partials[Dynamic.Atmosphere.MACH, Dynamic.Atmosphere.SPEED_OF_SOUND] = ( + -TAS / sos**2 + ) partials["EAS", Dynamic.Mission.VELOCITY] = sqrt_rho_rho_sl - partials["EAS", Dynamic.Mission.DENSITY] = tas * dsqrt_rho_rho_sl_drho + partials["EAS", Dynamic.Atmosphere.DENSITY] = tas * dsqrt_rho_rho_sl_drho partials["dTAS_dt_approx", "dTAS_dr"] = tas * cgam partials["dTAS_dt_approx", Dynamic.Mission.VELOCITY] = dTAS_dr * cgam if not ground_roll: - partials["dTAS_dt_approx", - Dynamic.Mission.FLIGHT_PATH_ANGLE] = -dTAS_dr * tas * sgam + partials["dTAS_dt_approx", Dynamic.Mission.FLIGHT_PATH_ANGLE] = ( + -dTAS_dr * tas * sgam + ) elif in_type is SpeedType.EAS: EAS = inputs["EAS"] @@ -372,33 +384,38 @@ def compute_partials(self, inputs, partials): dTAS_dRho = -0.5 * EAS * rho_sl**0.5 / rho**1.5 dTAS_dEAS = 1 / sqrt_rho_rho_sl - partials[Dynamic.Mission.DYNAMIC_PRESSURE, "EAS"] = EAS * rho_sl - partials[Dynamic.Mission.MACH, "EAS"] = dTAS_dEAS / sos - partials[Dynamic.Mission.MACH, Dynamic.Mission.DENSITY] = dTAS_dRho / sos - partials[Dynamic.Mission.MACH, - Dynamic.Mission.SPEED_OF_SOUND] = -TAS / sos ** 2 - partials[Dynamic.Mission.VELOCITY, Dynamic.Mission.DENSITY] = dTAS_dRho + partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, "EAS"] = EAS * rho_sl + partials[Dynamic.Atmosphere.MACH, "EAS"] = dTAS_dEAS / sos + partials[Dynamic.Atmosphere.MACH, Dynamic.Atmosphere.DENSITY] = ( + dTAS_dRho / sos + ) + partials[Dynamic.Atmosphere.MACH, Dynamic.Atmosphere.SPEED_OF_SOUND] = ( + -TAS / sos**2 + ) + partials[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.DENSITY] = dTAS_dRho partials[Dynamic.Mission.VELOCITY, "EAS"] = dTAS_dEAS partials["dTAS_dt_approx", "dEAS_dr"] = TAS * cgam * (rho_sl / rho)**1.5 partials['dTAS_dt_approx', 'drho_dh'] = -0.5 * \ EAS * TAS * sgam * rho_sl**1.5 / rho_sl**2.5 else: - mach = inputs[Dynamic.Mission.MACH] + mach = inputs[Dynamic.Atmosphere.MACH] TAS = sos * mach - partials[Dynamic.Mission.DYNAMIC_PRESSURE, - Dynamic.Mission.SPEED_OF_SOUND] = rho * sos * mach ** 2 - partials[Dynamic.Mission.DYNAMIC_PRESSURE, - Dynamic.Mission.MACH] = rho * sos ** 2 * mach - partials[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.DENSITY] = ( - 0.5 * sos**2 * mach**2 - ) - partials[Dynamic.Mission.VELOCITY, Dynamic.Mission.SPEED_OF_SOUND] = mach - partials[Dynamic.Mission.VELOCITY, Dynamic.Mission.MACH] = sos - partials["EAS", Dynamic.Mission.SPEED_OF_SOUND] = mach * sqrt_rho_rho_sl - partials["EAS", Dynamic.Mission.MACH] = sos * sqrt_rho_rho_sl - partials["EAS", Dynamic.Mission.DENSITY] = ( + partials[ + Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.SPEED_OF_SOUND + ] = (rho * sos * mach**2) + partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.MACH] = ( + rho * sos**2 * mach + ) + partials[ + Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.DENSITY + ] = (0.5 * sos**2 * mach**2) + partials[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.SPEED_OF_SOUND] = mach + partials[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.MACH] = sos + partials["EAS", Dynamic.Atmosphere.SPEED_OF_SOUND] = mach * sqrt_rho_rho_sl + partials["EAS", Dynamic.Atmosphere.MACH] = sos * sqrt_rho_rho_sl + partials["EAS", Dynamic.Atmosphere.DENSITY] = ( TAS * (1 / rho_sl) ** 0.5 * 0.5 * rho ** (-0.5) ) partials['dTAS_dt_approx', 'dmach_dr'] = TAS * cgam * sos diff --git a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_ode.py b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_ode.py index fcc5c10ce..cffa4259b 100644 --- a/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_ode.py +++ b/aviary/mission/gasp_based/ode/unsteady_solved/unsteady_solved_ode.py @@ -95,10 +95,10 @@ def setup(self): subsys=Atmosphere(num_nodes=nn, output_dsos_dh=True), promotes_inputs=[Dynamic.Mission.ALTITUDE], promotes_outputs=[ - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, "viscosity", "drhos_dh", "dsos_dh", @@ -132,10 +132,10 @@ def setup(self): throttle_balance_comp = om.BalanceComp() throttle_balance_comp.add_balance( - Dynamic.Mission.THROTTLE, + Dynamic.Vehicle.Propulsion.THROTTLE, units="unitless", val=np.ones(nn) * 0.5, - lhs_name=Dynamic.Mission.THRUST_TOTAL, + lhs_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, rhs_name="thrust_req", eq_units="lbf", normalize=False, @@ -195,7 +195,7 @@ def setup(self): input_list = [ '*', - (Dynamic.Mission.THRUST_TOTAL, "thrust_req"), + (Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "thrust_req"), Dynamic.Mission.VELOCITY, ] control_iter_group.add_subsystem("eom", subsys=eom_comp, @@ -232,38 +232,46 @@ def setup(self): # control_iter_group.nonlinear_solver.linesearch = om.BoundsEnforceLS() control_iter_group.linear_solver = om.DirectSolver(assemble_jac=True) - self.add_subsystem("mass_rate", - om.ExecComp("dmass_dr = fuelflow * dt_dr", - fuelflow={"units": "lbm/s", "shape": nn}, - dt_dr={"units": "s/distance_units", "shape": nn}, - dmass_dr={"units": "lbm/distance_units", - "shape": nn, - "tags": ['dymos.state_rate_source:mass', - 'dymos.state_units:lbm']}, - has_diag_partials=True), - promotes_inputs=[ - ("fuelflow", Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL), "dt_dr"], - promotes_outputs=["dmass_dr"]) + self.add_subsystem( + "mass_rate", + om.ExecComp( + "dmass_dr = fuelflow * dt_dr", + fuelflow={"units": "lbm/s", "shape": nn}, + dt_dr={"units": "s/distance_units", "shape": nn}, + dmass_dr={ + "units": "lbm/distance_units", + "shape": nn, + "tags": ['dymos.state_rate_source:mass', 'dymos.state_units:lbm'], + }, + has_diag_partials=True, + ), + promotes_inputs=[ + ("fuelflow", Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL), + "dt_dr", + ], + promotes_outputs=["dmass_dr"], + ) if self.options["include_param_comp"]: ParamPort.set_default_vals(self) onn = np.ones(nn) - self.set_input_defaults(name=Dynamic.Mission.DENSITY, - val=rho_sl * onn, units="slug/ft**3") self.set_input_defaults( - name=Dynamic.Mission.SPEED_OF_SOUND, - val=1116.4 * onn, - units="ft/s") + name=Dynamic.Atmosphere.DENSITY, val=rho_sl * onn, units="slug/ft**3" + ) + self.set_input_defaults( + name=Dynamic.Atmosphere.SPEED_OF_SOUND, val=1116.4 * onn, units="ft/s" + ) if not self.options['ground_roll']: self.set_input_defaults( - name=Dynamic.Mission.FLIGHT_PATH_ANGLE, val=0.0 * onn, units="rad") - self.set_input_defaults(name=Dynamic.Mission.VELOCITY, - val=250. * onn, units="kn") + name=Dynamic.Mission.FLIGHT_PATH_ANGLE, val=0.0 * onn, units="rad" + ) self.set_input_defaults( - name=Dynamic.Mission.ALTITUDE, - val=10000. * onn, - units="ft") + name=Dynamic.Mission.VELOCITY, val=250.0 * onn, units="kn" + ) + self.set_input_defaults( + name=Dynamic.Mission.ALTITUDE, val=10000.0 * onn, units="ft" + ) self.set_input_defaults(name="dh_dr", val=0. * onn, units="ft/distance_units") self.set_input_defaults(name="d2h_dr2", val=0. * onn, units="ft/distance_units**2") diff --git a/aviary/mission/gasp_based/phases/accel_phase.py b/aviary/mission/gasp_based/phases/accel_phase.py index a1dcfa5d5..0bfdbe487 100644 --- a/aviary/mission/gasp_based/phases/accel_phase.py +++ b/aviary/mission/gasp_based/phases/accel_phase.py @@ -64,11 +64,17 @@ def build_phase(self, aviary_options: AviaryValues = None): # Timeseries Outputs phase.add_timeseries_output("EAS", output_name="EAS", units="kn") phase.add_timeseries_output( - Dynamic.Mission.MACH, output_name=Dynamic.Mission.MACH, units="unitless") + Dynamic.Atmosphere.MACH, + output_name=Dynamic.Atmosphere.MACH, + units="unitless", + ) phase.add_timeseries_output("alpha", output_name="alpha", units="deg") phase.add_timeseries_output("aero.CL", output_name="CL", units="unitless") phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, output_name=Dynamic.Mission.THRUST_TOTAL, units="lbf") + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) phase.add_timeseries_output("aero.CD", output_name="CD", units="unitless") return phase diff --git a/aviary/mission/gasp_based/phases/ascent_phase.py b/aviary/mission/gasp_based/phases/ascent_phase.py index 663655411..6352dfccf 100644 --- a/aviary/mission/gasp_based/phases/ascent_phase.py +++ b/aviary/mission/gasp_based/phases/ascent_phase.py @@ -86,11 +86,13 @@ def build_phase(self, aviary_options: AviaryValues = None): phase.add_parameter("t_init_flaps", units="s", static_target=True, opt=False, val=48.21) - phase.add_timeseries_output(Dynamic.Mission.THRUST_TOTAL, units="lbf") + phase.add_timeseries_output( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units="lbf" + ) phase.add_timeseries_output("normal_force") - phase.add_timeseries_output(Dynamic.Mission.MACH) + phase.add_timeseries_output(Dynamic.Atmosphere.MACH) phase.add_timeseries_output("EAS", units="kn") - phase.add_timeseries_output(Dynamic.Mission.LIFT) + phase.add_timeseries_output(Dynamic.Vehicle.LIFT) phase.add_timeseries_output("CL") phase.add_timeseries_output("CD") diff --git a/aviary/mission/gasp_based/phases/climb_phase.py b/aviary/mission/gasp_based/phases/climb_phase.py index 0bb6bbed8..279c644a7 100644 --- a/aviary/mission/gasp_based/phases/climb_phase.py +++ b/aviary/mission/gasp_based/phases/climb_phase.py @@ -81,27 +81,41 @@ def build_phase(self, aviary_options: AviaryValues = None): if target_mach: phase.add_boundary_constraint( - Dynamic.Mission.MACH, loc="final", equals=mach_cruise, + Dynamic.Atmosphere.MACH, + loc="final", + equals=mach_cruise, ) # Timeseries Outputs phase.add_timeseries_output( - Dynamic.Mission.MACH, output_name=Dynamic.Mission.MACH, units="unitless") + Dynamic.Atmosphere.MACH, + output_name=Dynamic.Atmosphere.MACH, + units="unitless", + ) phase.add_timeseries_output("EAS", output_name="EAS", units="kn") phase.add_timeseries_output( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units="lbm/s") + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units="lbm/s" + ) phase.add_timeseries_output("theta", output_name="theta", units="deg") phase.add_timeseries_output("alpha", output_name="alpha", units="deg") - phase.add_timeseries_output(Dynamic.Mission.FLIGHT_PATH_ANGLE, - output_name=Dynamic.Mission.FLIGHT_PATH_ANGLE, units="deg") + phase.add_timeseries_output( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + output_name=Dynamic.Mission.FLIGHT_PATH_ANGLE, + units="deg", + ) phase.add_timeseries_output( "TAS_violation", output_name="TAS_violation", units="kn") phase.add_timeseries_output( - Dynamic.Mission.VELOCITY, output_name=Dynamic.Mission.VELOCITY, units="kn" + Dynamic.Mission.VELOCITY, + output_name=Dynamic.Mission.VELOCITY, + units="kn", ) phase.add_timeseries_output("aero.CL", output_name="CL", units="unitless") phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, output_name=Dynamic.Mission.THRUST_TOTAL, units="lbf") + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) phase.add_timeseries_output("aero.CD", output_name="CD", units="unitless") return phase diff --git a/aviary/mission/gasp_based/phases/cruise_phase.py b/aviary/mission/gasp_based/phases/cruise_phase.py index 44b7704f5..6ccfc8edf 100644 --- a/aviary/mission/gasp_based/phases/cruise_phase.py +++ b/aviary/mission/gasp_based/phases/cruise_phase.py @@ -61,17 +61,17 @@ def build_phase(self, aviary_options: AviaryValues = None): mach_cruise = user_options.get_val('mach_cruise') alt_cruise, alt_units = user_options.get_item('alt_cruise') - phase.add_parameter(Dynamic.Mission.ALTITUDE, opt=False, - val=alt_cruise, units=alt_units) - phase.add_parameter(Dynamic.Mission.MACH, opt=False, - val=mach_cruise) + phase.add_parameter( + Dynamic.Mission.ALTITUDE, opt=False, val=alt_cruise, units=alt_units + ) + phase.add_parameter(Dynamic.Atmosphere.MACH, opt=False, val=mach_cruise) phase.add_parameter("initial_distance", opt=False, val=0.0, units="NM", static_target=True) phase.add_parameter("initial_time", opt=False, val=0.0, units="s", static_target=True) phase.add_timeseries_output("time", units="s", output_name="time") - phase.add_timeseries_output(Dynamic.Mission.MASS, units="lbm") + phase.add_timeseries_output(Dynamic.Vehicle.MASS, units="lbm") phase.add_timeseries_output(Dynamic.Mission.DISTANCE, units="nmi") return phase diff --git a/aviary/mission/gasp_based/phases/descent_phase.py b/aviary/mission/gasp_based/phases/descent_phase.py index 713e2234f..409187456 100644 --- a/aviary/mission/gasp_based/phases/descent_phase.py +++ b/aviary/mission/gasp_based/phases/descent_phase.py @@ -53,18 +53,29 @@ def build_phase(self, aviary_options: AviaryValues = None): # Add timeseries outputs phase.add_timeseries_output( - Dynamic.Mission.MACH, output_name=Dynamic.Mission.MACH, units="unitless") + Dynamic.Atmosphere.MACH, + output_name=Dynamic.Atmosphere.MACH, + units="unitless", + ) phase.add_timeseries_output("EAS", output_name="EAS", units="kn") phase.add_timeseries_output( - Dynamic.Mission.VELOCITY, output_name=Dynamic.Mission.VELOCITY, units="kn" + Dynamic.Mission.VELOCITY, + output_name=Dynamic.Mission.VELOCITY, + units="kn", + ) + phase.add_timeseries_output( + Dynamic.Mission.FLIGHT_PATH_ANGLE, + output_name=Dynamic.Mission.FLIGHT_PATH_ANGLE, + units="deg", ) - phase.add_timeseries_output(Dynamic.Mission.FLIGHT_PATH_ANGLE, - output_name=Dynamic.Mission.FLIGHT_PATH_ANGLE, units="deg") phase.add_timeseries_output("alpha", output_name="alpha", units="deg") phase.add_timeseries_output("theta", output_name="theta", units="deg") phase.add_timeseries_output("aero.CL", output_name="CL", units="unitless") phase.add_timeseries_output( - Dynamic.Mission.THRUST_TOTAL, output_name=Dynamic.Mission.THRUST_TOTAL, units="lbf") + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + output_name=Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + units="lbf", + ) phase.add_timeseries_output("aero.CD", output_name="CD", units="unitless") return phase diff --git a/aviary/mission/gasp_based/phases/groundroll_phase.py b/aviary/mission/gasp_based/phases/groundroll_phase.py index d954b2c1b..a7d55e510 100644 --- a/aviary/mission/gasp_based/phases/groundroll_phase.py +++ b/aviary/mission/gasp_based/phases/groundroll_phase.py @@ -52,14 +52,14 @@ def build_phase(self, aviary_options: AviaryValues = None): self.add_velocity_state(user_options) phase.add_state( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, fix_initial=fix_initial_mass, input_initial=connect_initial_mass, fix_final=False, lower=mass_lower, upper=mass_upper, units="lbm", - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, ref=mass_ref, defect_ref=mass_defect_ref, ref0=mass_ref0, @@ -88,13 +88,15 @@ def build_phase(self, aviary_options: AviaryValues = None): # phase phase.add_timeseries_output("time", units="s", output_name="time") - phase.add_timeseries_output(Dynamic.Mission.THRUST_TOTAL, units="lbf") + phase.add_timeseries_output( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units="lbf" + ) phase.add_timeseries_output("normal_force") - phase.add_timeseries_output(Dynamic.Mission.MACH) + phase.add_timeseries_output(Dynamic.Atmosphere.MACH) phase.add_timeseries_output("EAS", units="kn") - phase.add_timeseries_output(Dynamic.Mission.LIFT) + phase.add_timeseries_output(Dynamic.Vehicle.LIFT) phase.add_timeseries_output("CL") phase.add_timeseries_output("CD") phase.add_timeseries_output("fuselage_pitch", output_name="theta", units="deg") diff --git a/aviary/mission/gasp_based/phases/rotation_phase.py b/aviary/mission/gasp_based/phases/rotation_phase.py index ebb04888b..8643ea5ec 100644 --- a/aviary/mission/gasp_based/phases/rotation_phase.py +++ b/aviary/mission/gasp_based/phases/rotation_phase.py @@ -97,11 +97,13 @@ def build_phase(self, aviary_options: AviaryValues = None): ) # Add timeseries outputs - phase.add_timeseries_output(Dynamic.Mission.THRUST_TOTAL, units="lbf") + phase.add_timeseries_output( + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units="lbf" + ) phase.add_timeseries_output("normal_force") - phase.add_timeseries_output(Dynamic.Mission.MACH) + phase.add_timeseries_output(Dynamic.Atmosphere.MACH) phase.add_timeseries_output("EAS", units="kn") - phase.add_timeseries_output(Dynamic.Mission.LIFT) + phase.add_timeseries_output(Dynamic.Vehicle.LIFT) phase.add_timeseries_output("CL") phase.add_timeseries_output("CD") phase.add_timeseries_output("fuselage_pitch", output_name="theta", units="deg") diff --git a/aviary/mission/gasp_based/phases/test/test_v_rotate_comp.py b/aviary/mission/gasp_based/phases/test/test_v_rotate_comp.py index f166d8a7a..3378792b4 100644 --- a/aviary/mission/gasp_based/phases/test/test_v_rotate_comp.py +++ b/aviary/mission/gasp_based/phases/test/test_v_rotate_comp.py @@ -25,7 +25,7 @@ def test_partials(self): prob.set_val("dVR", val=5, units="kn") prob.set_val(Aircraft.Wing.AREA, val=1370, units="ft**2") prob.set_val( - Dynamic.Mission.DENSITY, val=RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" + Dynamic.Atmosphere.DENSITY, val=RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" ) prob.set_val("CL_max", val=2.1886, units="unitless") prob.set_val("mass", val=175_000, units="lbm") @@ -59,7 +59,7 @@ def test_partials(self): prob.set_val("dVR", val=5, units="kn") prob.set_val(Aircraft.Wing.AREA, val=1370, units="ft**2") prob.set_val( - Dynamic.Mission.DENSITY, val=RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" + Dynamic.Atmosphere.DENSITY, val=RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3" ) prob.set_val("CL_max", val=2.1886, units="unitless") prob.set_val("mass", val=175_000, units="lbm") diff --git a/aviary/mission/gasp_based/phases/time_integration_phases.py b/aviary/mission/gasp_based/phases/time_integration_phases.py index ca8a10f39..7b5e5d0b8 100644 --- a/aviary/mission/gasp_based/phases/time_integration_phases.py +++ b/aviary/mission/gasp_based/phases/time_integration_phases.py @@ -32,14 +32,15 @@ def __init__( problem_name=phase_name, outputs=["normal_force"], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, ], # state_units=['lbm','nmi','ft','ft/s'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, **simupy_args, ) @@ -66,14 +67,15 @@ def __init__( problem_name=phase_name, outputs=["normal_force", "alpha"], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, ], # state_units=['lbm','nmi','ft'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, **simupy_args, ) @@ -108,8 +110,11 @@ def __init__( ): controls = None super().__init__( - AscentODE(analysis_scheme=AnalysisScheme.SHOOTING, - alpha_mode=alpha_mode, **ode_args), + AscentODE( + analysis_scheme=AnalysisScheme.SHOOTING, + alpha_mode=alpha_mode, + **ode_args, + ), problem_name=phase_name, outputs=[ "load_factor", @@ -118,7 +123,7 @@ def __init__( "alpha", ], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, @@ -127,7 +132,8 @@ def __init__( ], # state_units=['lbm','nmi','ft'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, controls=controls, **simupy_args, ) @@ -365,14 +371,15 @@ def __init__( problem_name=phase_name, outputs=["EAS", "mach", "alpha"], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, ], # state_units=['lbm','nmi','ft'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, **simupy_args, ) @@ -424,24 +431,26 @@ def __init__( "mach", "EAS", Dynamic.Mission.VELOCITY, - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "drag", Dynamic.Mission.ALTITUDE_RATE, ], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], # state_units=['lbm','nmi','ft'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, **simupy_args, ) self.phase_name = phase_name - self.add_trigger(Dynamic.Mission.ALTITUDE, "alt_trigger", - units=self.alt_trigger_units) + self.add_trigger( + Dynamic.Mission.ALTITUDE, "alt_trigger", units=self.alt_trigger_units + ) self.add_trigger(self.speed_trigger_name, "speed_trigger", units="speed_trigger_units") @@ -481,25 +490,26 @@ def __init__( "lift", "EAS", Dynamic.Mission.VELOCITY, - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "drag", Dynamic.Mission.ALTITUDE_RATE, ], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, Dynamic.Mission.VELOCITY, ], # state_units=['lbm','nmi','ft'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, **simupy_args, ) self.phase_name = phase_name self.add_trigger(Dynamic.Mission.DISTANCE, "distance_trigger") - self.add_trigger(Dynamic.Mission.MASS, 'mass_trigger') + self.add_trigger(Dynamic.Vehicle.MASS, 'mass_trigger') class SGMDescent(SimuPyProblem): @@ -544,23 +554,25 @@ def __init__( "lift", "EAS", Dynamic.Mission.VELOCITY, - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, "drag", Dynamic.Mission.ALTITUDE_RATE, ], states=[ - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE, Dynamic.Mission.ALTITUDE, ], # state_units=['lbm','nmi','ft'], alternate_state_rate_names={ - Dynamic.Mission.MASS: Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL}, + Dynamic.Vehicle.MASS: Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL + }, **simupy_args, ) self.phase_name = phase_name - self.add_trigger(Dynamic.Mission.ALTITUDE, "alt_trigger", - units=self.alt_trigger_units) + self.add_trigger( + Dynamic.Mission.ALTITUDE, "alt_trigger", units=self.alt_trigger_units + ) self.add_trigger(self.speed_trigger_name, "speed_trigger", units=self.speed_trigger_units) diff --git a/aviary/mission/gasp_based/phases/v_rotate_comp.py b/aviary/mission/gasp_based/phases/v_rotate_comp.py index 2c2b991be..a96a8ad0f 100644 --- a/aviary/mission/gasp_based/phases/v_rotate_comp.py +++ b/aviary/mission/gasp_based/phases/v_rotate_comp.py @@ -13,10 +13,10 @@ class VRotateComp(om.ExplicitComponent): def setup(self): # Temporarily set this to shape (1, 1) to avoid OpenMDAO bug - add_aviary_input(self, Dynamic.Mission.MASS, shape=(1, 1), units="lbm") + add_aviary_input(self, Dynamic.Vehicle.MASS, shape=(1, 1), units="lbm") add_aviary_input( self, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, shape=(1,), units="slug/ft**3", val=RHO_SEA_LEVEL_ENGLISH, @@ -39,8 +39,8 @@ def setup(self): self.declare_partials( of="Vrot", wrt=[ - Dynamic.Mission.MASS, - Dynamic.Mission.DENSITY, + Dynamic.Vehicle.MASS, + Dynamic.Atmosphere.DENSITY, Aircraft.Wing.AREA, "CL_max", ], @@ -56,7 +56,7 @@ def compute_partials(self, inputs, partials, discrete_inputs=None): K = 0.5 * ((2 * mass * GRAV_ENGLISH_LBM) / (rho * wing_area * CL_max)) ** 0.5 - partials["Vrot", Dynamic.Mission.MASS] = K / mass - partials["Vrot", Dynamic.Mission.DENSITY] = -K / rho + partials["Vrot", Dynamic.Vehicle.MASS] = K / mass + partials["Vrot", Dynamic.Atmosphere.DENSITY] = -K / rho partials["Vrot", Aircraft.Wing.AREA] = -K / wing_area partials["Vrot", "CL_max"] = -K / CL_max diff --git a/aviary/mission/gasp_based/test/test_idle_descent_estimation.py b/aviary/mission/gasp_based/test/test_idle_descent_estimation.py index be6910d58..7fc63fb5e 100644 --- a/aviary/mission/gasp_based/test/test_idle_descent_estimation.py +++ b/aviary/mission/gasp_based/test/test_idle_descent_estimation.py @@ -27,7 +27,9 @@ def setUp(self): aviary_inputs, _ = create_vehicle(input_deck) aviary_inputs.set_val(Settings.VERBOSITY, 0) aviary_inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, val=28690, units="lbf") - aviary_inputs.set_val(Dynamic.Mission.THROTTLE, val=0, units="unitless") + aviary_inputs.set_val( + Dynamic.Vehicle.Propulsion.THROTTLE, val=0, units="unitless" + ) engine = build_engine_deck(aviary_options=aviary_inputs) preprocess_propulsion(aviary_inputs, engine) @@ -76,8 +78,8 @@ def test_subproblem(self): warnings.filterwarnings('default', category=UserWarning) # Values obtained by running idle_descent_estimation - assert_near_equal(prob.get_val('descent_range', 'NM'), 98.38026813, self.tol) - assert_near_equal(prob.get_val('descent_fuel', 'lbm'), 250.84809336, self.tol) + assert_near_equal(prob.get_val('descent_range', 'NM'), 98.3445738, self.tol) + assert_near_equal(prob.get_val('descent_fuel', 'lbm'), 250.79875356, self.tol) # TODO: check_partials() call results in runtime error: Jacobian in 'ODE_group' is not full rank. # partial_data = prob.check_partials(out_stream=None, method="cs") diff --git a/aviary/mission/ode/altitude_rate.py b/aviary/mission/ode/altitude_rate.py index 30c045c1d..5b7b285ef 100644 --- a/aviary/mission/ode/altitude_rate.py +++ b/aviary/mission/ode/altitude_rate.py @@ -16,17 +16,30 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] - self.add_input(Dynamic.Mission.SPECIFIC_ENERGY_RATE, val=np.ones( - nn), desc='current specific power', units='m/s') - self.add_input(Dynamic.Mission.VELOCITY_RATE, val=np.ones( - nn), desc='current acceleration', units='m/s**2') + self.add_input( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + val=np.ones(nn), + desc='current specific power', + units='m/s', + ) + self.add_input( + Dynamic.Mission.VELOCITY_RATE, + val=np.ones(nn), + desc='current acceleration', + units='m/s**2', + ) self.add_input( Dynamic.Mission.VELOCITY, val=np.ones(nn), desc='current velocity', - units='m/s') - self.add_output(Dynamic.Mission.ALTITUDE_RATE, val=np.ones( - nn), desc='current climb rate', units='m/s') + units='m/s', + ) + self.add_output( + Dynamic.Mission.ALTITUDE_RATE, + val=np.ones(nn), + desc='current climb rate', + units='m/s', + ) def compute(self, inputs, outputs): gravity = constants.GRAV_METRIC_FLOPS @@ -34,23 +47,32 @@ def compute(self, inputs, outputs): acceleration = inputs[Dynamic.Mission.VELOCITY_RATE] velocity = inputs[Dynamic.Mission.VELOCITY] - outputs[Dynamic.Mission.ALTITUDE_RATE] = \ + outputs[Dynamic.Mission.ALTITUDE_RATE] = ( specific_power - (velocity * acceleration) / gravity + ) def setup_partials(self): arange = np.arange(self.options['num_nodes']) - self.declare_partials(Dynamic.Mission.ALTITUDE_RATE, - [Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.VELOCITY_RATE, - Dynamic.Mission.VELOCITY], - rows=arange, - cols=arange, - val=1) + self.declare_partials( + Dynamic.Mission.ALTITUDE_RATE, + [ + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.VELOCITY_RATE, + Dynamic.Mission.VELOCITY, + ], + rows=arange, + cols=arange, + val=1, + ) def compute_partials(self, inputs, J): gravity = constants.GRAV_METRIC_FLOPS acceleration = inputs[Dynamic.Mission.VELOCITY_RATE] velocity = inputs[Dynamic.Mission.VELOCITY] - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY_RATE] = -velocity / gravity - J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = -acceleration / gravity + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY_RATE] = ( + -velocity / gravity + ) + J[Dynamic.Mission.ALTITUDE_RATE, Dynamic.Mission.VELOCITY] = ( + -acceleration / gravity + ) diff --git a/aviary/mission/ode/specific_energy_rate.py b/aviary/mission/ode/specific_energy_rate.py index 41002d0df..2046a8e5e 100644 --- a/aviary/mission/ode/specific_energy_rate.py +++ b/aviary/mission/ode/specific_energy_rate.py @@ -20,50 +20,68 @@ def setup(self): Dynamic.Mission.VELOCITY, val=np.ones(nn), desc='current velocity', - units='m/s') + units='m/s', + ) self.add_input( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, val=np.ones(nn), desc='current mass', units='kg') - self.add_input(Dynamic.Mission.THRUST_TOTAL, val=np.ones(nn), + self.add_input(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.ones(nn), desc='current thrust', units='N') self.add_input( - Dynamic.Mission.DRAG, + Dynamic.Vehicle.DRAG, val=np.ones(nn), desc='current drag', units='N') - self.add_output(Dynamic.Mission.SPECIFIC_ENERGY_RATE, val=np.ones( - nn), desc='current specific power', units='m/s') + self.add_output( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + val=np.ones(nn), + desc='current specific power', + units='m/s', + ) def compute(self, inputs, outputs): velocity = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] - weight = inputs[Dynamic.Mission.MASS] * gravity - outputs[Dynamic.Mission.SPECIFIC_ENERGY_RATE] = velocity * \ - (thrust - drag) / weight + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * gravity + outputs[Dynamic.Mission.SPECIFIC_ENERGY_RATE] = ( + velocity * (thrust - drag) / weight + ) def setup_partials(self): arange = np.arange(self.options['num_nodes']) - self.declare_partials(Dynamic.Mission.SPECIFIC_ENERGY_RATE, - [Dynamic.Mission.VELOCITY, - Dynamic.Mission.MASS, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.DRAG], - rows=arange, - cols=arange) + self.declare_partials( + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + [ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.DRAG, + ], + rows=arange, + cols=arange, + ) def compute_partials(self, inputs, J): velocity = inputs[Dynamic.Mission.VELOCITY] - thrust = inputs[Dynamic.Mission.THRUST_TOTAL] - drag = inputs[Dynamic.Mission.DRAG] - weight = inputs[Dynamic.Mission.MASS] * gravity + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] + drag = inputs[Dynamic.Vehicle.DRAG] + weight = inputs[Dynamic.Vehicle.MASS] * gravity - J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.VELOCITY] = (thrust - drag) / weight - J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.THRUST_TOTAL] = velocity / weight - J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, Dynamic.Mission.DRAG] = -velocity / weight - J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, Dynamic.Mission.MASS] = -gravity\ - * velocity * (thrust - drag) / (weight)**2 + J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, Dynamic.Mission.VELOCITY] = ( + thrust - drag + ) / weight + J[ + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + ] = ( + velocity / weight + ) + J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, Dynamic.Vehicle.DRAG] = ( + -velocity / weight + ) + J[Dynamic.Mission.SPECIFIC_ENERGY_RATE, Dynamic.Vehicle.MASS] = ( + -gravity * velocity * (thrust - drag) / (weight) ** 2 + ) diff --git a/aviary/mission/ode/test/test_altitude_rate.py b/aviary/mission/ode/test/test_altitude_rate.py index e6d33d548..20c43fc26 100644 --- a/aviary/mission/ode/test/test_altitude_rate.py +++ b/aviary/mission/ode/test/test_altitude_rate.py @@ -27,15 +27,19 @@ def setUp(self): def test_case1(self): - do_validation_test(self.prob, - 'full_mission_test_data', - input_validation_data=data, - output_validation_data=data, - input_keys=[Dynamic.Mission.SPECIFIC_ENERGY_RATE, - Dynamic.Mission.VELOCITY, - Dynamic.Mission.VELOCITY_RATE], - output_keys=Dynamic.Mission.ALTITUDE_RATE, - tol=1e-9) + do_validation_test( + self.prob, + 'full_mission_test_data', + input_validation_data=data, + output_validation_data=data, + input_keys=[ + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Mission.VELOCITY, + Dynamic.Mission.VELOCITY_RATE, + ], + output_keys=Dynamic.Mission.ALTITUDE_RATE, + tol=1e-9, + ) def test_IO(self): assert_match_varnames(self.prob.model) diff --git a/aviary/mission/ode/test/test_specific_energy_rate.py b/aviary/mission/ode/test/test_specific_energy_rate.py index 3618e4c29..103860b48 100644 --- a/aviary/mission/ode/test/test_specific_energy_rate.py +++ b/aviary/mission/ode/test/test_specific_energy_rate.py @@ -27,16 +27,20 @@ def setUp(self): def test_case1(self): - do_validation_test(self.prob, - 'full_mission_test_data', - input_validation_data=data, - output_validation_data=data, - input_keys=[Dynamic.Mission.DRAG, - Dynamic.Mission.MASS, - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.VELOCITY], - output_keys=Dynamic.Mission.SPECIFIC_ENERGY_RATE, - tol=1e-12) + do_validation_test( + self.prob, + 'full_mission_test_data', + input_validation_data=data, + output_validation_data=data, + input_keys=[ + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.MASS, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Mission.VELOCITY, + ], + output_keys=Dynamic.Mission.SPECIFIC_ENERGY_RATE, + tol=1e-12, + ) def test_IO(self): assert_match_varnames(self.prob.model) diff --git a/aviary/mission/phase_builder_base.py b/aviary/mission/phase_builder_base.py index 11375cee4..c468db885 100644 --- a/aviary/mission/phase_builder_base.py +++ b/aviary/mission/phase_builder_base.py @@ -483,14 +483,14 @@ def add_mass_state(self, user_options): mass_ref0 = user_options.get_val('mass_ref0', units='lbm') mass_defect_ref = user_options.get_val('mass_defect_ref', units='lbm') self.phase.add_state( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, fix_initial=user_options.get_val('fix_initial'), fix_final=False, lower=mass_lower, upper=mass_upper, units="lbm", - rate_source=Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - targets=Dynamic.Mission.MASS, + rate_source=Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + targets=Dynamic.Vehicle.MASS, ref=mass_ref, ref0=mass_ref0, defect_ref=mass_defect_ref, diff --git a/aviary/mission/twodof_phase.py b/aviary/mission/twodof_phase.py index 21a96954d..15f2068f1 100644 --- a/aviary/mission/twodof_phase.py +++ b/aviary/mission/twodof_phase.py @@ -79,7 +79,7 @@ def build_phase(self, aviary_options: AviaryValues = None): phase.add_timeseries_output("EAS", units="kn") phase.add_timeseries_output(Dynamic.Mission.VELOCITY, units="kn") - phase.add_timeseries_output(Dynamic.Mission.LIFT) + phase.add_timeseries_output(Dynamic.Vehicle.LIFT) return phase diff --git a/aviary/models/N3CC/N3CC_data.py b/aviary/models/N3CC/N3CC_data.py index ccea7fb00..9e1841553 100644 --- a/aviary/models/N3CC/N3CC_data.py +++ b/aviary/models/N3CC/N3CC_data.py @@ -459,29 +459,44 @@ takeoff_trajectory_builder = TakeoffTrajectory('detailed_takeoff') # region - takeoff aero -takeoff_subsystem_options = {'core_aerodynamics': - {'method': 'low_speed', - 'ground_altitude': 0., # units='m' - 'angles_of_attack': [ - 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, - 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, - 12.0, 13.0, 14.0, 15.0], # units='deg' - 'lift_coefficients': [ - 0.5178, 0.6, 0.75, 0.85, 0.95, 1.05, - 1.15, 1.25, 1.35, 1.5, 1.6, 1.7, - 1.8, 1.85, 1.9, 1.95], - 'drag_coefficients': [ - 0.0674, 0.065, 0.065, 0.07, 0.072, 0.076, - 0.084, 0.09, 0.10, 0.11, 0.12, 0.13, - 0.15, 0.16, 0.18, 0.20], - 'lift_coefficient_factor': 1., - 'drag_coefficient_factor': 1.}} - -takeoff_subsystem_options_spoilers = {'core_aerodynamics': - {**takeoff_subsystem_options['core_aerodynamics'], - 'use_spoilers': True, - 'spoiler_drag_coefficient': inputs.get_val(Mission.Takeoff.SPOILER_DRAG_COEFFICIENT), - 'spoiler_lift_coefficient': inputs.get_val(Mission.Takeoff.SPOILER_LIFT_COEFFICIENT)}} +# block auto-formatting of tables +# autopep8: off +# fmt: off +takeoff_subsystem_options = { + 'core_aerodynamics': { + 'method': 'low_speed', + 'ground_altitude': 0.0, # units='m' + 'angles_of_attack': [ + 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, + 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, + ], # units='deg' + 'lift_coefficients': [ + 0.5178, 0.6, 0.75, 0.85, 0.95, 1.05, 1.15, 1.25, + 1.35, 1.5, 1.6, 1.7, 1.8, 1.85, 1.9, 1.95, + ], + 'drag_coefficients': [ + 0.0674, 0.065, 0.065, 0.07, 0.072, 0.076, 0.084, 0.09, + 0.10, 0.11, 0.12, 0.13, 0.15, 0.16, 0.18, 0.20, + ], + 'lift_coefficient_factor': 1.0, + 'drag_coefficient_factor': 1.0, + } +} +# autopep8: on +# fmt: on + +takeoff_subsystem_options_spoilers = { + 'core_aerodynamics': { + **takeoff_subsystem_options['core_aerodynamics'], + 'use_spoilers': True, + 'spoiler_drag_coefficient': inputs.get_val( + Mission.Takeoff.SPOILER_DRAG_COEFFICIENT + ), + 'spoiler_lift_coefficient': inputs.get_val( + Mission.Takeoff.SPOILER_LIFT_COEFFICIENT + ), + } +} # endregion - takeoff aero @@ -596,7 +611,8 @@ takeoff_liftoff_initial_guesses.set_val('throttle', 1.) takeoff_liftoff_initial_guesses.set_val('altitude', [0, 35.0], 'ft') takeoff_liftoff_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [0, 6.0], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [0, 6.0], 'deg' +) takeoff_liftoff_initial_guesses.set_val('angle_of_attack', 8.117, 'deg') takeoff_liftoff_initial_guesses.set_val('mass', gross_mass, gross_mass_units) @@ -639,7 +655,8 @@ takeoff_mic_p2_initial_guesses.set_val('throttle', 1.) takeoff_mic_p2_initial_guesses.set_val('altitude', [35, 985.0], 'ft') takeoff_mic_p2_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [7.0, 10.0], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [7.0, 10.0], 'deg' +) takeoff_mic_p2_initial_guesses.set_val('angle_of_attack', 8.117, 'deg') takeoff_mic_p2_initial_guesses.set_val('mass', gross_mass, gross_mass_units) @@ -694,7 +711,8 @@ takeoff_mic_p2_to_engine_cutback_initial_guesses.set_val('altitude', [985, 2500.0], 'ft') takeoff_mic_p2_to_engine_cutback_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [11.0, 10.0], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [11.0, 10.0], 'deg' +) takeoff_mic_p2_to_engine_cutback_initial_guesses.set_val('angle_of_attack', 5.0, 'deg') @@ -749,7 +767,8 @@ takeoff_engine_cutback_initial_guesses.set_val('altitude', [2500.0, 2600.0], 'ft') takeoff_engine_cutback_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [10.0, 10.0], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [10.0, 10.0], 'deg' +) takeoff_engine_cutback_initial_guesses.set_val('angle_of_attack', 5.0, 'deg') takeoff_engine_cutback_initial_guesses.set_val('mass', gross_mass, gross_mass_units) @@ -810,7 +829,8 @@ 'altitude', [2600, 2700.0], 'ft') takeoff_engine_cutback_to_mic_p1_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, 2.29, 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, 2.29, 'deg' +) takeoff_engine_cutback_to_mic_p1_initial_guesses.set_val('angle_of_attack', 5.0, 'deg') takeoff_engine_cutback_to_mic_p1_initial_guesses.set_val( @@ -857,7 +877,8 @@ takeoff_mic_p1_to_climb_initial_guesses.set_val('throttle', cutback_throttle) takeoff_mic_p1_to_climb_initial_guesses.set_val('altitude', [2700, 3200.0], 'ft') takeoff_mic_p1_to_climb_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, 2.29, 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, 2.29, 'deg' +) takeoff_mic_p1_to_climb_initial_guesses.set_val('angle_of_attack', 5.0, 'deg') takeoff_mic_p1_to_climb_initial_guesses.set_val('mass', gross_mass, gross_mass_units) @@ -883,14 +904,15 @@ detailed_takeoff.set_val(Dynamic.Mission.ALTITUDE, [0.00, 0.00, 0.64, 27.98], 'ft') velocity = np.array([4.74, 157.58, 160.99, 166.68]) detailed_takeoff.set_val(Dynamic.Mission.VELOCITY, velocity, 'kn') -detailed_takeoff.set_val(Dynamic.Mission.MACH, [0.007, 0.2342, 0.2393, 0.2477]) +detailed_takeoff.set_val(Dynamic.Atmosphere.MACH, [0.007, 0.2342, 0.2393, 0.2477]) detailed_takeoff.set_val( - Dynamic.Mission.THRUST_TOTAL, [44038.8, 34103.4, 33929.0, 33638.2], 'lbf') + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, [44038.8, 34103.4, 33929.0, 33638.2], 'lbf') detailed_takeoff.set_val('angle_of_attack', [0.000, 3.600, 8.117, 8.117], 'deg') -detailed_takeoff.set_val(Dynamic.Mission.FLIGHT_PATH_ANGLE, [ - 0.000, 0.000, 0.612, 4.096], 'deg') +detailed_takeoff.set_val( + Dynamic.Mission.FLIGHT_PATH_ANGLE, [0.000, 0.000, 0.612, 4.096], 'deg' +) # missing from the default FLOPS output generated by hand # RANGE_RATE = VELOCITY * cos(flight_path_angle) @@ -908,7 +930,7 @@ # NOTE FLOPS output is based on "constant" takeoff mass - assume gross weight # - currently neglecting taxi -detailed_takeoff.set_val(Dynamic.Mission.MASS, [ +detailed_takeoff.set_val(Dynamic.Vehicle.MASS, [ 129734., 129734., 129734., 129734.], 'lbm') lift_coeff = np.array([0.5580, 0.9803, 1.4831, 1.3952]) @@ -922,10 +944,10 @@ RHV2 = 0.5 * rho * v * v * S lift = RHV2 * lift_coeff # N -detailed_takeoff.set_val(Dynamic.Mission.LIFT, lift, 'N') +detailed_takeoff.set_val(Dynamic.Vehicle.LIFT, lift, 'N') drag = RHV2 * drag_coeff # N -detailed_takeoff.set_val(Dynamic.Mission.DRAG, drag, 'N') +detailed_takeoff.set_val(Dynamic.Vehicle.DRAG, drag, 'N') def _split_aviary_values(aviary_values, slicing): @@ -1050,7 +1072,8 @@ def _split_aviary_values(aviary_values, slicing): balanced_liftoff_initial_guesses.set_val('throttle', engine_out_throttle) balanced_liftoff_initial_guesses.set_val('altitude', [0., 35.], 'ft') balanced_liftoff_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [0., 5.], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [0.0, 5.0], 'deg' +) balanced_liftoff_initial_guesses.set_val('angle_of_attack', 8.117, 'deg') balanced_liftoff_initial_guesses.set_val('mass', gross_mass, gross_mass_units) @@ -1158,105 +1181,127 @@ def _split_aviary_values(aviary_values, slicing): detailed_landing = AviaryValues() -values = np.array([ - -4.08, -4.08, -3.92, -3.76, -3.59, -3.43, -3.27, -3.1, -2.94, -2.78, - -2.61, -2.45, -2.29, -2.12, -1.96, -1.8, -1.63, -1.47, -1.31, -1.14, - -0.98, -0.82, -0.65, -0.49, -0.33, -0.16, 0, 0.16, 0.33, 0.49, - 0.65, 0.82, 0.98, 1.14, 1.31, 1.47, 1.63, 1.8, 1.96, 2.12, - 2.29, 2.45, 2.61, 2.78, 2.94, 3.1, 3.13, 3.92, 4.97, 5.68, - 5.93, 6.97, 7.97, 8.97, 9.97, 10.97, 11.97, 12.97, 13.97, 14.97, - 15.97, 16.97, 17.97, 18.97, 19.97, 20.97, 21.97, 22.97, 23.97, 24.49]) +# block auto-formatting of tables +# autopep8: off +# fmt: off +values = np.array( + [ + -4.08, -4.08, -3.92, -3.76, -3.59, -3.43, -3.27, -3.1, -2.94, -2.78, -2.61, + -2.45, -2.29, -2.12, -1.96, -1.8, -1.63, -1.47, -1.31, -1.14, -0.98, -0.82, + -0.65, -0.49, -0.33, -0.16, 0, 0.16, 0.33, 0.49, 0.65, 0.82, 0.98, 1.14, 1.31, + 1.47, 1.63, 1.8, 1.96, 2.12, 2.29, 2.45, 2.61, 2.78, 2.94, 3.1, 3.13, 3.92, 4.97, + 5.68, 5.93, 6.97, 7.97, 8.97, 9.97, 10.97, 11.97, 12.97, 13.97, 14.97, 15.97, + 16.97, 17.97, 18.97, 19.97, 20.97, 21.97, 22.97, 23.97, 24.49 + ] +) base = values[0] values = values - base detailed_landing.set_val('time', values, 's') -values = np.array([ - -954.08, -954.06, -915.89, -877.73, -839.57, -801.41, -763.25, -725.08, - -686.92, -648.76, -610.6, -572.43, -534.27, -496.11, -457.95, -419.78, - -381.62, -343.46, -305.3, -267.14, -228.97, -190.81, -152.65, -114.49, - -76.32, -38.16, 0, 38.16, 76.32, 114.49, 152.65, 190.81, - 228.97, 267.14, 305.3, 343.46, 381.62, 419.78, 457.95, 496.11, - 534.27, 572.43, 610.6, 648.76, 686.92, 725.08, 731.46, 917.22, - 1160.47, 1324.21, 1381.29, 1610.61, 1817.53, 2010.56, 2190, 2356.17, - 2509.36, 2649.84, 2777.85, 2893.6, 2997.28, 3089.05, 3169.07, 3237.45, - 3294.31, 3339.73, 3373.78, 3396.51, 3407.96, 3409.47]) +values = np.array( + [ + -954.08, -954.06, -915.89, -877.73, -839.57, -801.41, -763.25, -725.08, -686.92, + -648.76, -610.6, -572.43, -534.27, -496.11, -457.95, -419.78, -381.62, -343.46, + -305.3, -267.14, -228.97, -190.81, -152.65, -114.49, -76.32, -38.16, 0, 38.16, + 76.32, 114.49, 152.65, 190.81, 228.97, 267.14, 305.3, 343.46, 381.62, 419.78, + 457.95, 496.11, 534.27, 572.43, 610.6, 648.76, 686.92, 725.08, 731.46, 917.22, + 1160.47, 1324.21, 1381.29, 1610.61, 1817.53, 2010.56, 2190, 2356.17, + 2509.36, 2649.84, 2777.85, 2893.6, 2997.28, 3089.05, 3169.07, 3237.45, + 3294.31, 3339.73, 3373.78, 3396.51, 3407.96, 3409.47 + ] +) +# autopep8: on +# fmt: on base = values[0] values = values - base detailed_landing.set_val(Dynamic.Mission.DISTANCE, values, 'ft') +# block auto-formatting of tables +# autopep8: off +# fmt: off detailed_landing.set_val( Dynamic.Mission.ALTITUDE, [ - 100, 100, 98, 96, 94, 92, 90, 88, 86, 84, - 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, - 62, 60, 58, 56, 54, 52, 50, 48, 46, 44, - 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, - 22, 20, 18, 16, 14, 12, 11.67, 2.49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - 'ft') + 100, 100, 98, 96, 94, 92, 90, 88, 86, 84, 80, 78, 76, 74, 72, 70, 68, 66, 64, 62, + 60, 58, 56, 54, 52, 50, 48, 46, 44, 42, 40, 38, 36, 34, 32, 30, 28, 26, 24, 22, + 20, 18, 16, 14, 12, 11.67, 2.49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ], + 'ft', +) detailed_landing.set_val( Dynamic.Mission.VELOCITY, - np.array([ - 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, - 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, - 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, - 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, - 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.6, 137.18, 136.12, - 134.43, 126.69, 118.46, 110.31, 102.35, 94.58, 86.97, 79.52, 72.19, 64.99, - 57.88, 50.88, 43.95, 37.09, 30.29, 23.54, 16.82, 10.12, 3.45, 0]), - 'kn') + np.array( + [ + 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, + 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, + 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, + 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, + 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, 138.65, + 138.65, 138.65, 138.60, 137.18, 136.12, 134.43, 126.69, 118.46, 110.31, + 102.35, 94.58, 86.97, 79.52, 72.19, 64.99, 57.88, 50.88, 43.95, 37.09, + 30.29, 23.54, 16.82, 10.12, 3.45, 0 + ] + ), + 'kn', +) detailed_landing.set_val( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, [ 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, - 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.206, 0.2039, 0.2023, + 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2061, 0.2060, 0.2039, 0.2023, 0.1998, 0.1883, 0.1761, 0.1639, 0.1521, 0.1406, 0.1293, 0.1182, 0.1073, 0.0966, - 0.086, 0.0756, 0.0653, 0.0551, 0.045, 0.035, 0.025, 0.015, 0.0051, 0]) + 0.086, 0.0756, 0.0653, 0.0551, 0.045, 0.035, 0.025, 0.015, 0.0051, 0, + ], +) detailed_landing.set_val( - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, [ - 7614, 7614, 7607.7, 7601, 7593.9, 7586.4, 7578.5, 7570.2, 7561.3, 7551.8, - 7541.8, 7531.1, 7519.7, 7507.6, 7494.6, 7480.6, 7465.7, 7449.7, 7432.5, 7414, - 7394, 7372.3, 7348.9, 7323.5, 7295.9, 7265.8, 7233, 7197.1, 7157.7, 7114.3, + 7614.0, 7614.0, 7607.7, 7601.0, 7593.9, 7586.4, 7578.5, 7570.2, 7561.3, 7551.8, + 7541.8, 7531.1, 7519.7, 7507.6, 7494.6, 7480.6, 7465.7, 7449.7, 7432.5, 7414.0, + 7394.0, 7372.3, 7348.9, 7323.5, 7295.9, 7265.8, 7233.0, 7197.1, 7157.7, 7114.3, 7066.6, 7013.8, 6955.3, 6890.2, 6817.7, 6736.7, 6645.8, 6543.5, 6428.2, 6297.6, - 6149.5, 5980.9, 5788.7, 5569.3, 5318.5, 5032, 4980.3, 4102, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - 'lbf') + 6149.5, 5980.9, 5788.7, 5569.3, 5318.5, 5032.0, 4980.3, 4102, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + 'lbf', +) detailed_landing.set_val( 'angle_of_attack', [ - 5.231, 5.231, 5.231, 5.23, 5.23, 5.23, 5.23, 5.23, 5.229, 5.229, - 5.229, 5.229, 5.228, 5.228, 5.227, 5.227, 5.227, 5.226, 5.226, 5.225, - 5.224, 5.224, 5.223, 5.222, 5.221, 5.22, 5.219, 5.218, 5.217, 5.215, - 5.214, 5.212, 5.21, 5.207, 5.204, 5.201, 5.197, 5.193, 5.187, 5.181, - 5.173, 5.163, 5.151, 5.136, 5.117, 5.091, 5.086, 6.834, 5.585, 4.023, - 3.473, 1.185, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + 5.231, 5.231, 5.231, 5.23, 5.23, 5.23, 5.23, 5.23, 5.229, 5.229, 5.229, 5.229, + 5.228, 5.228, 5.227, 5.227, 5.227, 5.226, 5.226, 5.225, 5.224, 5.224, 5.223, + 5.222, 5.221, 5.22, 5.219, 5.218, 5.217, 5.215, 5.214, 5.212, 5.21, 5.207, 5.204, + 5.201, 5.197, 5.193, 5.187, 5.181, 5.173, 5.163, 5.151, 5.136, 5.117, 5.091, + 5.086, 6.834, 5.585, 4.023, 3.473, 1.185, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 + ], 'deg') # glide slope == flight path angle? detailed_landing.set_val( Dynamic.Mission.FLIGHT_PATH_ANGLE, - np.array([ - -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, - -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, - -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, - -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, - -3, -3, -3, -3, -3, -3, -3, -2.47, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), - 'deg') + np.array( + [ + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, + -3, -3, -3, -3, -3, -3, -3, -3, -3, -2.47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ] + ), + 'deg', +) +# autopep8: on +# fmt: on # missing from the default FLOPS output generated by script # RANGE_RATE = VELOCITY * cos(flight_path_angle) @@ -1277,26 +1322,37 @@ def _split_aviary_values(aviary_values, slicing): detailed_landing_mass = 106292. # units='lbm' detailed_landing.set_val( - Dynamic.Mission.MASS, np.full(velocity.shape, detailed_landing_mass), 'lbm') + Dynamic.Vehicle.MASS, np.full(velocity.shape, detailed_landing_mass), 'lbm') +# block auto-formatting of tables +# autopep8: off +# fmt: off # lift/drag is calculated very close to landing altitude (sea level, in this case)... -lift_coeff = np.array([ - 1.4091, 1.4091, 1.4091, 1.4091, 1.4092, 1.4092, 1.4092, 1.4092, 1.4092, 1.4092, - 1.4092, 1.4092, 1.4092, 1.4093, 1.4093, 1.4093, 1.4093, 1.4093, 1.4094, 1.4094, - 1.4094, 1.4094, 1.4095, 1.4095, 1.4095, 1.4096, 1.4096, 1.4096, 1.4097, 1.4097, - 1.4098, 1.4099, 1.4099, 1.41, 1.4101, 1.4102, 1.4103, 1.4105, 1.4106, 1.4108, - 1.4109, 1.4112, 1.4114, 1.4117, 1.412, 1.4124, 1.4124, 1.6667, 1.595, 1.397, - 0.5237, 0.2338, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, - 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046]) - -drag_coeff = np.array([ - 0.1731, 0.1731, 0.173, 0.173, 0.1729, 0.1728, 0.1727, 0.1726, 0.1724, 0.1723, - 0.1722, 0.1721, 0.1719, 0.1718, 0.1716, 0.1714, 0.1712, 0.171, 0.1708, 0.1705, - 0.1703, 0.17, 0.1697, 0.1694, 0.169, 0.1686, 0.1682, 0.1677, 0.1672, 0.1666, - 0.166, 0.1653, 0.1646, 0.1637, 0.1628, 0.1618, 0.1606, 0.1592, 0.1577, 0.1561, - 0.1541, 0.1519, 0.1495, 0.1466, 0.1434, 0.1396, 0.139, 0.13, 0.1207, 0.1099, - 0.1922, 0.1827, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, - 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785]) +lift_coeff = np.array( + [ + 1.4091, 1.4091, 1.4091, 1.4091, 1.4092, 1.4092, 1.4092, 1.4092, 1.4092, 1.4092, + 1.4092, 1.4092, 1.4092, 1.4093, 1.4093, 1.4093, 1.4093, 1.4093, 1.4094, 1.4094, + 1.4094, 1.4094, 1.4095, 1.4095, 1.4095, 1.4096, 1.4096, 1.4096, 1.4097, 1.4097, + 1.4098, 1.4099, 1.4099, 1.41, 1.4101, 1.4102, 1.4103, 1.4105, 1.4106, 1.4108, + 1.4109, 1.4112, 1.4114, 1.4117, 1.412, 1.4124, 1.4124, 1.6667, 1.595, 1.397, + 0.5237, 0.2338, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, + 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046, 0.046 + ] +) + +drag_coeff = np.array( + [ + 0.1731, 0.1731, 0.173, 0.173, 0.1729, 0.1728, 0.1727, 0.1726, 0.1724, 0.1723, + 0.1722, 0.1721, 0.1719, 0.1718, 0.1716, 0.1714, 0.1712, 0.171, 0.1708, 0.1705, + 0.1703, 0.17, 0.1697, 0.1694, 0.169, 0.1686, 0.1682, 0.1677, 0.1672, 0.1666, + 0.166, 0.1653, 0.1646, 0.1637, 0.1628, 0.1618, 0.1606, 0.1592, 0.1577, 0.1561, + 0.1541, 0.1519, 0.1495, 0.1466, 0.1434, 0.1396, 0.139, 0.13, 0.1207, 0.1099, + 0.1922, 0.1827, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, + 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785, 0.1785 + ] +) +# autopep8: on +# fmt: on S = inputs.get_val(Aircraft.Wing.AREA, 'm**2') v = detailed_landing.get_val(Dynamic.Mission.VELOCITY, 'm/s') @@ -1306,10 +1362,10 @@ def _split_aviary_values(aviary_values, slicing): RHV2 = 0.5 * rho * v * v * S lift = RHV2 * lift_coeff # N -detailed_landing.set_val(Dynamic.Mission.LIFT, lift, 'N') +detailed_landing.set_val(Dynamic.Vehicle.LIFT, lift, 'N') drag = RHV2 * drag_coeff # N -detailed_landing.set_val(Dynamic.Mission.DRAG, drag, 'N') +detailed_landing.set_val(Dynamic.Vehicle.DRAG, drag, 'N') # Flops variable APRANG apr_angle = -3.0 # deg @@ -1350,7 +1406,8 @@ def _split_aviary_values(aviary_values, slicing): landing_approach_to_mic_p3_initial_guesses.set_val('altitude', [600., 394.], 'ft') landing_approach_to_mic_p3_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg' +) landing_approach_to_mic_p3_initial_guesses.set_val('angle_of_attack', 5.25, 'deg') @@ -1401,7 +1458,8 @@ def _split_aviary_values(aviary_values, slicing): landing_mic_p3_to_obstacle_initial_guesses.set_val('altitude', [394., 50.], 'ft') landing_mic_p3_to_obstacle_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg' +) landing_mic_p3_to_obstacle_initial_guesses.set_val('angle_of_attack', 5.25, 'deg') @@ -1439,7 +1497,8 @@ def _split_aviary_values(aviary_values, slicing): landing_obstacle_initial_guesses.set_val('altitude', [50., 15.], 'ft') landing_obstacle_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, apr_angle], 'deg' +) landing_obstacle_initial_guesses.set_val('angle_of_attack', 5.2, 'deg') @@ -1480,7 +1539,8 @@ def _split_aviary_values(aviary_values, slicing): landing_flare_initial_guesses.set_val('throttle', [throttle, throttle*4/7]) landing_flare_initial_guesses.set_val('altitude', [15., 0.], 'ft') landing_flare_initial_guesses.set_val( - Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, 0.], 'deg') + Dynamic.Mission.FLIGHT_PATH_ANGLE, [apr_angle, 0.0], 'deg' +) landing_flare_initial_guesses.set_val('angle_of_attack', [5.2, 7.5], 'deg') landing_flare_builder = LandingFlareToTouchdown( diff --git a/aviary/models/N3CC/N3CC_generic_low_speed_polars_FLOPSinp.csv b/aviary/models/N3CC/N3CC_generic_low_speed_polars_FLOPSinp.csv index 98cf16cf5..a222359a8 100644 --- a/aviary/models/N3CC/N3CC_generic_low_speed_polars_FLOPSinp.csv +++ b/aviary/models/N3CC/N3CC_generic_low_speed_polars_FLOPSinp.csv @@ -46,6 +46,7 @@ aircraft:engine:num_fuselage_engines,0,unitless aircraft:engine:num_wing_engines,2,unitless aircraft:engine:reference_mass,6293.8,lbm aircraft:engine:reference_sls_thrust,22200.5,lbf +aircraft:engine:scale_factor,0.99997747798473,unitless aircraft:engine:scaled_sls_thrust,22200,0,0,0,0,0,lbf aircraft:engine:subsonic_fuel_flow_scaler,1,unitless aircraft:engine:supersonic_fuel_flow_scaler,1,unitless diff --git a/aviary/models/engines/turboshaft_4465hp.deck b/aviary/models/engines/turboshaft_4465hp.deck index 91a42a30a..568d62045 100644 --- a/aviary/models/engines/turboshaft_4465hp.deck +++ b/aviary/models/engines/turboshaft_4465hp.deck @@ -12,7 +12,7 @@ # torque_limit: 22976.2 # sls_corrected_airflow: 30.5 - Mach_Number, Altitude (ft), Throttle, Shaft_Power (hp), Tailpipe_Thrust (lbf), Fuel_Flow (lb/h) + Mach_Number, Altitude (ft), Throttle, Shaft_Power_Corrected (hp), Tailpipe_Thrust (lbf), Fuel_Flow (lb/h) 0.0, 0.0, 0.52, 794.3999999999999, 618.3999999999999, 1035.8999999999999 0.0, 0.0, 0.56, 1191.5999999999997, 651.7, 1194.4999999999995 0.0, 0.0, 0.6, 1588.8999999999996, 684.8000000000001, 1353.7999999999993 diff --git a/aviary/models/large_single_aisle_1/large_single_aisle_1_GwGm.csv b/aviary/models/large_single_aisle_1/large_single_aisle_1_GwGm.csv index 0e33160b2..09894b55c 100644 --- a/aviary/models/large_single_aisle_1/large_single_aisle_1_GwGm.csv +++ b/aviary/models/large_single_aisle_1/large_single_aisle_1_GwGm.csv @@ -34,6 +34,7 @@ aircraft:engine:pod_mass_scaler,1,unitless aircraft:engine:pylon_factor,1.25,unitless aircraft:engine:reference_diameter,5.8,ft aircraft:engine:reference_sls_thrust,28690,lbf +aircraft:engine:scale_factor,1.0,unitless aircraft:engine:scaled_sls_thrust,28690,lbf aircraft:engine:type,7,unitless aircraft:engine:wing_locations,0.35,unitless diff --git a/aviary/models/large_turboprop_freighter/__init__.py b/aviary/models/large_turboprop_freighter/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/aviary/models/large_turboprop_freighter/large_turboprop_freighter.csv b/aviary/models/large_turboprop_freighter/large_turboprop_freighter.csv index a60b2ab4b..2fc5ebf5f 100644 --- a/aviary/models/large_turboprop_freighter/large_turboprop_freighter.csv +++ b/aviary/models/large_turboprop_freighter/large_turboprop_freighter.csv @@ -1,6 +1,28 @@ -# GASP-derived aircraft input deck converted from large_turboprop_freighter.dat +############ +# SETTINGS # +############ +settings:problem_type, fallout, unitless +settings:equations_of_motion, 2DOF +settings:mass_method, GASP -# Input Values +############ +# AIRCRAFT # +############ +aircraft:design:subsonic_drag_coeff_factor, 1.447, unitless + +# Design +aircraft:design:cg_delta, 0.25, unitless +aircraft:design:cockpit_control_mass_coefficient, 20, unitless +aircraft:design:drag_increment, 0.0015, unitless +aircraft:design:emergency_equipment_mass, 25, lbm +aircraft:design:max_structural_speed, 320, mi/h +aircraft:design:part25_structural_category, 3, unitless +aircraft:design:reserve_fuel_additional, 0.667, lbm +aircraft:design:static_margin, 0.05, unitless +aircraft:design:structural_mass_increment, 0, lbm +aircraft:design:supercritical_drag_shift, 0, unitless + +# Misc Systems aircraft:air_conditioning:mass_coefficient, 2.65, unitless aircraft:anti_icing:mass, 644, lbm aircraft:apu:mass, 756, lbm @@ -9,51 +31,58 @@ aircraft:controls:cockpit_control_mass_scaler, 1, unitless aircraft:controls:control_mass_increment, 0, lbm aircraft:controls:stability_augmentation_system_mass, 0, lbm aircraft:controls:stability_augmentation_system_mass_scaler, 1, unitless +aircraft:hydraulics:flight_control_mass_coefficient, 0.102, unitless +aircraft:hydraulics:gear_mass_coefficient, 0.11, unitless +aircraft:instruments:mass_coefficient, 0.0416, unitless + +# Crew and Payload aircraft:crew_and_payload:cargo_mass, 31273, lbm aircraft:crew_and_payload:catering_items_mass_per_passenger, 0, lbm aircraft:crew_and_payload:num_passengers, 60, unitless aircraft:crew_and_payload:passenger_mass_with_bags, 190, lbm aircraft:crew_and_payload:passenger_service_mass_per_passenger, 0, lbm aircraft:crew_and_payload:water_mass_per_occupant, 0, lbm -aircraft:design:cg_delta, 0.25, unitless -aircraft:design:cockpit_control_mass_coefficient, 20, unitless -aircraft:design:drag_increment, 0.0015, unitless -aircraft:design:emergency_equipment_mass, 25, lbm -aircraft:design:max_structural_speed, 320, mi/h -aircraft:design:part25_structural_category, 3, unitless -aircraft:design:reserve_fuel_additional, 0.667, lbm -aircraft:design:static_margin, 0.05, unitless -aircraft:design:structural_mass_increment, 0, lbm -aircraft:design:supercritical_drag_shift, 0, unitless + +# Engine/Propulsion +# setting electrical mass may not do anything +aircraft:electrical:mass, 300, lbm aircraft:engine:additional_mass_fraction, 0.34, unitless +aircraft:engine:data_file, models/engines/turboshaft_4465hp.deck aircraft:engine:mass_scaler, 1, unitless aircraft:engine:mass_specific, 0.37026, lbm/lbf aircraft:engine:num_engines, 4, unitless -aircraft:engine:data_file, models/engines/turboshaft_4465hp.deck +aircraft:engine:num_propeller_blades, 4, unitless aircraft:engine:pod_mass_scaler, 1, unitless +aircraft:engine:propeller_activity_factor, 167, unitless +aircraft:engine:propeller_diameter, 13.5, ft +aircraft:engine:propeller_integrated_lift_coefficient, 0.5, unitless +aircraft:engine:propeller_tip_speed_max, 720, ft/s aircraft:engine:pylon_factor, 0.7, unitless aircraft:engine:reference_diameter, 5.8, ft -aircraft:engine:reference_sls_thrust, 28690, lbf -aircraft:engine:scaled_sls_thrust, 28690, lbf +aircraft:engine:reference_sls_thrust, 5000, lbf +aircraft:engine:rpm_design, 13820, rpm +aircraft:engine:fixed_rpm, 13820, rpm +aircraft:engine:scaled_sls_thrust, 5000, lbf aircraft:engine:type, 6, unitless aircraft:engine:wing_locations, [0.385, 0.385], unitless -aircraft:engine:propeller_diameter, 13.5, ft -aircraft:engine:num_propeller_blades, 4, unitless -aircraft:engine:propeller_activity_factor, 167, unitless -aircraft:engine:propeller_tip_speed_max, 720, ft/s -# aircraft:engine:gearbox:gear_ratio, 13.53, unitless -aircraft:engine:fixed_rpm, 1019, rpm +aircraft:engine:gearbox:gear_ratio, 13.550135501355014, unitless +aircraft:engine:gearbox:efficiency, 1.0, unitless +aircraft:engine:gearbox:shaft_power_design, 4465, hp +aircraft:engine:gearbox:specific_torque, 100.0, N*m/kg + +# Fuel aircraft:fuel:density, 6.687, lbm/galUS aircraft:fuel:fuel_margin, 15, unitless aircraft:fuel:fuel_system_mass_coefficient, 0.065, unitless aircraft:fuel:fuel_system_mass_scaler, 1, unitless aircraft:fuel:unusable_fuel_mass_coefficient, 4.5, unitless aircraft:fuel:wing_fuel_fraction, 0.324, unitless -aircraft:furnishings:mass, 0, lbm + +# Fuselage aircraft:fuselage:aisle_width, 48.8, inch aircraft:fuselage:delta_diameter, 5, ft aircraft:fuselage:flat_plate_area_increment, 2, ft**2 -aircraft:fuselage:form_factor, -1, unitless +aircraft:fuselage:form_factor, 1.25, unitless aircraft:fuselage:mass_coefficient, 145.87, unitless aircraft:fuselage:nose_fineness, 1, unitless aircraft:fuselage:num_aisles, 1, unitless @@ -64,9 +93,11 @@ aircraft:fuselage:seat_pitch, 41.24, inch aircraft:fuselage:seat_width, 18, inch aircraft:fuselage:tail_fineness, 2.9, unitless aircraft:fuselage:wetted_area_factor, 1, unitless + +# H-Tail aircraft:horizontal_tail:area, 0, ft**2 aircraft:horizontal_tail:aspect_ratio, 6.03, unitless -aircraft:horizontal_tail:form_factor, -1, unitless +aircraft:horizontal_tail:form_factor, 1.25, unitless aircraft:horizontal_tail:mass_coefficient, 0.2285, unitless aircraft:horizontal_tail:moment_ratio, 0.3061, unitless aircraft:horizontal_tail:sweep, 0, deg @@ -74,35 +105,34 @@ aircraft:horizontal_tail:taper_ratio, 0.374, unitless aircraft:horizontal_tail:thickness_to_chord, 0.15, unitless aircraft:horizontal_tail:vertical_tail_fraction, 0, unitless aircraft:horizontal_tail:volume_coefficient, 0.8614, unitless -aircraft:hydraulics:flight_control_mass_coefficient, 0.102, unitless -aircraft:hydraulics:gear_mass_coefficient, 0.11, unitless -aircraft:instruments:mass_coefficient, 0.0416, unitless -aircraft:landing_gear:fixed_gear, True, unitless + +# Landing Gear +aircraft:landing_gear:fixed_gear, False, unitless aircraft:landing_gear:main_gear_location, 0, unitless aircraft:landing_gear:main_gear_mass_coefficient, 0.916, unitless aircraft:landing_gear:mass_coefficient, 0.0337, unitless aircraft:landing_gear:tail_hook_mass_scaler, 1, unitless aircraft:landing_gear:total_mass_scaler, 1, unitless + +# Nacelle aircraft:nacelle:clearance_ratio, 0.2, unitless aircraft:nacelle:core_diameter_ratio, 1.15, unitless aircraft:nacelle:fineness, 0.38, unitless -aircraft:nacelle:form_factor, -1, unitless +aircraft:nacelle:form_factor, 1.5, unitless aircraft:nacelle:mass_specific, 3, lbm/ft**2 -aircraft:strut:area_ratio, 0, unitless -aircraft:strut:attachment_location, 0, ft -aircraft:strut:attachment_location_dimensionless, 0, unitless -aircraft:strut:dimensional_location_specified, False, unitless -aircraft:strut:fuselage_interference_factor, 0, unitless -aircraft:strut:mass_coefficient, 0, unitless + +# V-Tail aircraft:vertical_tail:area, 0, ft**2 aircraft:vertical_tail:aspect_ratio, 1.81, unitless -aircraft:vertical_tail:form_factor, -1, unitless +aircraft:vertical_tail:form_factor, 1.25, unitless aircraft:vertical_tail:mass_coefficient, 0.2035, unitless aircraft:vertical_tail:moment_ratio, 2.809, unitless aircraft:vertical_tail:sweep, 0, deg aircraft:vertical_tail:taper_ratio, 0.296, unitless aircraft:vertical_tail:thickness_to_chord, 0.15, unitless aircraft:vertical_tail:volume_coefficient, 0.05355, unitless + +# Wing aircraft:wing:aspect_ratio, 10.078, unitless aircraft:wing:center_distance, 0.45, unitless aircraft:wing:choose_fold_location, True, unitless @@ -116,7 +146,7 @@ aircraft:wing:flap_type, double_slotted, unitless aircraft:wing:fold_dimensional_location_specified, False, unitless aircraft:wing:fold_mass_coefficient, 0, unitless aircraft:wing:folded_span, 0, ft -aircraft:wing:form_factor, -1, unitless +aircraft:wing:form_factor, 1.25, unitless aircraft:wing:fuselage_interference_factor, 1, unitless aircraft:wing:has_fold, False, unitless aircraft:wing:has_strut, False, unitless @@ -143,11 +173,29 @@ aircraft:wing:taper_ratio, 0.52, unitless aircraft:wing:thickness_to_chord_root, 0.18, unitless aircraft:wing:thickness_to_chord_tip, 0.12, unitless aircraft:wing:zero_lift_angle, -1, deg + +# Misc Mass (zeroed out) +aircraft:strut:area_ratio, 0, unitless +aircraft:strut:attachment_location, 0, ft +aircraft:strut:attachment_location_dimensionless, 0, unitless +aircraft:strut:dimensional_location_specified, False, unitless +aircraft:strut:fuselage_interference_factor, 0, unitless +aircraft:strut:mass_coefficient, 0, unitless +aircraft:furnishings:mass, 0, lbm + +########### +# MISSION # +########### +mission:summary:fuel_flow_scaler, 1, unitless + +# Design mission:design:cruise_altitude, 21000, ft mission:design:gross_mass, 155000, lbm mission:design:mach, 0.475, unitless -mission:design:range, 0, NM +mission:design:range, 2020, NM mission:design:rate_of_climb_at_top_of_climb, 300, ft/min + +# Takeoff and Landing mission:landing:airport_altitude, 0, ft mission:landing:braking_delay, 2, s mission:landing:glide_to_stall_ratio, 1.3, unitless @@ -155,17 +203,13 @@ mission:landing:maximum_flare_load_factor, 1.15, unitless mission:landing:maximum_sink_rate, 900, ft/min mission:landing:obstacle_height, 50, ft mission:landing:touchdown_sink_rate, 5, ft/s -mission:summary:fuel_flow_scaler, 1, unitless mission:takeoff:decision_speed_increment, 5, kn mission:takeoff:rotation_speed_increment, 5, kn mission:taxi:duration, 0.15, h -settings:problem_type, fallout, unitless -settings:equations_of_motion, 2DOF -settings:mass_method, GASP - -mission:constraints:max_mach, 0.5, unitless -# Initial Guesses +################### +# Initial Guesses # +################### actual_takeoff_mass, 0 climb_range, 0 cruise_mass_final, 0 @@ -175,7 +219,9 @@ reserves, 0 rotation_mass, 0.99 time_to_climb, 0 -# Unconverted Values +###################### +# Unconverted Values # +###################### INGASP.ACDCDR, 1, 1, 1, 1, 1.15, 1.392, 1.7855, 3.5714, 5.36 INGASP.ACLS, 0, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6, 1.8 INGASP.BENGOB, 0.05 @@ -222,17 +268,12 @@ INGASP.WLPCT, 0.976 INGASP.WPLX, 25000 INGASP.XLFMAX, 1.2 INGASP.XTORQ, 4500 -INPROP.AF, 167 INPROP.ANCQHP, 0.03405 -INPROP.BL, 4 INPROP.BLANG, 0 -INPROP.CLI, 0.5 INPROP.CTI, 0.2 INPROP.DIST, 1000 -INPROP.DPROP, 13.5 -INPROP.GR, 0.0738 +INPROP.GR, 13.550135501355014 INPROP.HNOYS, 1000 -INPROP.HPMSLS, 4465 INPROP.IDATE, 1980 INPROP.JSIZE, 1 INPROP.KNOYS, -1 @@ -243,7 +284,5 @@ INPROP.PCLER, 0.1724 INPROP.PCNCCL, 1.0228 INPROP.PCNCCR, 1.05357 INPROP.PCNCTO, 1 -INPROP.TSPDMX, 720 INPROP.WKPFAC, 1.1 INPROP.WPROP1, 4500 -INPROP.XNMAX, 13820 \ No newline at end of file diff --git a/aviary/models/large_turboprop_freighter/phase_info.py b/aviary/models/large_turboprop_freighter/phase_info.py index 660a85f53..3566a67c7 100644 --- a/aviary/models/large_turboprop_freighter/phase_info.py +++ b/aviary/models/large_turboprop_freighter/phase_info.py @@ -1,84 +1,84 @@ -from aviary.variable_info.enums import SpeedType +from aviary.variable_info.enums import SpeedType, ThrottleAllocation # Energy method -# phase_info = { -# "pre_mission": {"include_takeoff": False, "optimize_mass": True}, -# "climb": { -# "subsystem_options": {"core_aerodynamics": {"method": "solved_alpha"}}, -# "user_options": { -# "optimize_mach": False, -# "optimize_altitude": False, -# "num_segments": 5, -# "order": 3, -# "solve_for_distance": False, -# "initial_mach": (0.2, "unitless"), -# "final_mach": (0.475, "unitless"), -# "mach_bounds": ((0.08, 0.478), "unitless"), -# "initial_altitude": (0.0, "ft"), -# "final_altitude": (21_000.0, "ft"), -# "altitude_bounds": ((0.0, 22_000.0), "ft"), -# "throttle_enforcement": "path_constraint", -# "fix_initial": True, -# "constrain_final": False, -# "fix_duration": False, -# "initial_bounds": ((0.0, 0.0), "min"), -# "duration_bounds": ((24.0, 192.0), "min"), -# "add_initial_mass_constraint": False, -# }, -# }, -# "cruise": { -# "subsystem_options": {"core_aerodynamics": {"method": "solved_alpha"}}, -# "user_options": { -# "optimize_mach": False, -# "optimize_altitude": False, -# "num_segments": 5, -# "order": 3, -# "solve_for_distance": False, -# "initial_mach": (0.475, "unitless"), -# "final_mach": (0.475, "unitless"), -# "mach_bounds": ((0.47, 0.48), "unitless"), -# "initial_altitude": (21_000.0, "ft"), -# "final_altitude": (21_000.0, "ft"), -# "altitude_bounds": ((20_000.0, 22_000.0), "ft"), -# "throttle_enforcement": "boundary_constraint", -# "fix_initial": False, -# "constrain_final": False, -# "fix_duration": False, -# "initial_bounds": ((64.0, 192.0), "min"), -# "duration_bounds": ((56.5, 169.5), "min"), -# }, -# }, -# "descent": { -# "subsystem_options": {"core_aerodynamics": {"method": "solved_alpha"}}, -# "user_options": { -# "optimize_mach": False, -# "optimize_altitude": False, -# "num_segments": 5, -# "order": 3, -# "solve_for_distance": False, -# "initial_mach": (0.475, "unitless"), -# "final_mach": (0.1, "unitless"), -# "mach_bounds": ((0.08, 0.48), "unitless"), -# "initial_altitude": (21_000.0, "ft"), -# "final_altitude": (500.0, "ft"), -# "altitude_bounds": ((0.0, 22_000.0), "ft"), -# "throttle_enforcement": "path_constraint", -# "fix_initial": False, -# "constrain_final": True, -# "fix_duration": False, -# "initial_bounds": ((100, 361.5), "min"), -# "duration_bounds": ((29.0, 87.0), "min"), -# }, -# }, -# "post_mission": { -# "include_landing": False, -# "constrain_range": True, -# "target_range": (2_020., "nmi"), -# }, -# } +energy_phase_info = { + "pre_mission": {"include_takeoff": False, "optimize_mass": True}, + "climb": { + "subsystem_options": {"core_aerodynamics": {"method": "computed"}}, + "user_options": { + "optimize_mach": False, + "optimize_altitude": False, + "num_segments": 5, + "order": 3, + "solve_for_distance": False, + "initial_mach": (0.2, "unitless"), + "final_mach": (0.475, "unitless"), + "mach_bounds": ((0.08, 0.478), "unitless"), + "initial_altitude": (0.0, "ft"), + "final_altitude": (21_000.0, "ft"), + "altitude_bounds": ((0.0, 22_000.0), "ft"), + "throttle_enforcement": "path_constraint", + "fix_initial": True, + "constrain_final": False, + "fix_duration": False, + "initial_bounds": ((0.0, 0.0), "min"), + "duration_bounds": ((24.0, 192.0), "min"), + "add_initial_mass_constraint": False, + }, + }, + "cruise": { + "subsystem_options": {"core_aerodynamics": {"method": "computed"}}, + "user_options": { + "optimize_mach": False, + "optimize_altitude": False, + "num_segments": 5, + "order": 3, + "solve_for_distance": False, + "initial_mach": (0.475, "unitless"), + "final_mach": (0.475, "unitless"), + "mach_bounds": ((0.47, 0.48), "unitless"), + "initial_altitude": (21_000.0, "ft"), + "final_altitude": (21_000.0, "ft"), + "altitude_bounds": ((20_000.0, 22_000.0), "ft"), + "throttle_enforcement": "boundary_constraint", + "fix_initial": False, + "constrain_final": False, + "fix_duration": False, + "initial_bounds": ((64.0, 192.0), "min"), + "duration_bounds": ((56.5, 169.5), "min"), + }, + }, + "descent": { + "subsystem_options": {"core_aerodynamics": {"method": "computed"}}, + "user_options": { + "optimize_mach": False, + "optimize_altitude": False, + "num_segments": 5, + "order": 3, + "solve_for_distance": False, + "initial_mach": (0.475, "unitless"), + "final_mach": (0.1, "unitless"), + "mach_bounds": ((0.08, 0.48), "unitless"), + "initial_altitude": (21_000.0, "ft"), + "final_altitude": (500.0, "ft"), + "altitude_bounds": ((0.0, 22_000.0), "ft"), + "throttle_enforcement": "path_constraint", + "fix_initial": False, + "constrain_final": True, + "fix_duration": False, + "initial_bounds": ((100, 361.5), "min"), + "duration_bounds": ((29.0, 87.0), "min"), + }, + }, + "post_mission": { + "include_landing": False, + "constrain_range": True, + "target_range": (2_020.0, "nmi"), + }, +} # 2DOF -phase_info = { +two_dof_phase_info = { 'groundroll': { 'user_options': { 'num_segments': 1, @@ -217,7 +217,7 @@ 'num_segments': 1, 'order': 3, 'fix_initial': False, - 'EAS_target': (150, 'kn'), + 'EAS_target': (250, 'kn'), 'mach_cruise': 0.475, 'target_mach': False, 'final_altitude': (10.0e3, 'ft'), @@ -247,7 +247,7 @@ 'num_segments': 3, 'order': 3, 'fix_initial': False, - 'EAS_target': (160, 'kn'), + 'EAS_target': (250, 'kn'), 'mach_cruise': 0.475, 'target_mach': True, 'final_altitude': (21_000, 'ft'), @@ -271,7 +271,7 @@ 'initial_guesses': { 'time': ([216.0, 1300.0], 's'), 'distance': ([100.0e3, 200.0e3], 'ft'), - 'altitude': ([10_000, 20_000], 'ft'), + 'altitude': ([10_000, 21_000], 'ft'), 'throttle': ([0.956, 0.956], 'unitless'), }, }, @@ -295,7 +295,7 @@ 'order': 3, 'fix_initial': False, 'input_initial': False, - 'EAS_limit': (160, 'kn'), + 'EAS_limit': (350, 'kn'), 'mach_cruise': 0.475, 'input_speed_type': SpeedType.MACH, 'final_altitude': (10_000, 'ft'), @@ -360,3 +360,5 @@ }, }, } + +phase_info = two_dof_phase_info diff --git a/aviary/models/multi_engine_single_aisle/multi_engine_single_aisle_data.py b/aviary/models/multi_engine_single_aisle/multi_engine_single_aisle_data.py index 0ff0dc67a..0ff5b633c 100644 --- a/aviary/models/multi_engine_single_aisle/multi_engine_single_aisle_data.py +++ b/aviary/models/multi_engine_single_aisle/multi_engine_single_aisle_data.py @@ -156,7 +156,8 @@ engine_1_inputs.set_val(Aircraft.Engine.DATA_FILE, filename) engine_1_inputs.set_val(Aircraft.Engine.MASS, 7400, 'lbm') engine_1_inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 7400, 'lbm') -engine_1_inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 28928.1/2, 'lbf') +# engine_1_inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 28928.1/2, 'lbf') +engine_1_inputs.set_val(Aircraft.Engine.SCALE_FACTOR, 0.3837186) # engine_1_inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 28928.1, 'lbf') engine_1_inputs.set_val(Aircraft.Engine.NUM_ENGINES, 2) engine_1_inputs.set_val(Aircraft.Engine.NUM_FUSELAGE_ENGINES, 0) @@ -188,7 +189,8 @@ engine_2_inputs.set_val(Aircraft.Engine.DATA_FILE, filename) engine_2_inputs.set_val(Aircraft.Engine.MASS, 6293.8, 'lbm') engine_2_inputs.set_val(Aircraft.Engine.REFERENCE_MASS, 6293.8, 'lbm') -engine_2_inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 22200.5/2, 'lbf') +# engine_2_inputs.set_val(Aircraft.Engine.SCALED_SLS_THRUST, 22200.5/2, 'lbf') +engine_2_inputs.set_val(Aircraft.Engine.SCALE_FACTOR, 0.65151911) # engine_2_inputs.set_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 22200.5, 'lbf') engine_2_inputs.set_val(Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, 0.0) engine_2_inputs.set_val(Aircraft.Engine.NUM_ENGINES, 2) diff --git a/aviary/models/small_single_aisle/small_single_aisle_GwGm.csv b/aviary/models/small_single_aisle/small_single_aisle_GwGm.csv index bf9dc3fec..0d7afc190 100644 --- a/aviary/models/small_single_aisle/small_single_aisle_GwGm.csv +++ b/aviary/models/small_single_aisle/small_single_aisle_GwGm.csv @@ -34,6 +34,7 @@ aircraft:engine:pod_mass_scaler,1,unitless aircraft:engine:pylon_factor,0.6,unitless aircraft:engine:reference_diameter,6.04,ft aircraft:engine:reference_sls_thrust,28690,lbf +aircraft:engine:scale_factor,0.8295573370512374,unitless aircraft:engine:scaled_sls_thrust,23800,lbf aircraft:engine:type,7,unitless aircraft:engine:wing_locations,0.272,unitless diff --git a/aviary/models/test_aircraft/aircraft_for_bench_FwGm.csv b/aviary/models/test_aircraft/aircraft_for_bench_FwGm.csv index f828f4f13..e209ed2ca 100644 --- a/aviary/models/test_aircraft/aircraft_for_bench_FwGm.csv +++ b/aviary/models/test_aircraft/aircraft_for_bench_FwGm.csv @@ -178,12 +178,10 @@ aircraft:crew_and_payload:passenger_service_mass_scaler,1.0,unitless aircraft:crew_and_payload:wing_cargo,0.0,lbm aircraft:design:base_area,0.0,ft**2 aircraft:design:empty_mass_margin_scaler,0.0,unitless -aircraft:design:lift_dependent_drag_coeff_factor,0.909839381134961,unitless aircraft:design:touchdown_mass,152800.0,lbm aircraft:design:subsonic_drag_coeff_factor,1.0,unitless aircraft:design:supersonic_drag_coeff_factor,1.0,unitless aircraft:design:use_alt_mass,False,unitless -aircraft:design:zero_lift_drag_coeff_factor,0.930890028006548,unitless aircraft:electrical:mass_scaler,1.25,unitless aircraft:fins:area,0.0,ft**2 aircraft:fins:mass_scaler,1.0,unitless diff --git a/aviary/models/test_aircraft/converter_configuration_test_data_GwGm.csv b/aviary/models/test_aircraft/converter_configuration_test_data_GwGm.csv index 8f9e52ad1..7b23f37b1 100644 --- a/aviary/models/test_aircraft/converter_configuration_test_data_GwGm.csv +++ b/aviary/models/test_aircraft/converter_configuration_test_data_GwGm.csv @@ -34,6 +34,7 @@ aircraft:engine:pod_mass_scaler,1,unitless aircraft:engine:pylon_factor,1.25,unitless aircraft:engine:reference_diameter,6.15,ft aircraft:engine:reference_sls_thrust,28690,lbf +aircraft:engine:scale_factor,0.7376089229696758,unitless aircraft:engine:scaled_sls_thrust,21162,lbf aircraft:engine:type,7,unitless aircraft:engine:wing_locations,0.2143,unitless diff --git a/aviary/sizing_problem.json b/aviary/sizing_problem.json deleted file mode 100644 index 419e44243..000000000 --- a/aviary/sizing_problem.json +++ /dev/null @@ -1,1307 +0,0 @@ -[ - [ - "aircraft:blended_wing_body_design:num_bays", - 0, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:mass_per_passenger", - 180, - "lbm", - "" - ], - [ - "aircraft:crew_and_payload:num_business_class", - 0, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:num_first_class", - 11, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:num_passengers", - 169, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:num_tourist_class", - 158, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:passenger_mass_with_bags", - 200, - "lbm", - "" - ], - [ - "aircraft:design:compute_htail_volume_coeff", - false, - "unitless", - "" - ], - [ - "aircraft:design:compute_vtail_volume_coeff", - false, - "unitless", - "" - ], - [ - "aircraft:design:part25_structural_category", - 3, - "unitless", - "" - ], - [ - "aircraft:design:reserve_fuel_additional", - 3000, - "lbm", - "" - ], - [ - "aircraft:design:reserve_fuel_fraction", - 0, - "unitless", - "" - ], - [ - "aircraft:design:smooth_mass_discontinuities", - false, - "unitless", - "" - ], - [ - "aircraft:design:ulf_calculated_from_maneuver", - false, - "unitless", - "" - ], - [ - "aircraft:design:use_alt_mass", - false, - "unitless", - "" - ], - [ - "aircraft:electrical:has_hybrid_system", - false, - "unitless", - "" - ], - [ - "aircraft:engine:compute_propeller_installation_loss", - [ - true - ], - "unitless", - "" - ], - [ - "aircraft:engine:constant_fuel_consumption", - [ - 0.0 - ], - "lbm/h", - "" - ], - [ - "aircraft:engine:flight_idle_max_fraction", - [ - 1.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:flight_idle_min_fraction", - [ - 0.08 - ], - "unitless", - "" - ], - [ - "aircraft:engine:flight_idle_thrust_fraction", - [ - 0.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:fuel_flow_scaler_constant_term", - [ - 0.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:fuel_flow_scaler_linear_term", - [ - 0.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:generate_flight_idle", - [ - true - ], - "unitless", - "" - ], - [ - "aircraft:engine:geopotential_alt", - [ - false - ], - "unitless", - "" - ], - [ - "aircraft:engine:has_propellers", - [ - false - ], - "unitless", - "" - ], - [ - "aircraft:engine:ignore_negative_thrust", - [ - false - ], - "unitless", - "" - ], - [ - "aircraft:engine:interpolation_method", - [ - "slinear" - ], - "unitless", - "" - ], - [ - "aircraft:engine:num_engines", - [ - 2 - ], - "unitless", - "" - ], - [ - "aircraft:engine:num_fuselage_engines", - [ - 0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:num_propeller_blades", - [ - 0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:num_wing_engines", - [ - 2 - ], - "unitless", - "" - ], - [ - "aircraft:engine:scale_mass", - [ - true - ], - "unitless", - "" - ], - [ - "aircraft:engine:scale_performance", - [ - true - ], - "unitless", - "" - ], - [ - "aircraft:engine:subsonic_fuel_flow_scaler", - [ - 1.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:supersonic_fuel_flow_scaler", - [ - 1.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:type", - [ - "[]" - ], - "unitless", - "" - ], - [ - "aircraft:engine:use_propeller_map", - [ - false - ], - "unitless", - "" - ], - [ - "aircraft:engine:shaft_power_design", - [ - 1.0 - ], - "hp", - "" - ], - [ - "aircraft:fins:num_fins", - 0, - "unitless", - "" - ], - [ - "aircraft:fuel:num_tanks", - 7, - "unitless", - "" - ], - [ - "aircraft:fuselage:aisle_width", - 24, - "inch", - "" - ], - [ - "aircraft:fuselage:military_cargo_floor", - false, - "unitless", - "" - ], - [ - "aircraft:fuselage:num_aisles", - 1, - "unitless", - "" - ], - [ - "aircraft:fuselage:num_fuselages", - 1, - "unitless", - "" - ], - [ - "aircraft:fuselage:num_seats_abreast", - 6, - "unitless", - "" - ], - [ - "aircraft:fuselage:seat_pitch", - 29, - "inch", - "" - ], - [ - "aircraft:fuselage:seat_width", - 20, - "inch", - "" - ], - [ - "aircraft:landing_gear:carrier_based", - false, - "unitless", - "" - ], - [ - "aircraft:landing_gear:drag_coefficient", - 0.0, - "unitless", - "" - ], - [ - "aircraft:landing_gear:fixed_gear", - true, - "unitless", - "" - ], - [ - "aircraft:strut:dimensional_location_specified", - true, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:num_tails", - 1, - "unitless", - "" - ], - [ - "aircraft:wing:airfoil_technology", - 1.92669766647637, - "unitless", - "" - ], - [ - "aircraft:wing:choose_fold_location", - true, - "unitless", - "" - ], - [ - "aircraft:wing:detailed_wing", - false, - "unitless", - "" - ], - [ - "aircraft:wing:flap_type", - "[]", - "unitless", - "" - ], - [ - "aircraft:wing:fold_dimensional_location_specified", - false, - "unitless", - "" - ], - [ - "aircraft:wing:has_fold", - false, - "unitless", - "" - ], - [ - "aircraft:wing:has_strut", - false, - "unitless", - "" - ], - [ - "aircraft:wing:load_distribution_control", - 2, - "unitless", - "" - ], - [ - "aircraft:wing:loading_above_20", - true, - "unitless", - "" - ], - [ - "aircraft:wing:num_flap_segments", - 2, - "unitless", - "" - ], - [ - "aircraft:wing:num_integration_stations", - 50, - "unitless", - "" - ], - [ - "aircraft:wing:span_efficiency_reduction", - false, - "unitless", - "" - ], - [ - "mission:design:cruise_altitude", - 35000, - "ft", - "" - ], - [ - "mission:design:rate_of_climb_at_top_of_climb", - 0.0, - "ft/min", - "" - ], - [ - "mission:summary:fuel_flow_scaler", - 1, - "unitless", - "" - ], - [ - "mission:takeoff:angle_of_attack_runway", - 0.0, - "deg", - "" - ], - [ - "mission:takeoff:obstacle_height", - 35.0, - "ft", - "" - ], - [ - "mission:takeoff:thrust_incidence", - 0.0, - "deg", - "" - ], - [ - "mission:taxi:duration", - 0.167, - "h", - "" - ], - [ - "mission:taxi:mach", - 0.0001, - "unitless", - "" - ], - [ - "settings:verbosity", - "[]", - "unitless", - "" - ], - [ - "INGASP.JENGSZ", - 4, - "unitless", - "" - ], - [ - "test_mode", - false, - "unitless", - "" - ], - [ - "use_surrogates", - true, - "unitless", - "" - ], - [ - "mass_defect", - 10000, - "lbm", - "" - ], - [ - "settings:problem_type", - "[]", - "unitless", - "" - ], - [ - "aircraft:air_conditioning:mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:anti_icing:mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:apu:mass_scaler", - 1.1, - "unitless", - "" - ], - [ - "aircraft:avionics:mass_scaler", - 1.2, - "unitless", - "" - ], - [ - "aircraft:canard:area", - 0, - "ft**2", - "" - ], - [ - "aircraft:canard:aspect_ratio", - 0, - "unitless", - "" - ], - [ - "aircraft:canard:thickness_to_chord", - 0, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:baggage_mass_per_passenger", - 45, - "lbm", - "" - ], - [ - "aircraft:crew_and_payload:cargo_container_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:flight_crew_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:misc_cargo", - 0, - "lbm", - "" - ], - [ - "aircraft:crew_and_payload:non_flight_crew_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:num_flight_attendants", - 3, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:num_flight_crew", - 2, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:num_galley_crew", - 0, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:passenger_service_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:crew_and_payload:wing_cargo", - 0, - "lbm", - "" - ], - [ - "aircraft:design:base_area", - 0, - "ft**2", - "" - ], - [ - "aircraft:design:empty_mass_margin_scaler", - 0, - "unitless", - "" - ], - [ - "aircraft:design:lift_dependent_drag_coeff_factor", - 0.909839381134961, - "unitless", - "" - ], - [ - "aircraft:design:touchdown_mass", - 152800, - "lbm", - "" - ], - [ - "aircraft:design:subsonic_drag_coeff_factor", - 1, - "unitless", - "" - ], - [ - "aircraft:design:supersonic_drag_coeff_factor", - 1, - "unitless", - "" - ], - [ - "aircraft:design:zero_lift_drag_coeff_factor", - 0.930890028006548, - "unitless", - "" - ], - [ - "aircraft:electrical:mass_scaler", - 1.25, - "unitless", - "" - ], - [ - "aircraft:engine:additional_mass_fraction", - [ - 0.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:data_file", - [ - "models/engines/turbofan_28k.deck" - ], - "unitless", - "" - ], - [ - "aircraft:engine:mass_scaler", - [ - 1.15 - ], - "unitless", - "" - ], - [ - "aircraft:engine:mass", - [ - 7400.0 - ], - "lbm", - "" - ], - [ - "aircraft:engine:reference_mass", - [ - 7400 - ], - "lbm", - "" - ], - [ - "aircraft:engine:reference_sls_thrust", - [ - 28928.1 - ], - "lbf", - "" - ], - [ - "aircraft:engine:scaled_sls_thrust", - [ - 28928.1 - ], - "lbf", - "" - ], - [ - "aircraft:engine:thrust_reversers_mass_scaler", - [ - 0.0 - ], - "unitless", - "" - ], - [ - "aircraft:engine:wing_locations", - [ - 0.26869218 - ], - "unitless", - "" - ], - [ - "aircraft:fins:area", - 0, - "ft**2", - "" - ], - [ - "aircraft:fins:mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:fins:mass", - 0, - "lbm", - "" - ], - [ - "aircraft:fins:taper_ratio", - 10, - "unitless", - "" - ], - [ - "aircraft:fuel:auxiliary_fuel_capacity", - 0, - "lbm", - "" - ], - [ - "aircraft:fuel:density_ratio", - 1, - "unitless", - "" - ], - [ - "aircraft:fuel:fuel_system_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:fuel:fuselage_fuel_capacity", - 0, - "lbm", - "" - ], - [ - "aircraft:fuel:total_capacity", - 45694, - "lbm", - "" - ], - [ - "aircraft:fuel:unusable_fuel_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:furnishings:mass_scaler", - 1.1, - "unitless", - "" - ], - [ - "aircraft:fuselage:length", - 128, - "ft", - "" - ], - [ - "aircraft:fuselage:mass_scaler", - 1.05, - "unitless", - "" - ], - [ - "aircraft:fuselage:max_height", - 13.17, - "ft", - "" - ], - [ - "aircraft:fuselage:max_width", - 12.33, - "ft", - "" - ], - [ - "aircraft:fuselage:passenger_compartment_length", - 85.5, - "ft", - "" - ], - [ - "aircraft:fuselage:planform_area", - 1578.24, - "ft**2", - "" - ], - [ - "aircraft:fuselage:wetted_area_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:fuselage:wetted_area", - 4158.62, - "ft**2", - "" - ], - [ - "aircraft:horizontal_tail:area", - 355, - "ft**2", - "" - ], - [ - "aircraft:horizontal_tail:aspect_ratio", - 6, - "unitless", - "" - ], - [ - "aircraft:horizontal_tail:mass_scaler", - 1.2, - "unitless", - "" - ], - [ - "aircraft:horizontal_tail:taper_ratio", - 0.22, - "unitless", - "" - ], - [ - "aircraft:horizontal_tail:thickness_to_chord", - 0.125, - "unitless", - "" - ], - [ - "aircraft:horizontal_tail:vertical_tail_fraction", - 0, - "unitless", - "" - ], - [ - "aircraft:horizontal_tail:wetted_area_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:horizontal_tail:wetted_area", - 592.65, - "ft**2", - "" - ], - [ - "aircraft:hydraulics:mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:hydraulics:system_pressure", - 3000, - "psi", - "" - ], - [ - "aircraft:instruments:mass_scaler", - 1.25, - "unitless", - "" - ], - [ - "aircraft:landing_gear:main_gear_mass_scaler", - 1.1, - "unitless", - "" - ], - [ - "aircraft:landing_gear:main_gear_oleo_length", - 102, - "inch", - "" - ], - [ - "aircraft:landing_gear:nose_gear_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:landing_gear:nose_gear_oleo_length", - 67, - "inch", - "" - ], - [ - "aircraft:nacelle:avg_diameter", - [ - 7.94 - ], - "ft", - "" - ], - [ - "aircraft:nacelle:avg_length", - [ - 12.3 - ], - "ft", - "" - ], - [ - "aircraft:nacelle:mass_scaler", - [ - 1.0 - ], - "unitless", - "" - ], - [ - "aircraft:nacelle:wetted_area_scaler", - [ - 1.0 - ], - "unitless", - "" - ], - [ - "aircraft:paint:mass_per_unit_area", - 0.037, - "lbm/ft**2", - "" - ], - [ - "aircraft:propulsion:engine_oil_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:propulsion:misc_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:area", - 284, - "ft**2", - "" - ], - [ - "aircraft:vertical_tail:aspect_ratio", - 1.75, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:taper_ratio", - 0.33, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:thickness_to_chord", - 0.1195, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:wetted_area_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:vertical_tail:wetted_area", - 581.13, - "ft**2", - "" - ], - [ - "aircraft:wing:aeroelastic_tailoring_factor", - 0, - "unitless", - "" - ], - [ - "aircraft:wing:area", - 1370, - "ft**2", - "" - ], - [ - "aircraft:wing:aspect_ratio", - 11.22091, - "unitless", - "" - ], - [ - "aircraft:wing:bending_mass_scaler", - 1, - "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", - "" - ], - [ - "aircraft:wing:control_surface_area_ratio", - 0.1, - "unitless", - "" - ], - [ - "aircraft:wing:glove_and_bat", - 134, - "ft**2", - "" - ], - [ - "aircraft:wing:input_station_dist", - [ - 0, - 0.2759, - 0.9367 - ], - "unitless", - "" - ], - [ - "aircraft:wing:load_fraction", - 1, - "unitless", - "" - ], - [ - "aircraft:wing:load_path_sweep_dist", - [ - 0, - 22 - ], - "deg", - "" - ], - [ - "aircraft:wing:mass_scaler", - 1.23, - "unitless", - "" - ], - [ - "aircraft:wing:max_camber_at_70_semispan", - 0, - "unitless", - "" - ], - [ - "aircraft:wing:misc_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:wing:shear_control_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:wing:span", - 117.83, - "ft", - "" - ], - [ - "aircraft:wing:strut_bracing_factor", - 0, - "unitless", - "" - ], - [ - "aircraft:wing:surface_ctrl_mass_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:wing:sweep", - 25, - "deg", - "" - ], - [ - "aircraft:wing:taper_ratio", - 0.278, - "unitless", - "" - ], - [ - "aircraft:wing:thickness_to_chord_dist", - [ - 0.145, - 0.115, - 0.104 - ], - "unitless", - "" - ], - [ - "aircraft:wing:thickness_to_chord", - 0.13, - "unitless", - "" - ], - [ - "aircraft:wing:ultimate_load_factor", - 3.75, - "unitless", - "" - ], - [ - "aircraft:wing:var_sweep_mass_penalty", - 0, - "unitless", - "" - ], - [ - "aircraft:wing:wetted_area_scaler", - 1, - "unitless", - "" - ], - [ - "aircraft:wing:wetted_area", - 2396.56, - "ft**2", - "" - ], - [ - "mission:constraints:max_mach", - 0.785, - "unitless", - "" - ], - [ - "mission:design:gross_mass", - 175864.58080717592, - "lbm", - "" - ], - [ - "mission:design:range", - 3375.0, - "NM", - "" - ], - [ - "mission:design:thrust_takeoff_per_eng", - 28928.1, - "lbf", - "" - ], - [ - "mission:landing:lift_coefficient_max", - 2, - "unitless", - "" - ], - [ - "mission:summary:cruise_mach", - 0.785, - "unitless", - "" - ], - [ - "mission:takeoff:fuel_simple", - 577, - "lbm", - "" - ], - [ - "mission:takeoff:lift_coefficient_max", - 3, - "unitless", - "" - ], - [ - "mission:takeoff:lift_over_drag", - 17.354, - "unitless", - "" - ], - [ - "settings:equations_of_motion", - "[]", - "unitless", - "" - ], - [ - "settings:mass_method", - "[]", - "unitless", - "" - ], - [ - "mission:summary:gross_mass", - 175864.58080717592, - "lbm", - "" - ], - [ - "aircraft:propulsion:total_num_engines", - 2, - "unitless", - "" - ], - [ - "aircraft:propulsion:total_num_fuselage_engines", - 0, - "unitless", - "" - ], - [ - "aircraft:propulsion:total_num_wing_engines", - 2, - "unitless", - "" - ] -] \ No newline at end of file diff --git a/aviary/subsystems/aerodynamics/aero_common.py b/aviary/subsystems/aerodynamics/aero_common.py index 964a0fa72..de4750977 100644 --- a/aviary/subsystems/aerodynamics/aero_common.py +++ b/aviary/subsystems/aerodynamics/aero_common.py @@ -20,16 +20,25 @@ def setup(self): nn = self.options['num_nodes'] self.add_input( - Dynamic.Mission.STATIC_PRESSURE, np.ones(nn), units='lbf/ft**2', - desc='Static pressure at each evaulation point.') + Dynamic.Atmosphere.STATIC_PRESSURE, + np.ones(nn), + units='lbf/ft**2', + desc='Static pressure at each evaulation point.', + ) self.add_input( - Dynamic.Mission.MACH, np.ones(nn), units='unitless', - desc='Mach at each evaulation point.') + Dynamic.Atmosphere.MACH, + np.ones(nn), + units='unitless', + desc='Mach at each evaulation point.', + ) self.add_output( - Dynamic.Mission.DYNAMIC_PRESSURE, val=np.ones(nn), units='lbf/ft**2', - desc='pressure caused by fluid motion') + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + val=np.ones(nn), + units='lbf/ft**2', + desc='pressure caused by fluid motion', + ) def setup_partials(self): nn = self.options['num_nodes'] @@ -37,22 +46,27 @@ def setup_partials(self): rows_cols = np.arange(nn) self.declare_partials( - Dynamic.Mission.DYNAMIC_PRESSURE, [ - Dynamic.Mission.STATIC_PRESSURE, Dynamic.Mission.MACH], - rows=rows_cols, cols=rows_cols) + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + [Dynamic.Atmosphere.STATIC_PRESSURE, Dynamic.Atmosphere.MACH], + rows=rows_cols, + cols=rows_cols, + ) def compute(self, inputs, outputs): gamma = self.options['gamma'] - P = inputs[Dynamic.Mission.STATIC_PRESSURE] - M = inputs[Dynamic.Mission.MACH] + P = inputs[Dynamic.Atmosphere.STATIC_PRESSURE] + M = inputs[Dynamic.Atmosphere.MACH] - outputs[Dynamic.Mission.DYNAMIC_PRESSURE] = 0.5 * gamma * P * M**2 + outputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] = 0.5 * gamma * P * M**2 def compute_partials(self, inputs, partials): gamma = self.options['gamma'] - P = inputs[Dynamic.Mission.STATIC_PRESSURE] - M = inputs[Dynamic.Mission.MACH] - - partials[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.MACH] = gamma * P * M - partials[Dynamic.Mission.DYNAMIC_PRESSURE, - Dynamic.Mission.STATIC_PRESSURE] = 0.5 * gamma * M**2 + P = inputs[Dynamic.Atmosphere.STATIC_PRESSURE] + M = inputs[Dynamic.Atmosphere.MACH] + + partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.MACH] = ( + gamma * P * M + ) + partials[ + Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.STATIC_PRESSURE + ] = (0.5 * gamma * M**2) diff --git a/aviary/subsystems/aerodynamics/aerodynamics_builder.py b/aviary/subsystems/aerodynamics/aerodynamics_builder.py index a68286458..d0dd6296e 100644 --- a/aviary/subsystems/aerodynamics/aerodynamics_builder.py +++ b/aviary/subsystems/aerodynamics/aerodynamics_builder.py @@ -199,37 +199,46 @@ def mission_inputs(self, **kwargs): if self.code_origin is FLOPS: if method == 'computed': - promotes = [Dynamic.Mission.STATIC_PRESSURE, - Dynamic.Mission.MACH, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.MASS, - 'aircraft:*', 'mission:*'] + promotes = [ + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Vehicle.MASS, + 'aircraft:*', + 'mission:*', + ] elif method == 'solved_alpha': - promotes = [Dynamic.Mission.ALTITUDE, - Dynamic.Mission.MACH, - Dynamic.Mission.MASS, - Dynamic.Mission.STATIC_PRESSURE, - 'aircraft:*'] + promotes = [ + Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.MACH, + Dynamic.Vehicle.MASS, + Dynamic.Atmosphere.STATIC_PRESSURE, + 'aircraft:*', + ] elif method == 'low_speed': - promotes = ['angle_of_attack', - Dynamic.Mission.ALTITUDE, - Dynamic.Mission.FLIGHT_PATH_ANGLE, - Mission.Takeoff.DRAG_COEFFICIENT_MIN, - Aircraft.Wing.ASPECT_RATIO, - Aircraft.Wing.HEIGHT, - Aircraft.Wing.SPAN, - Dynamic.Mission.DYNAMIC_PRESSURE, - Aircraft.Wing.AREA] + promotes = [ + 'angle_of_attack', + Dynamic.Mission.ALTITUDE, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + Mission.Takeoff.DRAG_COEFFICIENT_MIN, + Aircraft.Wing.ASPECT_RATIO, + Aircraft.Wing.HEIGHT, + Aircraft.Wing.SPAN, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + Aircraft.Wing.AREA, + ] elif method == 'tabular': - promotes = [Dynamic.Mission.ALTITUDE, - Dynamic.Mission.MACH, - Dynamic.Mission.MASS, - Dynamic.Mission.VELOCITY, - Dynamic.Mission.DENSITY, - 'aircraft:*'] + promotes = [ + Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.MACH, + Dynamic.Vehicle.MASS, + Dynamic.Mission.VELOCITY, + Dynamic.Atmosphere.DENSITY, + 'aircraft:*', + ] else: raise ValueError('FLOPS-based aero method is not one of the following: ' @@ -260,24 +269,25 @@ def mission_outputs(self, **kwargs): promotes = ['*'] if self.code_origin is FLOPS: - promotes = [Dynamic.Mission.DRAG, Dynamic.Mission.LIFT] + promotes = [Dynamic.Vehicle.DRAG, Dynamic.Vehicle.LIFT] elif self.code_origin is GASP: if method == 'low_speed': - promotes = [Dynamic.Mission.DRAG, - Dynamic.Mission.LIFT, - 'CL', 'CD', 'flap_factor', 'gear_factor'] + promotes = [ + Dynamic.Vehicle.DRAG, + Dynamic.Vehicle.LIFT, + 'CL', + 'CD', + 'flap_factor', + 'gear_factor', + ] elif method == 'cruise': if 'output_alpha' in kwargs: if kwargs['output_alpha']: - promotes = [Dynamic.Mission.DRAG, - Dynamic.Mission.LIFT, - 'alpha'] + promotes = [Dynamic.Vehicle.DRAG, Dynamic.Vehicle.LIFT, 'alpha'] else: - promotes = [Dynamic.Mission.DRAG, - Dynamic.Mission.LIFT, - 'CL_max'] + promotes = [Dynamic.Vehicle.DRAG, Dynamic.Vehicle.LIFT, 'CL_max'] else: raise ValueError('GASP-based aero method is not one of the following: ' @@ -566,7 +576,7 @@ def report(self, prob, reports_folder, **kwargs): AERO_2DOF_INPUTS = [ Aircraft.Design.CG_DELTA, - Aircraft.Design.DRAG_COEFFICIENT_INCREMENT, # drag increment? + Aircraft.Design.DRAG_COEFFICIENT_INCREMENT, # drag increment? Aircraft.Design.STATIC_MARGIN, Aircraft.Fuselage.AVG_DIAMETER, Aircraft.Fuselage.FLAT_PLATE_AREA_INCREMENT, @@ -611,4 +621,8 @@ def report(self, prob, reports_folder, **kwargs): AERO_CLEAN_2DOF_INPUTS = [ Aircraft.Design.SUPERCRITICAL_DIVERGENCE_SHIFT, # super drag shift? Mission.Design.LIFT_COEFFICIENT_MAX_FLAPS_UP, + Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, + Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, + Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, + Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, ] diff --git a/aviary/subsystems/aerodynamics/flops_based/buffet_lift.py b/aviary/subsystems/aerodynamics/flops_based/buffet_lift.py index 1a415f735..f97334ab5 100644 --- a/aviary/subsystems/aerodynamics/flops_based/buffet_lift.py +++ b/aviary/subsystems/aerodynamics/flops_based/buffet_lift.py @@ -23,10 +23,8 @@ def setup(self): # Simulation inputs self.add_input( - Dynamic.Mission.MACH, - shape=(nn), - units='unitless', - desc="Mach number") + Dynamic.Atmosphere.MACH, shape=(nn), units='unitless', desc="Mach number" + ) # Aero design inputs add_aviary_input(self, Mission.Design.MACH, 0.0) @@ -45,10 +43,8 @@ def setup_partials(self): nn = self.options["num_nodes"] self.declare_partials( - 'DELCLB', - Dynamic.Mission.MACH, - rows=np.arange(nn), - cols=np.arange(nn)) + 'DELCLB', Dynamic.Atmosphere.MACH, rows=np.arange(nn), cols=np.arange(nn) + ) self.declare_partials('DELCLB', [Aircraft.Wing.ASPECT_RATIO, Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, Aircraft.Wing.SWEEP, @@ -113,7 +109,7 @@ def compute_partials(self, inputs, partials): # wrt CAM dCLB_dCAM = FCLB * AR / 10.0 * cos_fact - partials["DELCLB", Dynamic.Mission.MACH] = dCLB_dMach + partials["DELCLB", Dynamic.Atmosphere.MACH] = dCLB_dMach partials["DELCLB", Mission.Design.MACH] = dCLB_ddesign_Mach partials['DELCLB', Aircraft.Wing.ASPECT_RATIO] = dCLB_dAR partials['DELCLB', Aircraft.Wing.THICKNESS_TO_CHORD] = dCLB_dTC diff --git a/aviary/subsystems/aerodynamics/flops_based/compressibility_drag.py b/aviary/subsystems/aerodynamics/flops_based/compressibility_drag.py index 9a320d2fe..f6bcfb66e 100644 --- a/aviary/subsystems/aerodynamics/flops_based/compressibility_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/compressibility_drag.py @@ -1,4 +1,3 @@ - import numpy as np import openmdao.api as om from openmdao.components.interp_util.interp import InterpND @@ -22,10 +21,8 @@ def setup(self): # Simulation inputs self.add_input( - Dynamic.Mission.MACH, - shape=(nn), - units='unitless', - desc="Mach number") + Dynamic.Atmosphere.MACH, shape=(nn), units='unitless', desc="Mach number" + ) # Aero design inputs add_aviary_input(self, Mission.Design.MACH, 0.0) @@ -50,8 +47,12 @@ def setup_partials(self): nn = self.options["num_nodes"] row_col = np.arange(nn) - self.declare_partials(of='compress_drag_coeff', wrt=[Dynamic.Mission.MACH], - rows=row_col, cols=row_col) + self.declare_partials( + of='compress_drag_coeff', + wrt=[Dynamic.Atmosphere.MACH], + rows=row_col, + cols=row_col, + ) wrt2 = [Aircraft.Wing.THICKNESS_TO_CHORD, Aircraft.Wing.ASPECT_RATIO, Aircraft.Wing.SWEEP, Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, @@ -67,7 +68,7 @@ def compute(self, inputs, outputs): Calculate compressibility drag. """ - del_mach = inputs[Dynamic.Mission.MACH] - inputs[Mission.Design.MACH] + del_mach = inputs[Dynamic.Atmosphere.MACH] - inputs[Mission.Design.MACH] idx_super = np.where(del_mach > 0.05) idx_sub = np.where(del_mach <= 0.05) @@ -84,7 +85,7 @@ def _compute_supersonic(self, inputs, outputs, idx): Calculate compressibility drag for supersonic speeds. """ - mach = inputs[Dynamic.Mission.MACH][idx] + mach = inputs[Dynamic.Atmosphere.MACH][idx] nn = len(mach) del_mach = mach - inputs[Mission.Design.MACH] AR = inputs[Aircraft.Wing.ASPECT_RATIO] @@ -166,7 +167,7 @@ def _compute_subsonic(self, inputs, outputs, idx): Calculate compressibility drag for subsonic speeds. """ - mach = inputs[Dynamic.Mission.MACH][idx] + mach = inputs[Dynamic.Atmosphere.MACH][idx] nn = len(mach) del_mach = mach - inputs[Mission.Design.MACH] TC = inputs[Aircraft.Wing.THICKNESS_TO_CHORD] @@ -224,7 +225,7 @@ def compute_partials(self, inputs, partials): :type partials: _type_ """ - del_mach = inputs[Dynamic.Mission.MACH] - inputs[Mission.Design.MACH] + del_mach = inputs[Dynamic.Atmosphere.MACH] - inputs[Mission.Design.MACH] idx_super = np.where(del_mach > 0.05) idx_sub = np.where(del_mach <= 0.05) @@ -235,7 +236,7 @@ def compute_partials(self, inputs, partials): def _compute_partials_supersonic(self, inputs, partials, idx): - mach = inputs[Dynamic.Mission.MACH][idx] + mach = inputs[Dynamic.Atmosphere.MACH][idx] nn = len(mach) AR = inputs[Aircraft.Wing.ASPECT_RATIO] TC = inputs[Aircraft.Wing.THICKNESS_TO_CHORD] @@ -353,7 +354,7 @@ def _compute_partials_supersonic(self, inputs, partials, idx): dCd_dwing_taper_ratio = dCd3_dCD3 * dCD3_dART * dART_dwing_taper_ratio dCd_dsweep25 = dCd3_dsweep25 - partials["compress_drag_coeff", Dynamic.Mission.MACH][idx] = dCd_dMach + partials["compress_drag_coeff", Dynamic.Atmosphere.MACH][idx] = dCd_dMach partials["compress_drag_coeff", Mission.Design.MACH][idx, 0] = dCd_ddesign_Mach partials["compress_drag_coeff", Aircraft.Wing.THICKNESS_TO_CHORD][idx, 0] = dCd_dTC partials["compress_drag_coeff", @@ -377,7 +378,7 @@ def _compute_partials_supersonic(self, inputs, partials, idx): def _compute_partials_subsonic(self, inputs, partials, idx): - mach = inputs[Dynamic.Mission.MACH][idx] + mach = inputs[Dynamic.Atmosphere.MACH][idx] nn = len(mach) TC = inputs[Aircraft.Wing.THICKNESS_TO_CHORD] max_camber_70 = inputs[Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN] @@ -417,7 +418,7 @@ def _compute_partials_subsonic(self, inputs, partials, idx): # wrt max_camber_70 dCd_dmax_camber_70 = CD1 * (1.0 / 10.0) * TC**(5.0 / 3.0) - partials["compress_drag_coeff", Dynamic.Mission.MACH][idx] = dCd_dMach + partials["compress_drag_coeff", Dynamic.Atmosphere.MACH][idx] = dCd_dMach partials["compress_drag_coeff", Mission.Design.MACH][idx, 0] = dCd_ddesign_Mach partials["compress_drag_coeff", Aircraft.Wing.THICKNESS_TO_CHORD][idx, 0] = dCd_dTC partials["compress_drag_coeff", diff --git a/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py index 33f61c5d6..22ff6ea54 100644 --- a/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/computed_aero_group.py @@ -51,47 +51,68 @@ def setup(self): 'laminar_fractions_upper', 'laminar_fractions_lower']) self.add_subsystem( - 'DynamicPressure', DynamicPressure(num_nodes=num_nodes, gamma=gamma), - promotes_inputs=[Dynamic.Mission.MACH, Dynamic.Mission.STATIC_PRESSURE], - promotes_outputs=[Dynamic.Mission.DYNAMIC_PRESSURE]) + 'DynamicPressure', + DynamicPressure(num_nodes=num_nodes, gamma=gamma), + promotes_inputs=[ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.STATIC_PRESSURE, + ], + promotes_outputs=[Dynamic.Atmosphere.DYNAMIC_PRESSURE], + ) comp = LiftEqualsWeight(num_nodes=num_nodes) self.add_subsystem( - name=Dynamic.Mission.LIFT, subsys=comp, - promotes_inputs=[Aircraft.Wing.AREA, Dynamic.Mission.MASS, - Dynamic.Mission.DYNAMIC_PRESSURE], - promotes_outputs=['cl', Dynamic.Mission.LIFT]) + name=Dynamic.Vehicle.LIFT, + subsys=comp, + promotes_inputs=[ + Aircraft.Wing.AREA, + Dynamic.Vehicle.MASS, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + ], + promotes_outputs=['cl', Dynamic.Vehicle.LIFT], + ) comp = LiftDependentDrag(num_nodes=num_nodes, gamma=gamma) self.add_subsystem( - 'PressureDrag', comp, + 'PressureDrag', + comp, promotes_inputs=[ - Dynamic.Mission.MACH, Dynamic.Mission.LIFT, Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + Dynamic.Vehicle.LIFT, + Dynamic.Atmosphere.STATIC_PRESSURE, Mission.Design.MACH, Mission.Design.LIFT_COEFFICIENT, Aircraft.Wing.AREA, Aircraft.Wing.ASPECT_RATIO, Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, Aircraft.Wing.SWEEP, - Aircraft.Wing.THICKNESS_TO_CHORD]) + Aircraft.Wing.THICKNESS_TO_CHORD, + ], + ) comp = InducedDrag( num_nodes=num_nodes, gamma=gamma, aviary_options=aviary_options) self.add_subsystem( - 'InducedDrag', comp, + 'InducedDrag', + comp, promotes_inputs=[ - Dynamic.Mission.MACH, Dynamic.Mission.LIFT, Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + Dynamic.Vehicle.LIFT, + Dynamic.Atmosphere.STATIC_PRESSURE, Aircraft.Wing.AREA, Aircraft.Wing.ASPECT_RATIO, Aircraft.Wing.SPAN_EFFICIENCY_FACTOR, Aircraft.Wing.SWEEP, - Aircraft.Wing.TAPER_RATIO]) + Aircraft.Wing.TAPER_RATIO, + ], + ) comp = CompressibilityDrag(num_nodes=num_nodes) self.add_subsystem( - 'CompressibilityDrag', comp, + 'CompressibilityDrag', + comp, promotes_inputs=[ - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, Mission.Design.MACH, Aircraft.Design.BASE_AREA, Aircraft.Wing.AREA, @@ -102,15 +123,22 @@ def setup(self): Aircraft.Wing.THICKNESS_TO_CHORD, Aircraft.Fuselage.CROSS_SECTION, Aircraft.Fuselage.DIAMETER_TO_WING_SPAN, - Aircraft.Fuselage.LENGTH_TO_DIAMETER]) + Aircraft.Fuselage.LENGTH_TO_DIAMETER, + ], + ) comp = SkinFriction(num_nodes=num_nodes, aviary_options=aviary_options) self.add_subsystem( - 'SkinFrictionCoef', comp, + 'SkinFrictionCoef', + comp, promotes_inputs=[ - Dynamic.Mission.MACH, Dynamic.Mission.STATIC_PRESSURE, Dynamic.Mission.TEMPERATURE, - 'characteristic_lengths'], - promotes_outputs=['skin_friction_coeff', 'Re']) + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.TEMPERATURE, + 'characteristic_lengths', + ], + promotes_outputs=['skin_friction_coeff', 'Re'], + ) comp = SkinFrictionDrag(num_nodes=num_nodes, aviary_options=aviary_options) self.add_subsystem( @@ -122,25 +150,33 @@ def setup(self): comp = ComputedDrag(num_nodes=num_nodes) self.add_subsystem( - 'Drag', comp, + 'Drag', + comp, promotes_inputs=[ - Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.MACH, Aircraft.Wing.AREA, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.MACH, + Aircraft.Wing.AREA, Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, - Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR], - promotes_outputs=['CDI', 'CD0', 'CD', Dynamic.Mission.DRAG]) + Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, + ], + promotes_outputs=['CDI', 'CD0', 'CD', Dynamic.Vehicle.DRAG], + ) buf = BuffetLift(num_nodes=num_nodes) self.add_subsystem( - 'Buffet', buf, + 'Buffet', + buf, promotes_inputs=[ - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, Mission.Design.MACH, Aircraft.Wing.ASPECT_RATIO, Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, Aircraft.Wing.SWEEP, - Aircraft.Wing.THICKNESS_TO_CHORD]) + Aircraft.Wing.THICKNESS_TO_CHORD, + ], + ) self.connect('PressureDrag.CD', 'Drag.pressure_drag_coeff') self.connect('InducedDrag.induced_drag_coeff', 'Drag.induced_drag_coeff') @@ -174,15 +210,21 @@ def setup(self): desc='zero-lift drag coefficient') self.add_subsystem( - Dynamic.Mission.DRAG, TotalDrag(num_nodes=nn), + Dynamic.Vehicle.DRAG, + TotalDrag(num_nodes=nn), promotes_inputs=[ Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, Aircraft.Wing.AREA, Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, - 'CDI', 'CD0', Dynamic.Mission.MACH, Dynamic.Mission.DYNAMIC_PRESSURE], - promotes_outputs=['CD', Dynamic.Mission.DRAG]) + 'CDI', + 'CD0', + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + ], + promotes_outputs=['CD', Dynamic.Vehicle.DRAG], + ) self.set_input_defaults(Aircraft.Wing.AREA, 1., 'ft**2') diff --git a/aviary/subsystems/aerodynamics/flops_based/drag.py b/aviary/subsystems/aerodynamics/flops_based/drag.py index d2b5e1b67..7e188bafe 100644 --- a/aviary/subsystems/aerodynamics/flops_based/drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/drag.py @@ -24,8 +24,11 @@ def setup(self): add_aviary_input(self, Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, val=1.) self.add_input( - Dynamic.Mission.MACH, val=np.ones(nn), units='unitless', - desc='ratio of local fluid speed to local speed of sound') + Dynamic.Atmosphere.MACH, + val=np.ones(nn), + units='unitless', + desc='ratio of local fluid speed to local speed of sound', + ) self.add_input( 'CD_prescaled', val=np.ones(nn), units='unitless', @@ -41,8 +44,7 @@ def setup_partials(self): Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR] ) - self.declare_partials('CD', - Dynamic.Mission.MACH, dependent=False) + self.declare_partials('CD', Dynamic.Atmosphere.MACH, dependent=False) nn = self.options['num_nodes'] rows_cols = np.arange(nn) @@ -54,7 +56,7 @@ def setup_partials(self): def compute(self, inputs, outputs): FCDSUB = inputs[Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR] FCDSUP = inputs[Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR] - M = inputs[Dynamic.Mission.MACH] + M = inputs[Dynamic.Atmosphere.MACH] CD_prescaled = inputs['CD_prescaled'] @@ -66,7 +68,7 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, partials): FCDSUB = inputs[Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR] FCDSUP = inputs[Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR] - M = inputs[Dynamic.Mission.MACH] + M = inputs[Dynamic.Atmosphere.MACH] CD_prescaled = inputs['CD_prescaled'] idx_sup = np.where(M >= 1.0) @@ -102,45 +104,48 @@ def setup(self): add_aviary_input(self, Aircraft.Wing.AREA, val=1., units='m**2') self.add_input( - Dynamic.Mission.DYNAMIC_PRESSURE, val=np.ones(nn), units='N/m**2', - desc='pressure caused by fluid motion') + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + val=np.ones(nn), + units='N/m**2', + desc='pressure caused by fluid motion', + ) self.add_input( 'CD', val=np.ones(nn), units='unitless', desc='total drag coefficient') - self.add_output(Dynamic.Mission.DRAG, val=np.ones(nn), - units='N', desc='total drag') + self.add_output( + Dynamic.Vehicle.DRAG, val=np.ones(nn), units='N', desc='total drag' + ) def setup_partials(self): nn = self.options['num_nodes'] rows_cols = np.arange(nn) - self.declare_partials( - Dynamic.Mission.DRAG, - Aircraft.Wing.AREA - ) + self.declare_partials(Dynamic.Vehicle.DRAG, Aircraft.Wing.AREA) self.declare_partials( - Dynamic.Mission.DRAG, - [Dynamic.Mission.DYNAMIC_PRESSURE, 'CD'], - rows=rows_cols, cols=rows_cols) + Dynamic.Vehicle.DRAG, + [Dynamic.Atmosphere.DYNAMIC_PRESSURE, 'CD'], + rows=rows_cols, + cols=rows_cols, + ) def compute(self, inputs, outputs): S = inputs[Aircraft.Wing.AREA] - q = inputs[Dynamic.Mission.DYNAMIC_PRESSURE] + q = inputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] CD = inputs['CD'] - outputs[Dynamic.Mission.DRAG] = q * S * CD + outputs[Dynamic.Vehicle.DRAG] = q * S * CD def compute_partials(self, inputs, partials): S = inputs[Aircraft.Wing.AREA] - q = inputs[Dynamic.Mission.DYNAMIC_PRESSURE] + q = inputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] CD = inputs['CD'] - partials[Dynamic.Mission.DRAG, Aircraft.Wing.AREA] = q * CD - partials[Dynamic.Mission.DRAG, Dynamic.Mission.DYNAMIC_PRESSURE] = S * CD - partials[Dynamic.Mission.DRAG, 'CD'] = q * S + partials[Dynamic.Vehicle.DRAG, Aircraft.Wing.AREA] = q * CD + partials[Dynamic.Vehicle.DRAG, Dynamic.Atmosphere.DYNAMIC_PRESSURE] = S * CD + partials[Dynamic.Vehicle.DRAG, 'CD'] = q * S class TotalDrag(om.Group): diff --git a/aviary/subsystems/aerodynamics/flops_based/ground_effect.py b/aviary/subsystems/aerodynamics/flops_based/ground_effect.py index 1b1ca9de6..3130ed5da 100644 --- a/aviary/subsystems/aerodynamics/flops_based/ground_effect.py +++ b/aviary/subsystems/aerodynamics/flops_based/ground_effect.py @@ -42,8 +42,9 @@ def setup(self): add_aviary_input(self, Dynamic.Mission.ALTITUDE, np.zeros(nn), units='m') - add_aviary_input(self, Dynamic.Mission.FLIGHT_PATH_ANGLE, - val=np.zeros(nn), units='rad') + add_aviary_input( + self, Dynamic.Mission.FLIGHT_PATH_ANGLE, val=np.zeros(nn), units='rad' + ) self.add_input( 'minimum_drag_coefficient', 0.0, @@ -83,17 +84,21 @@ def setup_partials(self): ) self.declare_partials( - 'lift_coefficient', [Dynamic.Mission.ALTITUDE, 'base_lift_coefficient'], - rows=rows_cols, cols=rows_cols + 'lift_coefficient', + [Dynamic.Mission.ALTITUDE, 'base_lift_coefficient'], + rows=rows_cols, + cols=rows_cols, ) self.declare_partials( 'lift_coefficient', [ - 'angle_of_attack', Dynamic.Mission.FLIGHT_PATH_ANGLE, 'minimum_drag_coefficient', + 'angle_of_attack', + Dynamic.Mission.FLIGHT_PATH_ANGLE, + 'minimum_drag_coefficient', 'base_drag_coefficient', ], - dependent=False + dependent=False, ) self.declare_partials( @@ -104,10 +109,14 @@ def setup_partials(self): self.declare_partials( 'drag_coefficient', [ - 'angle_of_attack', Dynamic.Mission.ALTITUDE, Dynamic.Mission.FLIGHT_PATH_ANGLE, - 'base_drag_coefficient', 'base_lift_coefficient' + 'angle_of_attack', + Dynamic.Mission.ALTITUDE, + Dynamic.Mission.FLIGHT_PATH_ANGLE, + 'base_drag_coefficient', + 'base_lift_coefficient', ], - rows=rows_cols, cols=rows_cols + rows=rows_cols, + cols=rows_cols, ) self.declare_partials('drag_coefficient', 'minimum_drag_coefficient', @@ -224,7 +233,9 @@ def compute_partials(self, inputs, J, discrete_inputs=None): (d_hf_alt * lift_coeff_factor_denom) - (height_factor * d_lcfd_alt) ) / lift_coeff_factor_denom**2 - J['lift_coefficient', Dynamic.Mission.ALTITUDE] = base_lift_coefficient * d_lcf_alt + J['lift_coefficient', Dynamic.Mission.ALTITUDE] = ( + base_lift_coefficient * d_lcf_alt + ) J['lift_coefficient', 'base_lift_coefficient'] = lift_coeff_factor # endregion lift_coefficient wrt [altitude, base_lift_coefficient] diff --git a/aviary/subsystems/aerodynamics/flops_based/induced_drag.py b/aviary/subsystems/aerodynamics/flops_based/induced_drag.py index 8ac3f4726..001fa60f8 100644 --- a/aviary/subsystems/aerodynamics/flops_based/induced_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/induced_drag.py @@ -28,12 +28,17 @@ def setup(self): # Simulation inputs self.add_input( - Dynamic.Mission.MACH, shape=(nn), units='unitless', desc="Mach number") + Dynamic.Atmosphere.MACH, shape=(nn), units='unitless', desc="Mach number" + ) self.add_input( - Dynamic.Mission.LIFT, shape=(nn), units="lbf", desc="Lift magnitude") + Dynamic.Vehicle.LIFT, shape=(nn), units="lbf", desc="Lift magnitude" + ) self.add_input( - Dynamic.Mission.STATIC_PRESSURE, np.ones(nn), units='lbf/ft**2', - desc='Static pressure at each evaulation point.') + Dynamic.Atmosphere.STATIC_PRESSURE, + np.ones(nn), + units='lbf/ft**2', + desc='Static pressure at each evaulation point.', + ) # Aero design inputs add_aviary_input(self, Aircraft.Wing.AREA, 0.0) @@ -53,8 +58,14 @@ def setup_partials(self): row_col = np.arange(nn) self.declare_partials( 'induced_drag_coeff', - [Dynamic.Mission.MACH, Dynamic.Mission.LIFT, Dynamic.Mission.STATIC_PRESSURE], - rows=row_col, cols=row_col) + [ + Dynamic.Atmosphere.MACH, + Dynamic.Vehicle.LIFT, + Dynamic.Atmosphere.STATIC_PRESSURE, + ], + rows=row_col, + cols=row_col, + ) wrt = [ Aircraft.Wing.AREA, @@ -143,9 +154,11 @@ def compute_partials(self, inputs, partials): dCDi_dAR = -CL ** 2 / (np.pi * AR ** 2 * span_efficiency) dCDi_dspan = -CL ** 2 / (np.pi * AR * span_efficiency ** 2) - partials['induced_drag_coeff', Dynamic.Mission.MACH] = dCDi_dCL * dCL_dmach - partials['induced_drag_coeff', Dynamic.Mission.LIFT] = dCDi_dCL * dCL_dL - partials['induced_drag_coeff', Dynamic.Mission.STATIC_PRESSURE] = dCDi_dCL * dCL_dP + partials['induced_drag_coeff', Dynamic.Atmosphere.MACH] = dCDi_dCL * dCL_dmach + partials['induced_drag_coeff', Dynamic.Vehicle.LIFT] = dCDi_dCL * dCL_dL + partials['induced_drag_coeff', Dynamic.Atmosphere.STATIC_PRESSURE] = ( + dCDi_dCL * dCL_dP + ) partials['induced_drag_coeff', Aircraft.Wing.ASPECT_RATIO] = dCDi_dAR partials['induced_drag_coeff', Aircraft.Wing.SPAN_EFFICIENCY_FACTOR] = 0.0 partials['induced_drag_coeff', Aircraft.Wing.SWEEP] = 0.0 @@ -207,17 +220,19 @@ def compute_partials(self, inputs, partials): dCDi_dCAYT = CL ** 2 dCDi_dCL = 2.0 * CAYT * CL - partials['induced_drag_coeff', Dynamic.Mission.MACH] += \ + partials['induced_drag_coeff', Dynamic.Atmosphere.MACH] += ( dCDi_dCL * dCL_dmach + dCDi_dCAYT * dCAYT_dmach - partials['induced_drag_coeff', Dynamic.Mission.LIFT] += dCDi_dCL * dCL_dL + ) + partials['induced_drag_coeff', Dynamic.Vehicle.LIFT] += dCDi_dCL * dCL_dL partials['induced_drag_coeff', Aircraft.Wing.ASPECT_RATIO] += ( dCDi_dCAYT * dTH_dAR * (dCAYT_dCOSA * dCOSA_dTH + dCAYT_dCOSB * dCOSB_dTH)) partials['induced_drag_coeff', Aircraft.Wing.SWEEP] += ( dCDi_dCAYT * dtansw_dsw * (dCAYT_dCOSA * dCOSA_dtansw + dCAYT_dCOSB * dCOSB_dtansw)) - partials['induced_drag_coeff', - Dynamic.Mission.STATIC_PRESSURE] += dCDi_dCL * dCL_dP + partials['induced_drag_coeff', Dynamic.Atmosphere.STATIC_PRESSURE] += ( + dCDi_dCL * dCL_dP + ) partials['induced_drag_coeff', Aircraft.Wing.TAPER_RATIO] += ( dCDi_dCAYT * dTH_dTR * (dCAYT_dCOSA * dCOSA_dTH + dCAYT_dCOSB * dCOSB_dTH)) diff --git a/aviary/subsystems/aerodynamics/flops_based/lift.py b/aviary/subsystems/aerodynamics/flops_based/lift.py index 7f126d1d7..0e1e59985 100644 --- a/aviary/subsystems/aerodynamics/flops_based/lift.py +++ b/aviary/subsystems/aerodynamics/flops_based/lift.py @@ -22,40 +22,47 @@ def setup(self): add_aviary_input(self, Aircraft.Wing.AREA, val=1., units='m**2') self.add_input( - Dynamic.Mission.DYNAMIC_PRESSURE, val=np.ones(nn), units='N/m**2', - desc='pressure caused by fluid motion') + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + val=np.ones(nn), + units='N/m**2', + desc='pressure caused by fluid motion', + ) self.add_input( name='cl', val=np.ones(nn), desc='current coefficient of lift', units='unitless') - self.add_output(name=Dynamic.Mission.LIFT, + self.add_output(name=Dynamic.Vehicle.LIFT, val=np.ones(nn), desc='Lift', units='N') def setup_partials(self): nn = self.options['num_nodes'] rows_cols = np.arange(nn) - self.declare_partials(Dynamic.Mission.LIFT, Aircraft.Wing.AREA) + self.declare_partials(Dynamic.Vehicle.LIFT, Aircraft.Wing.AREA) self.declare_partials( - Dynamic.Mission.LIFT, [Dynamic.Mission.DYNAMIC_PRESSURE, 'cl'], rows=rows_cols, cols=rows_cols) + Dynamic.Vehicle.LIFT, + [Dynamic.Atmosphere.DYNAMIC_PRESSURE, 'cl'], + rows=rows_cols, + cols=rows_cols, + ) def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): S = inputs[Aircraft.Wing.AREA] - q = inputs[Dynamic.Mission.DYNAMIC_PRESSURE] + q = inputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] CL = inputs['cl'] - outputs[Dynamic.Mission.LIFT] = q * S * CL + outputs[Dynamic.Vehicle.LIFT] = q * S * CL def compute_partials(self, inputs, partials, discrete_inputs=None): S = inputs[Aircraft.Wing.AREA] - q = inputs[Dynamic.Mission.DYNAMIC_PRESSURE] + q = inputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] CL = inputs['cl'] - partials[Dynamic.Mission.LIFT, Aircraft.Wing.AREA] = q * CL - partials[Dynamic.Mission.LIFT, Dynamic.Mission.DYNAMIC_PRESSURE] = S * CL - partials[Dynamic.Mission.LIFT, 'cl'] = q * S + partials[Dynamic.Vehicle.LIFT, Aircraft.Wing.AREA] = q * CL + partials[Dynamic.Vehicle.LIFT, Dynamic.Atmosphere.DYNAMIC_PRESSURE] = S * CL + partials[Dynamic.Vehicle.LIFT, 'cl'] = q * S class LiftEqualsWeight(om.ExplicitComponent): @@ -74,18 +81,21 @@ def setup(self): add_aviary_input(self, varname=Aircraft.Wing.AREA, val=1.0, units='m**2') self.add_input( - name=Dynamic.Mission.MASS, val=np.ones(nn), desc='current aircraft mass', + name=Dynamic.Vehicle.MASS, val=np.ones(nn), desc='current aircraft mass', units='kg') self.add_input( - Dynamic.Mission.DYNAMIC_PRESSURE, val=np.ones(nn), units='N/m**2', - desc='pressure caused by fluid motion') + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + val=np.ones(nn), + units='N/m**2', + desc='pressure caused by fluid motion', + ) self.add_output( name='cl', val=np.ones(nn), desc='current coefficient of lift', units='unitless') - self.add_output(name=Dynamic.Mission.LIFT, + self.add_output(name=Dynamic.Vehicle.LIFT, val=np.ones(nn), desc='Lift', units='N') def setup_partials(self): @@ -93,29 +103,36 @@ def setup_partials(self): row_col = np.arange(nn) self.declare_partials( - Dynamic.Mission.LIFT, Dynamic.Mission.MASS, rows=row_col, cols=row_col, val=grav_metric) + Dynamic.Vehicle.LIFT, Dynamic.Vehicle.MASS, rows=row_col, cols=row_col, val=grav_metric) self.declare_partials( - Dynamic.Mission.LIFT, [Aircraft.Wing.AREA, Dynamic.Mission.DYNAMIC_PRESSURE], dependent=False) + Dynamic.Vehicle.LIFT, + [Aircraft.Wing.AREA, Dynamic.Atmosphere.DYNAMIC_PRESSURE], + dependent=False, + ) self.declare_partials('cl', Aircraft.Wing.AREA) self.declare_partials( - 'cl', [Dynamic.Mission.MASS, Dynamic.Mission.DYNAMIC_PRESSURE], rows=row_col, cols=row_col) + 'cl', + [Dynamic.Vehicle.MASS, Dynamic.Atmosphere.DYNAMIC_PRESSURE], + rows=row_col, + cols=row_col, + ) def compute(self, inputs, outputs): S = inputs[Aircraft.Wing.AREA] - q = inputs[Dynamic.Mission.DYNAMIC_PRESSURE] - weight = grav_metric * inputs[Dynamic.Mission.MASS] + q = inputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] + weight = grav_metric * inputs[Dynamic.Vehicle.MASS] outputs['cl'] = weight / (q * S) - outputs[Dynamic.Mission.LIFT] = weight + outputs[Dynamic.Vehicle.LIFT] = weight def compute_partials(self, inputs, partials, discrete_inputs=None): S = inputs[Aircraft.Wing.AREA] - q = inputs[Dynamic.Mission.DYNAMIC_PRESSURE] - weight = grav_metric * inputs[Dynamic.Mission.MASS] + q = inputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] + weight = grav_metric * inputs[Dynamic.Vehicle.MASS] f = weight / q # df = 0. @@ -123,10 +140,10 @@ def compute_partials(self, inputs, partials, discrete_inputs=None): # dg = 1. partials['cl', Aircraft.Wing.AREA] = -f / g**2 - partials['cl', Dynamic.Mission.MASS] = grav_metric / (q * S) + partials['cl', Dynamic.Vehicle.MASS] = grav_metric / (q * S) f = weight / S # df = 0. g = q # dg = 1. - partials['cl', Dynamic.Mission.DYNAMIC_PRESSURE] = -f / g**2 + partials['cl', Dynamic.Atmosphere.DYNAMIC_PRESSURE] = -f / g**2 diff --git a/aviary/subsystems/aerodynamics/flops_based/lift_dependent_drag.py b/aviary/subsystems/aerodynamics/flops_based/lift_dependent_drag.py index 9c8140008..96c592634 100644 --- a/aviary/subsystems/aerodynamics/flops_based/lift_dependent_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/lift_dependent_drag.py @@ -22,12 +22,18 @@ def setup(self): nn = self.options["num_nodes"] # Simulation inputs - self.add_input(Dynamic.Mission.MACH, shape=( - nn), units='unitless', desc="Mach number") - self.add_input(Dynamic.Mission.LIFT, shape=( - nn), units="lbf", desc="Lift magnitude") - self.add_input(Dynamic.Mission.STATIC_PRESSURE, np.ones(nn), units='lbf/ft**2', - desc='Static pressure at each evaulation point.') + self.add_input( + Dynamic.Atmosphere.MACH, shape=(nn), units='unitless', desc="Mach number" + ) + self.add_input( + Dynamic.Vehicle.LIFT, shape=(nn), units="lbf", desc="Lift magnitude" + ) + self.add_input( + Dynamic.Atmosphere.STATIC_PRESSURE, + np.ones(nn), + units='lbf/ft**2', + desc='Static pressure at each evaulation point.', + ) # Aero design inputs add_aviary_input(self, Mission.Design.LIFT_COEFFICIENT, 0.0) @@ -47,8 +53,16 @@ def setup(self): def setup_partials(self): nn = self.options["num_nodes"] - self.declare_partials('CD', [Dynamic.Mission.MACH, Dynamic.Mission.LIFT, Dynamic.Mission.STATIC_PRESSURE], - rows=np.arange(nn), cols=np.arange(nn)) + self.declare_partials( + 'CD', + [ + Dynamic.Atmosphere.MACH, + Dynamic.Vehicle.LIFT, + Dynamic.Atmosphere.STATIC_PRESSURE, + ], + rows=np.arange(nn), + cols=np.arange(nn), + ) wrt = [Mission.Design.LIFT_COEFFICIENT, Mission.Design.MACH, @@ -286,9 +300,9 @@ def compute_partials(self, inputs, partials): dFCDP_dSW25 = dFCDP_dA * dA_dSW25 dCD_dSW25 = dDCDP_dFCDP * dFCDP_dSW25 - partials["CD", Dynamic.Mission.MACH] = dCD_dmach + dCD_dCL * ddelCL_dmach - partials["CD", Dynamic.Mission.LIFT] = dCD_dCL * ddelCL_dL - partials["CD", Dynamic.Mission.STATIC_PRESSURE] = dCD_dCL * ddelCL_dP + partials["CD", Dynamic.Atmosphere.MACH] = dCD_dmach + dCD_dCL * ddelCL_dmach + partials["CD", Dynamic.Vehicle.LIFT] = dCD_dCL * ddelCL_dL + partials["CD", Dynamic.Atmosphere.STATIC_PRESSURE] = dCD_dCL * ddelCL_dP partials["CD", Aircraft.Wing.AREA] = dCD_dCL * ddelCL_dSref partials["CD", Aircraft.Wing.ASPECT_RATIO] = dCD_dAR partials["CD", Aircraft.Wing.THICKNESS_TO_CHORD] = dCD_dTC @@ -298,9 +312,9 @@ def compute_partials(self, inputs, partials): partials["CD", Mission.Design.MACH] = -dCD_dmach if self.clamp_indices: - partials["CD", Dynamic.Mission.MACH][self.clamp_indices] = 0.0 - partials["CD", Dynamic.Mission.LIFT][self.clamp_indices] = 0.0 - partials["CD", Dynamic.Mission.STATIC_PRESSURE][self.clamp_indices] = 0.0 + partials["CD", Dynamic.Atmosphere.MACH][self.clamp_indices] = 0.0 + partials["CD", Dynamic.Vehicle.LIFT][self.clamp_indices] = 0.0 + partials["CD", Dynamic.Atmosphere.STATIC_PRESSURE][self.clamp_indices] = 0.0 partials["CD", Aircraft.Wing.AREA][self.clamp_indices] = 0.0 partials["CD", Aircraft.Wing.ASPECT_RATIO][self.clamp_indices] = 0.0 partials["CD", Aircraft.Wing.THICKNESS_TO_CHORD][self.clamp_indices] = 0.0 diff --git a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py index 957ad53ac..aa6d9373a 100644 --- a/aviary/subsystems/aerodynamics/flops_based/skin_friction.py +++ b/aviary/subsystems/aerodynamics/flops_based/skin_friction.py @@ -53,9 +53,10 @@ def setup(self): self.nc = nc = 2 + num_tails + num_fuselages + int(sum(num_engines)) # Simulation inputs - self.add_input(Dynamic.Mission.TEMPERATURE, np.ones(nn), units='degR') - self.add_input(Dynamic.Mission.STATIC_PRESSURE, np.ones(nn), units='lbf/ft**2') - self.add_input(Dynamic.Mission.MACH, np.ones(nn), units='unitless') + self.add_input(Dynamic.Atmosphere.TEMPERATURE, np.ones(nn), units='degR') + self.add_input(Dynamic.Atmosphere.STATIC_PRESSURE, + np.ones(nn), units='lbf/ft**2') + self.add_input(Dynamic.Atmosphere.MACH, np.ones(nn), units='unitless') # Aero subsystem inputs self.add_input('characteristic_lengths', np.ones(nc), units='ft') @@ -86,15 +87,45 @@ def setup_partials(self): col = np.arange(nn) cols = np.repeat(col, nc) self.declare_partials( - 'cf_iter', [Dynamic.Mission.TEMPERATURE, Dynamic.Mission.STATIC_PRESSURE, Dynamic.Mission.MACH], rows=row_col, cols=cols) + 'cf_iter', + [ + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + ], + rows=row_col, + cols=cols, + ) self.declare_partials( - 'wall_temp', [Dynamic.Mission.TEMPERATURE, Dynamic.Mission.STATIC_PRESSURE, Dynamic.Mission.MACH], rows=row_col, cols=cols) + 'wall_temp', + [ + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + ], + rows=row_col, + cols=cols, + ) self.declare_partials( - 'Re', [Dynamic.Mission.TEMPERATURE, Dynamic.Mission.STATIC_PRESSURE, Dynamic.Mission.MACH], rows=row_col, cols=cols) + 'Re', + [ + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + ], + rows=row_col, + cols=cols, + ) self.declare_partials( - 'skin_friction_coeff', [Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, Dynamic.Mission.MACH], - rows=row_col, cols=cols) + 'skin_friction_coeff', + [ + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, + ], + rows=row_col, + cols=cols, + ) col = np.arange(nc) cols = np.tile(col, nn) @@ -189,9 +220,9 @@ def linearize(self, inputs, outputs, partials): dreyn_dmach = np.einsum('i,j->ij', RE, length) dreyn_dlen = np.tile(RE * mach, nc).reshape((nc, nn)).T - partials['Re', Dynamic.Mission.STATIC_PRESSURE] = -dreyn_dp.ravel() - partials['Re', Dynamic.Mission.TEMPERATURE] = -dreyn_dT.ravel() - partials['Re', Dynamic.Mission.MACH] = -dreyn_dmach.ravel() + partials['Re', Dynamic.Atmosphere.STATIC_PRESSURE] = -dreyn_dp.ravel() + partials['Re', Dynamic.Atmosphere.TEMPERATURE] = -dreyn_dT.ravel() + partials['Re', Dynamic.Atmosphere.MACH] = -dreyn_dmach.ravel() partials['Re', 'characteristic_lengths'] = -dreyn_dlen.ravel() suth_const = T + 198.72 @@ -228,14 +259,14 @@ def linearize(self, inputs, outputs, partials): -0.5 - 1.5 * self.TAW * np.einsum('i,ij->ij', combined_const, wall_temp ** 2) / (CFL * den ** 2)) - partials['wall_temp', Dynamic.Mission.STATIC_PRESSURE] = ( + partials['wall_temp', Dynamic.Atmosphere.STATIC_PRESSURE] = ( np.einsum('ij,i->ij', dreswt_dcomb, dcomb_dp)).ravel() - partials['wall_temp', Dynamic.Mission.TEMPERATURE] = ( + partials['wall_temp', Dynamic.Atmosphere.TEMPERATURE] = ( np.einsum('ij,i->ij', dreswt_dcomb, dcomb_dT) + dreswt_dCFL * dCFL_dT).ravel() - partials['wall_temp', Dynamic.Mission.MACH] = ( - np.einsum('ij,i->ij', dreswt_dcomb, dcomb_dmach) - + dreswt_dCFL * dCFL_dmach).ravel() + partials['wall_temp', Dynamic.Atmosphere.MACH] = ( + np.einsum('ij,i->ij', dreswt_dcomb, dcomb_dmach) + dreswt_dCFL * dCFL_dmach + ).ravel() partials['wall_temp', 'wall_temp'] = ( dreswt_dCFL * dCFL_dwt + dreswt_dwt).ravel() partials['wall_temp', 'cf_iter'] = (dreswt_dCFL * dCFL_dcf).ravel() @@ -260,20 +291,22 @@ def linearize(self, inputs, outputs, partials): drescf_dRP = -2.0 * fact / (RP * np.log(RP * cf) ** 3) drescf_dcf = -2.0 * fact / (cf * np.log(RP * cf) ** 3) - 1.0 - partials['cf_iter', Dynamic.Mission.STATIC_PRESSURE] = ( + partials['cf_iter', Dynamic.Atmosphere.STATIC_PRESSURE] = ( drescf_dRP * dRP_dp).ravel() - partials['cf_iter', Dynamic.Mission.TEMPERATURE] = (drescf_dRP * dRP_dT).ravel() - partials['cf_iter', Dynamic.Mission.MACH] = (drescf_dRP * dRP_dmach).ravel() + partials['cf_iter', Dynamic.Atmosphere.TEMPERATURE] = ( + drescf_dRP * dRP_dT).ravel() + partials['cf_iter', Dynamic.Atmosphere.MACH] = (drescf_dRP * dRP_dmach).ravel() partials['cf_iter', 'characteristic_lengths'] = (drescf_dRP * dRP_dlen).ravel() partials['cf_iter', 'wall_temp'] = (drescf_dRP * dRP_dwt).ravel() partials['cf_iter', 'cf_iter'] = drescf_dcf.ravel() dskf_dwtr = outputs['cf_iter'] / wall_temp_ratio ** 2 - partials['skin_friction_coeff', Dynamic.Mission.TEMPERATURE] = ( + partials['skin_friction_coeff', Dynamic.Atmosphere.TEMPERATURE] = ( dskf_dwtr * dwtr_dT).ravel() - partials['skin_friction_coeff', Dynamic.Mission.MACH] = np.einsum( - 'ij,i->ij', dskf_dwtr, dwtr_dmach).ravel() + partials['skin_friction_coeff', Dynamic.Atmosphere.MACH] = np.einsum( + 'ij,i->ij', dskf_dwtr, dwtr_dmach + ).ravel() partials['skin_friction_coeff', 'wall_temp'] = np.einsum( 'ij,i->ij', dskf_dwtr, dwtr_dwt).ravel() partials['skin_friction_coeff', 'cf_iter'] = (- 1.0 / wall_temp_ratio).ravel() diff --git a/aviary/subsystems/aerodynamics/flops_based/solved_alpha_group.py b/aviary/subsystems/aerodynamics/flops_based/solved_alpha_group.py index ace5bb457..2e3e058d0 100644 --- a/aviary/subsystems/aerodynamics/flops_based/solved_alpha_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/solved_alpha_group.py @@ -40,8 +40,10 @@ def initialize(self): self.options.declare('structured', types=bool, default=True, desc='Flag that sets if data is a structured grid') - self.options.declare('extrapolate', default=True, desc='Flag that sets if drag ' - 'data can be extrapolated') + self.options.declare( + 'extrapolate', default=True, + desc='Flag that sets if drag ' + 'data can be extrapolated') def setup(self): options = self.options @@ -52,9 +54,14 @@ def setup(self): extrapolate = options['extrapolate'] self.add_subsystem( - 'DynamicPressure', DynamicPressure(num_nodes=nn), - promotes_inputs=[Dynamic.Mission.MACH, Dynamic.Mission.STATIC_PRESSURE], - promotes_outputs=[Dynamic.Mission.DYNAMIC_PRESSURE]) + 'DynamicPressure', + DynamicPressure(num_nodes=nn), + promotes_inputs=[ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.STATIC_PRESSURE, + ], + promotes_outputs=[Dynamic.Atmosphere.DYNAMIC_PRESSURE], + ) aero = TabularCruiseAero(num_nodes=nn, aero_data=aero_data, @@ -68,12 +75,19 @@ def setup(self): else: extra_promotes = [] - self.add_subsystem("tabular_aero", aero, - promotes_inputs=[Dynamic.Mission.ALTITUDE, Dynamic.Mission.MACH, - Aircraft.Wing.AREA, Dynamic.Mission.MACH, - Dynamic.Mission.DYNAMIC_PRESSURE] - + extra_promotes, - promotes_outputs=['CD', Dynamic.Mission.LIFT, Dynamic.Mission.DRAG]) + self.add_subsystem( + "tabular_aero", + aero, + promotes_inputs=[ + Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.MACH, + Aircraft.Wing.AREA, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + ] + + extra_promotes, + promotes_outputs=['CD', Dynamic.Vehicle.LIFT, Dynamic.Vehicle.DRAG], + ) balance = self.add_subsystem('balance', om.BalanceComp()) balance.add_balance('alpha', val=np.ones(nn), units='deg', res_ref=1.0e6) @@ -81,17 +95,21 @@ def setup(self): self.connect('balance.alpha', 'tabular_aero.alpha') self.connect('needed_lift.lift_resid', 'balance.lhs:alpha') - self.add_subsystem('needed_lift', - om.ExecComp('lift_resid = mass * grav_metric - computed_lift', - grav_metric={'val': grav_metric}, - mass={'units': 'kg', 'shape': nn}, - computed_lift={'units': 'N', 'shape': nn}, - lift_resid={'shape': nn}, - has_diag_partials=True, - ), - promotes_inputs=[('mass', Dynamic.Mission.MASS), - ('computed_lift', Dynamic.Mission.LIFT)] - ) + self.add_subsystem( + 'needed_lift', + om.ExecComp( + 'lift_resid = mass * grav_metric - computed_lift', + grav_metric={'val': grav_metric}, + mass={'units': 'kg', 'shape': nn}, + computed_lift={'units': 'N', 'shape': nn}, + lift_resid={'shape': nn}, + has_diag_partials=True, + ), + promotes_inputs=[ + ('mass', Dynamic.Vehicle.MASS), + ('computed_lift', Dynamic.Vehicle.LIFT), + ], + ) self.linear_solver = om.DirectSolver() newton = self.nonlinear_solver = om.NewtonSolver(solve_subsystems=True) diff --git a/aviary/subsystems/aerodynamics/flops_based/tabular_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/tabular_aero_group.py index 936495c02..a168b6042 100644 --- a/aviary/subsystems/aerodynamics/flops_based/tabular_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/tabular_aero_group.py @@ -4,8 +4,7 @@ from pathlib import Path from aviary.subsystems.aerodynamics.flops_based.drag import TotalDrag as Drag -from aviary.subsystems.aerodynamics.flops_based.lift import \ - LiftEqualsWeight as CL +from aviary.subsystems.aerodynamics.flops_based.lift import LiftEqualsWeight as CL from aviary.utils.csv_data_file import read_data_file from aviary.utils.data_interpolator_builder import build_data_interpolator from aviary.utils.functions import get_path @@ -17,14 +16,21 @@ # spaces are replaced with underscores when data tables are read) # "Repeated" aliases allows variables with different cases to match with desired # all-lowercase name -aliases = {Dynamic.Mission.ALTITUDE: ['h', 'alt', 'altitude'], - Dynamic.Mission.MACH: ['m', 'mach'], - 'lift_coefficient': ['cl', 'coefficient_of_lift', 'lift_coefficient'], - 'lift_dependent_drag_coefficient': ['cdi', 'lift_dependent_drag_coefficient', - 'lift-dependent_drag_coefficient'], - 'zero_lift_drag_coefficient': ['cd0', 'zero_lift_drag_coefficient', - 'zero-lift_drag_coefficient'], - } +aliases = { + Dynamic.Mission.ALTITUDE: ['h', 'alt', 'altitude'], + Dynamic.Atmosphere.MACH: ['m', 'mach'], + 'lift_coefficient': ['cl', 'coefficient_of_lift', 'lift_coefficient'], + 'lift_dependent_drag_coefficient': [ + 'cdi', + 'lift_dependent_drag_coefficient', + 'lift-dependent_drag_coefficient', + ], + 'zero_lift_drag_coefficient': [ + 'cd0', + 'zero_lift_drag_coefficient', + 'zero-lift_drag_coefficient', + ], +} class TabularAeroGroup(om.Group): @@ -50,16 +56,26 @@ def initialize(self): options.declare('num_nodes', types=int) - options.declare('CD0_data', types=(str, Path, NamedValues), - desc='Data file or NamedValues object containing zero-lift drag ' - 'coefficient table.') + options.declare( + 'CD0_data', + types=(str, Path, NamedValues), + desc='Data file or NamedValues object containing zero-lift drag ' + 'coefficient table.', + ) - options.declare('CDI_data', types=(str, Path, NamedValues), - desc='Data file or NamedValues object containing lift-dependent ' - 'drag coefficient table.') + options.declare( + 'CDI_data', + types=(str, Path, NamedValues), + desc='Data file or NamedValues object containing lift-dependent ' + 'drag coefficient table.', + ) - options.declare('structured', types=bool, default=True, - desc='Flag that sets if data is a structured grid.') + options.declare( + 'structured', + types=bool, + default=True, + desc='Flag that sets if data is a structured grid.', + ) options.declare( 'connect_training_data', @@ -113,26 +129,33 @@ def setup(self): # add subsystems self.add_subsystem( - Dynamic.Mission.DYNAMIC_PRESSURE, _DynamicPressure(num_nodes=nn), - promotes_inputs=[Dynamic.Mission.VELOCITY, Dynamic.Mission.DENSITY], - promotes_outputs=[Dynamic.Mission.DYNAMIC_PRESSURE]) + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + _DynamicPressure(num_nodes=nn), + promotes_inputs=[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.DENSITY], + promotes_outputs=[Dynamic.Atmosphere.DYNAMIC_PRESSURE], + ) self.add_subsystem( - 'lift_coefficient', CL(num_nodes=nn), - promotes_inputs=[Dynamic.Mission.MASS, - Aircraft.Wing.AREA, Dynamic.Mission.DYNAMIC_PRESSURE], - promotes_outputs=[('cl', 'lift_coefficient'), Dynamic.Mission.LIFT]) + 'lift_coefficient', + CL(num_nodes=nn), + promotes_inputs=[ + Dynamic.Vehicle.MASS, + Aircraft.Wing.AREA, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + ], + promotes_outputs=[('cl', 'lift_coefficient'), Dynamic.Vehicle.LIFT], + ) - self.add_subsystem('CD0_interp', CD0_interp, - promotes_inputs=['*'], - promotes_outputs=['*']) + self.add_subsystem( + 'CD0_interp', CD0_interp, promotes_inputs=['*'], promotes_outputs=['*'] + ) - self.add_subsystem('CDI_interp', CDI_interp, - promotes_inputs=['*'], - promotes_outputs=['*']) + self.add_subsystem( + 'CDI_interp', CDI_interp, promotes_inputs=['*'], promotes_outputs=['*'] + ) self.add_subsystem( - Dynamic.Mission.DRAG, + Dynamic.Vehicle.DRAG, Drag(num_nodes=nn), promotes_inputs=[ Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, @@ -142,10 +165,10 @@ def setup(self): Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, ('CDI', 'lift_dependent_drag_coefficient'), ('CD0', 'zero_lift_drag_coefficient'), - Dynamic.Mission.MACH, - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, ], - promotes_outputs=['CD', Dynamic.Mission.DRAG], + promotes_outputs=['CD', Dynamic.Vehicle.DRAG], ) @@ -161,11 +184,14 @@ def setup(self): nn = self.options['num_nodes'] self.add_input(Dynamic.Mission.VELOCITY, val=np.ones(nn), units='m/s') - self.add_input(Dynamic.Mission.DENSITY, val=np.ones(nn), units='kg/m**3') + self.add_input(Dynamic.Atmosphere.DENSITY, val=np.ones(nn), units='kg/m**3') self.add_output( - Dynamic.Mission.DYNAMIC_PRESSURE, val=np.ones(nn), units='N/m**2', - desc='pressure caused by fluid motion') + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + val=np.ones(nn), + units='N/m**2', + desc='pressure caused by fluid motion', + ) def setup_partials(self): nn = self.options['num_nodes'] @@ -173,20 +199,25 @@ def setup_partials(self): rows_cols = np.arange(nn) self.declare_partials( - Dynamic.Mission.DYNAMIC_PRESSURE, [ - Dynamic.Mission.VELOCITY, Dynamic.Mission.DENSITY], - rows=rows_cols, cols=rows_cols) + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + [Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.DENSITY], + rows=rows_cols, + cols=rows_cols, + ) def compute(self, inputs, outputs): TAS = inputs[Dynamic.Mission.VELOCITY] - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] - outputs[Dynamic.Mission.DYNAMIC_PRESSURE] = 0.5 * rho * TAS**2 + outputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] = 0.5 * rho * TAS**2 def compute_partials(self, inputs, partials): TAS = inputs[Dynamic.Mission.VELOCITY] - rho = inputs[Dynamic.Mission.DENSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] - partials[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.VELOCITY] = rho * TAS - partials[Dynamic.Mission.DYNAMIC_PRESSURE, - Dynamic.Mission.DENSITY] = 0.5 * TAS**2 + partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Mission.VELOCITY] = ( + rho * TAS + ) + partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.DENSITY] = ( + 0.5 * TAS**2 + ) diff --git a/aviary/subsystems/aerodynamics/flops_based/takeoff_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/takeoff_aero_group.py index 85e2186b0..9d1cde015 100644 --- a/aviary/subsystems/aerodynamics/flops_based/takeoff_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/takeoff_aero_group.py @@ -121,10 +121,13 @@ def setup(self): } inputs = [ - 'angle_of_attack', Dynamic.Mission.ALTITUDE, Dynamic.Mission.FLIGHT_PATH_ANGLE, + 'angle_of_attack', + Dynamic.Mission.ALTITUDE, + Dynamic.Mission.FLIGHT_PATH_ANGLE, ('minimum_drag_coefficient', Mission.Takeoff.DRAG_COEFFICIENT_MIN), - Aircraft.Wing.ASPECT_RATIO, Aircraft.Wing.HEIGHT, - Aircraft.Wing.SPAN + Aircraft.Wing.ASPECT_RATIO, + Aircraft.Wing.HEIGHT, + Aircraft.Wing.SPAN, ] self.add_subsystem( @@ -179,8 +182,8 @@ def setup(self): self.connect('ground_effect.drag_coefficient', 'ground_effect_drag') self.connect('climb_drag_coefficient', 'aero_forces.CD') - inputs = [Dynamic.Mission.DYNAMIC_PRESSURE, Aircraft.Wing.AREA] - outputs = [Dynamic.Mission.LIFT, Dynamic.Mission.DRAG] + inputs = [Dynamic.Atmosphere.DYNAMIC_PRESSURE, Aircraft.Wing.AREA] + outputs = [Dynamic.Vehicle.LIFT, Dynamic.Vehicle.DRAG] self.add_subsystem( 'aero_forces', AeroForces(num_nodes=nn), 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 f6d4de0be..350d10b6d 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 @@ -82,20 +82,22 @@ def test_basic_large_single_aisle_1(self): promotes=['*'] ) + prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) + prob.setup(force_alloc_complex=True) prob.set_solver_print(level=2) # Mission params - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P, units='lbf/ft**2') - prob.set_val(Dynamic.Mission.TEMPERATURE, val=T, units='degR') - prob.set_val(Dynamic.Mission.MASS, val=mass, units='lbm') + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P, units='lbf/ft**2') + prob.set_val(Dynamic.Atmosphere.TEMPERATURE, val=T, units='degR') + prob.set_val(Dynamic.Vehicle.MASS, val=mass, units='lbm') set_aviary_initial_values(prob, flops_inputs) prob.run_model() - D = prob.get_val(Dynamic.Mission.DRAG, 'lbf') + D = prob.get_val(Dynamic.Vehicle.DRAG, 'lbf') CD = D / (Sref * 0.5 * 1.4 * P * mach ** 2) data = np.array([ @@ -194,19 +196,21 @@ def test_n3cc_drag(self): promotes=['*'] ) + prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) + prob.setup() # Mission params - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P, units='lbf/ft**2') - prob.set_val(Dynamic.Mission.TEMPERATURE, val=T, units='degR') - prob.set_val(Dynamic.Mission.MASS, val=mass, units='lbm') + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P, units='lbf/ft**2') + prob.set_val(Dynamic.Atmosphere.TEMPERATURE, val=T, units='degR') + prob.set_val(Dynamic.Vehicle.MASS, val=mass, units='lbm') set_aviary_initial_values(prob, flops_inputs) prob.run_model() - D = prob.get_val(Dynamic.Mission.DRAG, 'lbf') + D = prob.get_val(Dynamic.Vehicle.DRAG, 'lbf') CD = D / (Sref * 0.5 * 1.4 * P * mach ** 2) data = np.array([ @@ -305,19 +309,21 @@ def test_large_single_aisle_2_drag(self): promotes=['*'] ) + prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) + prob.setup() # Mission params - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P, units='lbf/ft**2') - prob.set_val(Dynamic.Mission.TEMPERATURE, val=T, units='degR') - prob.set_val(Dynamic.Mission.MASS, val=mass, units='lbm') + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P, units='lbf/ft**2') + prob.set_val(Dynamic.Atmosphere.TEMPERATURE, val=T, units='degR') + prob.set_val(Dynamic.Vehicle.MASS, val=mass, units='lbm') set_aviary_initial_values(prob, flops_inputs) prob.run_model() - D = prob.get_val(Dynamic.Mission.DRAG, 'lbf') + D = prob.get_val(Dynamic.Vehicle.DRAG, 'lbf') CD = D / (Sref * 0.5 * 1.4 * P * mach ** 2) data = np.array([ diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_drag.py b/aviary/subsystems/aerodynamics/flops_based/test/test_drag.py index 476c5cac3..9fe79ab54 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_drag.py @@ -44,14 +44,14 @@ def test_case(self, case_name): # dynamic pressure = 4 digits precision # drag coefficient = 5 digits precision mission_keys = ( - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, 'CD_prescaled', 'CD', - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, ) # drag = 4 digits precision - outputs_keys = (Dynamic.Mission.DRAG,) + outputs_keys = (Dynamic.Vehicle.DRAG,) # using lowest precision from all available data should "always" work # - will a higher precision comparison work? find a practical tolerance that fits @@ -61,7 +61,7 @@ def test_case(self, case_name): prob = om.Problem() model = prob.model - q, _ = mission_data.get_item(Dynamic.Mission.DYNAMIC_PRESSURE) + q, _ = mission_data.get_item(Dynamic.Atmosphere.DYNAMIC_PRESSURE) nn = len(q) model.add_subsystem('simple_drag', SimpleDrag(num_nodes=nn), promotes=['*']) model.add_subsystem('simple_cd', SimpleCD(num_nodes=nn), promotes=['*']) @@ -95,7 +95,7 @@ def test_case(self, case_name): assert_near_equal(prob.get_val("CD"), mission_simple_CD[case_name], 1e-6) assert_near_equal( - prob.get_val(Dynamic.Mission.DRAG), mission_simple_drag[case_name], 1e-6 + prob.get_val(Dynamic.Vehicle.DRAG), mission_simple_drag[case_name], 1e-6 ) @@ -121,14 +121,14 @@ def test_case(self, case_name): # dynamic pressure = 4 digits precision # drag coefficient = 5 digits precision mission_keys = ( - Dynamic.Mission.DYNAMIC_PRESSURE, - Dynamic.Mission.MACH, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.MACH, 'CD0', 'CDI', ) # drag = 4 digits precision - outputs_keys = ('CD_prescaled', 'CD', Dynamic.Mission.DRAG) + outputs_keys = ('CD_prescaled', 'CD', Dynamic.Vehicle.DRAG) # using lowest precision from all available data should "always" work # - will a higher precision comparison work? find a practical tolerance that fits @@ -138,7 +138,7 @@ def test_case(self, case_name): prob = om.Problem() model = prob.model - q, _ = mission_data.get_item(Dynamic.Mission.DYNAMIC_PRESSURE) + q, _ = mission_data.get_item(Dynamic.Atmosphere.DYNAMIC_PRESSURE) nn = len(q) model.add_subsystem('total_drag', TotalDrag(num_nodes=nn), promotes=['*']) @@ -171,7 +171,7 @@ def test_case(self, case_name): assert_near_equal(prob.get_val("CD"), mission_total_CD[case_name], 1e-6) assert_near_equal( - prob.get_val(Dynamic.Mission.DRAG), mission_total_drag[case_name], 1e-6 + prob.get_val(Dynamic.Vehicle.DRAG), mission_total_drag[case_name], 1e-6 ) @@ -193,7 +193,7 @@ def test_derivs(self): 'computed_drag', ComputedDrag(num_nodes=nn), promotes_inputs=['*'], - promotes_outputs=['CD', Dynamic.Mission.DRAG], + promotes_outputs=['CD', Dynamic.Vehicle.DRAG], ) prob.setup(force_alloc_complex=True) @@ -202,14 +202,14 @@ def test_derivs(self): prob.set_val('pressure_drag_coeff', 0.01 * cdp) prob.set_val('compress_drag_coeff', 0.01 * cdc) prob.set_val('induced_drag_coeff', 0.01 * cdi) - prob.set_val(Dynamic.Mission.MACH, M) + prob.set_val(Dynamic.Atmosphere.MACH, M) prob.set_val(Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, 0.7) prob.set_val(Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, 0.3) prob.set_val(Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, 1.4) prob.set_val(Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, 1.1) prob.set_val(Aircraft.Wing.AREA, 1370, units="ft**2") - prob.set_val(Dynamic.Mission.DYNAMIC_PRESSURE, [206.0, 205.6], 'lbf/ft**2') + prob.set_val(Dynamic.Atmosphere.DYNAMIC_PRESSURE, [206.0, 205.6], 'lbf/ft**2') prob.run_model() @@ -217,7 +217,7 @@ def test_derivs(self): assert_check_partials(derivs, atol=1e-12, rtol=1e-12) assert_near_equal(prob.get_val("CD"), [0.0249732, 0.0297451], 1e-6) - assert_near_equal(prob.get_val(Dynamic.Mission.DRAG), [31350.8, 37268.8], 1e-6) + assert_near_equal(prob.get_val(Dynamic.Vehicle.DRAG), [31350.8, 37268.8], 1e-6) # region - mission test data taken from the baseline FLOPS output for each case @@ -267,19 +267,19 @@ def _add_drag_coefficients( key = 'LargeSingleAisle1FLOPS' mission_test_data[key] = _mission_data = AviaryValues() _mission_data.set_val( - Dynamic.Mission.DYNAMIC_PRESSURE, np.array([206.0, 205.6, 205.4]), 'lbf/ft**2' + Dynamic.Atmosphere.DYNAMIC_PRESSURE, np.array([206.0, 205.6, 205.4]), 'lbf/ft**2' ) _mission_data.set_val( - Dynamic.Mission.MASS, np.array([176751.0, 176400.0, 176185.0]), 'lbm' + Dynamic.Vehicle.MASS, np.array([176751.0, 176400.0, 176185.0]), 'lbm' ) -_mission_data.set_val(Dynamic.Mission.DRAG, np.array([9350.0, 9333.0, 9323.0]), 'lbf') +_mission_data.set_val(Dynamic.Vehicle.DRAG, np.array([9350.0, 9333.0, 9323.0]), 'lbf') M = np.array([0.7750, 0.7750, 0.7750]) CD_scaled = np.array([0.03313, 0.03313, 0.03313]) CD0_scaled = np.array([0.02012, 0.02013, 0.02013]) CDI_scaled = np.array([0.01301, 0.01301, 0.01300]) -_mission_data.set_val(Dynamic.Mission.MACH, M) +_mission_data.set_val(Dynamic.Atmosphere.MACH, M) _add_drag_coefficients(key, _mission_data, M, CD_scaled, CD0_scaled, CDI_scaled) mission_simple_CD[key] = np.array([0.03313, 0.03313, 0.03313]) @@ -290,17 +290,17 @@ def _add_drag_coefficients( key = 'LargeSingleAisle2FLOPS' mission_test_data[key] = _mission_data = AviaryValues() _mission_data.set_val( - Dynamic.Mission.DYNAMIC_PRESSURE, [215.4, 215.4, 215.4], 'lbf/ft**2' + Dynamic.Atmosphere.DYNAMIC_PRESSURE, [215.4, 215.4, 215.4], 'lbf/ft**2' ) -_mission_data.set_val(Dynamic.Mission.MASS, [169730.0, 169200.0, 167400.0], 'lbm') -_mission_data.set_val(Dynamic.Mission.DRAG, [9542.0, 9512.0, 9411.0], 'lbf') +_mission_data.set_val(Dynamic.Vehicle.MASS, [169730.0, 169200.0, 167400.0], 'lbm') +_mission_data.set_val(Dynamic.Vehicle.DRAG, [9542.0, 9512.0, 9411.0], 'lbf') M = np.array([0.7850, 0.7850, 0.7850]) CD_scaled = np.array([0.03304, 0.03293, 0.03258]) CD0_scaled = np.array([0.02016, 0.02016, 0.02016]) CDI_scaled = np.array([0.01288, 0.01277, 0.01242]) -_mission_data.set_val(Dynamic.Mission.MACH, M) +_mission_data.set_val(Dynamic.Atmosphere.MACH, M) _add_drag_coefficients(key, _mission_data, M, CD_scaled, CD0_scaled, CDI_scaled) mission_simple_CD[key] = np.array([0.03304, 0.03293, 0.03258]) @@ -311,17 +311,17 @@ def _add_drag_coefficients( key = 'N3CC' mission_test_data[key] = _mission_data = AviaryValues() _mission_data.set_val( - Dynamic.Mission.DYNAMIC_PRESSURE, [208.4, 288.5, 364.0], 'lbf/ft**2' + Dynamic.Atmosphere.DYNAMIC_PRESSURE, [208.4, 288.5, 364.0], 'lbf/ft**2' ) -_mission_data.set_val(Dynamic.Mission.MASS, [128777.0, 128721.0, 128667.0], 'lbm') -_mission_data.set_val(Dynamic.Mission.DRAG, [5837.0, 6551.0, 7566.0], 'lbf') +_mission_data.set_val(Dynamic.Vehicle.MASS, [128777.0, 128721.0, 128667.0], 'lbm') +_mission_data.set_val(Dynamic.Vehicle.DRAG, [5837.0, 6551.0, 7566.0], 'lbf') M = np.array([0.4522, 0.5321, 0.5985]) CD_scaled = np.array([0.02296, 0.01861, 0.01704]) CD0_scaled = np.array([0.01611, 0.01569, 0.01556]) CDI_scaled = np.array([0.00806, 0.00390, 0.00237]) -_mission_data.set_val(Dynamic.Mission.MACH, M) +_mission_data.set_val(Dynamic.Atmosphere.MACH, M) _add_drag_coefficients(key, _mission_data, M, CD_scaled, CD0_scaled, CDI_scaled) # endregion - mission test data taken from the baseline FLOPS output for each case diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_ground_effect.py b/aviary/subsystems/aerodynamics/flops_based/test/test_ground_effect.py index 2262993a7..d94fa8139 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_ground_effect.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_ground_effect.py @@ -61,17 +61,19 @@ def make_problem(): height = (8., 'ft') span = (34., 'm') - inputs = AviaryValues({ - 'angle_of_attack': (np.array([0., 2., 6]), 'deg'), - Dynamic.Mission.ALTITUDE: (np.array([100.0, 132, 155]), 'm'), - Dynamic.Mission.FLIGHT_PATH_ANGLE: (np.array([0., 0.5, 1.0]), 'deg'), - 'minimum_drag_coefficient': minimum_drag_coefficient, - 'base_lift_coefficient': base_lift_coefficient, - 'base_drag_coefficient': base_drag_coefficient, - Aircraft.Wing.ASPECT_RATIO: aspect_ratio, - Aircraft.Wing.HEIGHT: height, - Aircraft.Wing.SPAN: span - }) + inputs = AviaryValues( + { + 'angle_of_attack': (np.array([0.0, 2.0, 6]), 'deg'), + Dynamic.Mission.ALTITUDE: (np.array([100.0, 132, 155]), 'm'), + Dynamic.Mission.FLIGHT_PATH_ANGLE: (np.array([0.0, 0.5, 1.0]), 'deg'), + 'minimum_drag_coefficient': minimum_drag_coefficient, + 'base_lift_coefficient': base_lift_coefficient, + 'base_drag_coefficient': base_drag_coefficient, + Aircraft.Wing.ASPECT_RATIO: aspect_ratio, + Aircraft.Wing.HEIGHT: height, + Aircraft.Wing.SPAN: span, + } + ) ground_effect = GroundEffect(num_nodes=nn, ground_altitude=ground_altitude) 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 8d5a34d1e..dd990ccdf 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_induced_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_induced_drag.py @@ -30,9 +30,9 @@ def test_derivs(self): num_nodes=nn, aviary_options=AviaryValues(options)), promotes=['*']) prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.LIFT, val=lift) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P) + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Vehicle.LIFT, val=lift) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P) prob.set_val(Aircraft.Wing.AREA, val=Sref) prob.set_val(Aircraft.Wing.SWEEP, val=-25.03) prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.278) @@ -69,9 +69,9 @@ def test_derivs_span_eff_redux(self): num_nodes=nn, aviary_options=AviaryValues(options)), promotes=['*']) prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.LIFT, val=lift) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P) + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Vehicle.LIFT, val=lift) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P) prob.set_val(Aircraft.Wing.AREA, val=Sref) prob.set_val(Aircraft.Wing.SWEEP, val=-25.10) prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.312) @@ -98,9 +98,9 @@ def test_derivs_span_eff_redux(self): num_nodes=nn, aviary_options=AviaryValues(options)), promotes=['*']) prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.LIFT, val=lift) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P) + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Vehicle.LIFT, val=lift) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P) prob.set_val(Aircraft.Wing.AREA, val=Sref) prob.set_val(Aircraft.Wing.SWEEP, val=-25.10) prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.312) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_lift.py b/aviary/subsystems/aerodynamics/flops_based/test/test_lift.py index 65137fec3..790bae080 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_lift.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_lift.py @@ -31,10 +31,10 @@ def test_case(self, case_name): # dynamic pressure = 4 digits precision # lift coefficient = 5 digits precision - mission_keys = (Dynamic.Mission.DYNAMIC_PRESSURE, 'cl') + mission_keys = (Dynamic.Atmosphere.DYNAMIC_PRESSURE, 'cl') # lift = 6 digits precision - outputs_keys = (Dynamic.Mission.LIFT,) + outputs_keys = (Dynamic.Vehicle.LIFT,) # use lowest precision from all available data tol = 1e-4 @@ -42,7 +42,7 @@ def test_case(self, case_name): prob = om.Problem() model = prob.model - q, _ = mission_data.get_item(Dynamic.Mission.DYNAMIC_PRESSURE) + q, _ = mission_data.get_item(Dynamic.Atmosphere.DYNAMIC_PRESSURE) nn = len(q) model.add_subsystem('simple_lift', SimpleLift(num_nodes=nn), promotes=['*']) @@ -74,7 +74,7 @@ def test_case(self, case_name): assert_check_partials(data, atol=2.5e-10, rtol=1e-12) assert_near_equal( - prob.get_val(Dynamic.Mission.LIFT), mission_simple_data[case_name], 1e-6 + prob.get_val(Dynamic.Vehicle.LIFT), mission_simple_data[case_name], 1e-6 ) @@ -91,11 +91,11 @@ def test_case(self, case_name): # dynamic pressure = 4 digits precision # mass = 6 digits precision - mission_keys = (Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.MASS) + mission_keys = (Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Vehicle.MASS) # lift coefficient = 5 digits precision # lift = 6 digits precision - outputs_keys = ('cl', Dynamic.Mission.LIFT) + outputs_keys = ('cl', Dynamic.Vehicle.LIFT) # use lowest precision from all available data tol = 1e-4 @@ -103,7 +103,7 @@ def test_case(self, case_name): prob = om.Problem() model = prob.model - q, _ = mission_data.get_item(Dynamic.Mission.DYNAMIC_PRESSURE) + q, _ = mission_data.get_item(Dynamic.Atmosphere.DYNAMIC_PRESSURE) nn = len(q) model.add_subsystem( @@ -138,7 +138,7 @@ def test_case(self, case_name): assert_check_partials(data, atol=2.5e-10, rtol=1e-12) assert_near_equal( - prob.get_val(Dynamic.Mission.LIFT), mission_equal_data[case_name], 1e-6 + prob.get_val(Dynamic.Vehicle.LIFT), mission_equal_data[case_name], 1e-6 ) @@ -152,31 +152,31 @@ def test_case(self, case_name): mission_test_data['LargeSingleAisle1FLOPS'] = _mission_data = AviaryValues() _mission_data.set_val( - Dynamic.Mission.DYNAMIC_PRESSURE, [206.0, 205.6, 205.4], 'lbf/ft**2' + Dynamic.Atmosphere.DYNAMIC_PRESSURE, [206.0, 205.6, 205.4], 'lbf/ft**2' ) _mission_data.set_val('cl', [0.62630, 0.62623, 0.62619]) -_mission_data.set_val(Dynamic.Mission.LIFT, [176751.0, 176400.0, 176185.0], 'lbf') -_mission_data.set_val(Dynamic.Mission.MASS, [176751.0, 176400.0, 176185.0], 'lbm') +_mission_data.set_val(Dynamic.Vehicle.LIFT, [176751.0, 176400.0, 176185.0], 'lbf') +_mission_data.set_val(Dynamic.Vehicle.MASS, [176751.0, 176400.0, 176185.0], 'lbm') mission_simple_data['LargeSingleAisle1FLOPS'] = [786242.68, 784628.29, 783814.96] mission_equal_data['LargeSingleAisle1FLOPS'] = [786227.62, 784666.29, 783709.93] mission_test_data['LargeSingleAisle2FLOPS'] = _mission_data = AviaryValues() _mission_data.set_val( - Dynamic.Mission.DYNAMIC_PRESSURE, [215.4, 215.4, 215.4], 'lbf/ft**2' + Dynamic.Atmosphere.DYNAMIC_PRESSURE, [215.4, 215.4, 215.4], 'lbf/ft**2' ) _mission_data.set_val('cl', [0.58761, 0.58578, 0.57954]) -_mission_data.set_val(Dynamic.Mission.LIFT, [169730.0, 169200.0, 167400.0], 'lbf') -_mission_data.set_val(Dynamic.Mission.MASS, [169730.0, 169200.0, 167400.0], 'lbm') +_mission_data.set_val(Dynamic.Vehicle.LIFT, [169730.0, 169200.0, 167400.0], 'lbf') +_mission_data.set_val(Dynamic.Vehicle.MASS, [169730.0, 169200.0, 167400.0], 'lbm') mission_simple_data['LargeSingleAisle2FLOPS'] = [755005.42, 752654.10, 744636.48] mission_equal_data['LargeSingleAisle2FLOPS'] = [754996.65, 752639.10, 744632.30] mission_test_data['N3CC'] = _mission_data = AviaryValues() _mission_data.set_val( - Dynamic.Mission.DYNAMIC_PRESSURE, [208.4, 288.5, 364.0], 'lbf/ft**2' + Dynamic.Atmosphere.DYNAMIC_PRESSURE, [208.4, 288.5, 364.0], 'lbf/ft**2' ) _mission_data.set_val('cl', [0.50651, 0.36573, 0.28970]) -_mission_data.set_val(Dynamic.Mission.LIFT, [128777.0, 128721.0, 128667.0], 'lbf') -_mission_data.set_val(Dynamic.Mission.MASS, [128777.0, 128721.0, 128667.0], 'lbm') +_mission_data.set_val(Dynamic.Vehicle.LIFT, [128777.0, 128721.0, 128667.0], 'lbf') +_mission_data.set_val(Dynamic.Vehicle.MASS, [128777.0, 128721.0, 128667.0], 'lbm') mission_simple_data['N3CC'] = [572838.22, 572601.72, 572263.60] mission_equal_data['N3CC'] = [572828.63, 572579.53, 572339.33] diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_lift_dependent_drag.py b/aviary/subsystems/aerodynamics/flops_based/test/test_lift_dependent_drag.py index e02606f6d..19fc5c4d0 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_lift_dependent_drag.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_lift_dependent_drag.py @@ -27,9 +27,9 @@ def test_derivs_edge_interp(self): prob.model.add_subsystem('drag', LiftDependentDrag(num_nodes=nn), promotes=['*']) prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.LIFT, val=lift) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P) + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Vehicle.LIFT, val=lift) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P) prob.set_val(Aircraft.Wing.AREA, val=Sref) prob.set_val(Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, val=1.0) prob.set_val(Aircraft.Wing.SWEEP, val=25.03) @@ -64,9 +64,9 @@ def test_derivs_inner_interp(self): prob.model.add_subsystem('drag', LiftDependentDrag(num_nodes=nn), promotes=['*']) prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.MACH, val=mach) - prob.set_val(Dynamic.Mission.LIFT, val=lift) - prob.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P) + prob.set_val(Dynamic.Atmosphere.MACH, val=mach) + prob.set_val(Dynamic.Vehicle.LIFT, val=lift) + prob.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P) prob.set_val(Aircraft.Wing.AREA, val=Sref) prob.set_val(Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, val=1.0) prob.set_val(Aircraft.Wing.SWEEP, val=25.07) 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 e458dbb71..456b23524 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 @@ -57,16 +57,15 @@ def test_case(self): # test data from large_single_aisle_2 climb profile # tabular aero was set to large_single_aisle_1, expected value adjusted accordingly self.prob.set_val( - Dynamic.Mission.VELOCITY, - val=115, - units='m/s') # convert from knots to ft/s + Dynamic.Mission.VELOCITY, val=115, units='m/s' + ) # convert from knots to ft/s self.prob.set_val(Dynamic.Mission.ALTITUDE, val=10582, units='m') - self.prob.set_val(Dynamic.Mission.MASS, val=80442, units='kg') - self.prob.set_val(Dynamic.Mission.MACH, val=0.3876, units='unitless') + self.prob.set_val(Dynamic.Vehicle.MASS, val=80442, units='kg') + self.prob.set_val(Dynamic.Atmosphere.MACH, val=0.3876, units='unitless') # 1344.5? 'reference' vs 'calculated'? self.prob.set_val(Aircraft.Wing.AREA, val=1341, units='ft**2') # calculated from online atmospheric table - self.prob.set_val(Dynamic.Mission.DENSITY, val=0.88821, units='kg/m**3') + self.prob.set_val(Dynamic.Atmosphere.DENSITY, val=0.88821, units='kg/m**3') self.prob.run_model() @@ -75,7 +74,7 @@ def test_case(self): tol = .03 assert_near_equal( - self.prob.get_val(Dynamic.Mission.DRAG, units='N'), 53934.78861492, tol + self.prob.get_val(Dynamic.Vehicle.DRAG, units='N'), 53934.78861492, tol ) # check the value of each output # TODO resolve partials wrt gravity (decide on implementation of gravity) @@ -171,16 +170,15 @@ def test_case(self): # test data from large_single_aisle_2 climb profile # tabular aero was set to large_single_aisle_1 data, expected value adjusted accordingly self.prob.set_val( - Dynamic.Mission.VELOCITY, - val=115, - units='m/s') # convert from knots to ft/s + Dynamic.Mission.VELOCITY, val=115, units='m/s' + ) # convert from knots to ft/s self.prob.set_val(Dynamic.Mission.ALTITUDE, val=10582, units='m') - self.prob.set_val(Dynamic.Mission.MASS, val=80442, units='kg') - self.prob.set_val(Dynamic.Mission.MACH, val=0.3876, units='unitless') + self.prob.set_val(Dynamic.Vehicle.MASS, val=80442, units='kg') + self.prob.set_val(Dynamic.Atmosphere.MACH, val=0.3876, units='unitless') # 1344.5? 'reference' vs 'calculated'? self.prob.set_val(Aircraft.Wing.AREA, val=1341, units='ft**2') # calculated from online atmospheric table - self.prob.set_val(Dynamic.Mission.DENSITY, val=0.88821, units='kg/m**3') + self.prob.set_val(Dynamic.Atmosphere.DENSITY, val=0.88821, units='kg/m**3') self.prob.run_model() @@ -189,7 +187,7 @@ def test_case(self): tol = .03 assert_near_equal( - self.prob.get_val(Dynamic.Mission.DRAG, units='N'), 53934.78861492, tol + self.prob.get_val(Dynamic.Vehicle.DRAG, units='N'), 53934.78861492, tol ) # check the value of each output # TODO resolve partials wrt gravity (decide on implementation of gravity) @@ -236,28 +234,28 @@ def test_case(self, case_name): dynamic_inputs.set_val(Dynamic.Mission.VELOCITY, val=vel, units=vel_units) dynamic_inputs.set_val(Dynamic.Mission.ALTITUDE, val=alt, units=alt_units) - dynamic_inputs.set_val(Dynamic.Mission.MASS, val=mass, units=units) + dynamic_inputs.set_val(Dynamic.Vehicle.MASS, val=mass, units=units) prob = _get_computed_aero_data_at_altitude(alt, alt_units) - sos = prob.get_val(Dynamic.Mission.SPEED_OF_SOUND, vel_units) + sos = prob.get_val(Dynamic.Atmosphere.SPEED_OF_SOUND, vel_units) mach = vel / sos - dynamic_inputs.set_val(Dynamic.Mission.MACH, val=mach, units='unitless') + dynamic_inputs.set_val(Dynamic.Atmosphere.MACH, val=mach, units='unitless') - key = Dynamic.Mission.DENSITY + key = Dynamic.Atmosphere.DENSITY units = 'kg/m**3' val = prob.get_val(key, units) dynamic_inputs.set_val(key, val=val, units=units) - key = Dynamic.Mission.TEMPERATURE + key = Dynamic.Atmosphere.TEMPERATURE units = 'degR' val = prob.get_val(key, units) dynamic_inputs.set_val(key, val=val, units=units) - key = Dynamic.Mission.STATIC_PRESSURE + key = Dynamic.Atmosphere.STATIC_PRESSURE units = 'N/m**2' val = prob.get_val(key, units) @@ -265,7 +263,7 @@ def test_case(self, case_name): prob = _run_computed_aero_harness(flops_inputs, dynamic_inputs, 1) - computed_drag = prob.get_val(Dynamic.Mission.DRAG, 'N') + computed_drag = prob.get_val(Dynamic.Vehicle.DRAG, 'N') CDI_data, CD0_data = _computed_aero_drag_data( flops_inputs, *_design_altitudes.get_item(case_name)) @@ -298,7 +296,7 @@ def test_case(self, case_name): prob.run_model() - tabular_drag = prob.get_val(Dynamic.Mission.DRAG, 'N') + tabular_drag = prob.get_val(Dynamic.Vehicle.DRAG, 'N') assert_near_equal(tabular_drag, computed_drag, 0.005) @@ -376,7 +374,7 @@ def _default_CD0_data(): CD0_data = NamedValues() CD0_data.set_val(Dynamic.Mission.ALTITUDE, alt_range, 'ft') - CD0_data.set_val(Dynamic.Mission.MACH, mach_range) + CD0_data.set_val(Dynamic.Atmosphere.MACH, mach_range) CD0_data.set_val('zero_lift_drag_coefficient', CD0) return CD0_data @@ -442,7 +440,7 @@ def _default_CDI_data(): # cl_list = np.array(cl_list).flatten() # mach_list = np.array(mach_list).flatten() CDI_data = NamedValues() - CDI_data.set_val(Dynamic.Mission.MACH, mach_range) + CDI_data.set_val(Dynamic.Atmosphere.MACH, mach_range) CDI_data.set_val('lift_coefficient', cl_range) CDI_data.set_val('lift_dependent_drag_coefficient', CDI) @@ -501,8 +499,8 @@ def _computed_aero_drag_data(flops_inputs: AviaryValues, design_altitude, units) # calculate temperature (degR), static pressure (lbf/ft**2), and mass (lbm) at design # altitude from lift coefficients and Mach numbers prob: om.Problem = _get_computed_aero_data_at_altitude(design_altitude, units) - T = prob.get_val(Dynamic.Mission.TEMPERATURE, 'degR') - P = prob.get_val(Dynamic.Mission.STATIC_PRESSURE, 'lbf/ft**2') + T = prob.get_val(Dynamic.Atmosphere.TEMPERATURE, 'degR') + P = prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, 'lbf/ft**2') mass = lift = CL * S * 0.5 * 1.4 * P * mach**2 # lbf -> lbm * 1g @@ -511,10 +509,10 @@ def _computed_aero_drag_data(flops_inputs: AviaryValues, design_altitude, units) dynamic_inputs = AviaryValues() - dynamic_inputs.set_val(Dynamic.Mission.MACH, val=mach) - dynamic_inputs.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P, units='lbf/ft**2') - dynamic_inputs.set_val(Dynamic.Mission.TEMPERATURE, val=T, units='degR') - dynamic_inputs.set_val(Dynamic.Mission.MASS, val=mass, units='lbm') + dynamic_inputs.set_val(Dynamic.Atmosphere.MACH, val=mach) + dynamic_inputs.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, val=P, units='lbf/ft**2') + dynamic_inputs.set_val(Dynamic.Atmosphere.TEMPERATURE, val=T, units='degR') + dynamic_inputs.set_val(Dynamic.Vehicle.MASS, val=mass, units='lbm') prob = _run_computed_aero_harness(flops_inputs, dynamic_inputs, nn) @@ -522,7 +520,7 @@ def _computed_aero_drag_data(flops_inputs: AviaryValues, design_altitude, units) CDI = np.reshape(CDI.flatten(), (nsteps, nsteps)) CDI_data = NamedValues() - CDI_data.set_val(Dynamic.Mission.MACH, seed) + CDI_data.set_val(Dynamic.Atmosphere.MACH, seed) CDI_data.set_val('lift_coefficient', seed) CDI_data.set_val('lift_dependent_drag_coefficient', CDI) @@ -535,18 +533,19 @@ def _computed_aero_drag_data(flops_inputs: AviaryValues, design_altitude, units) dynamic_inputs = AviaryValues() - dynamic_inputs.set_val(Dynamic.Mission.MACH, val=mach) - dynamic_inputs.set_val(Dynamic.Mission.MASS, val=mass, units=units) + dynamic_inputs.set_val(Dynamic.Atmosphere.MACH, val=mach) + dynamic_inputs.set_val(Dynamic.Vehicle.MASS, val=mass, units=units) CD0 = [] for h in alt: prob: om.Problem = _get_computed_aero_data_at_altitude(h, 'ft') - T = prob.get_val(Dynamic.Mission.TEMPERATURE, 'degR') - P = prob.get_val(Dynamic.Mission.STATIC_PRESSURE, 'lbf/ft**2') + T = prob.get_val(Dynamic.Atmosphere.TEMPERATURE, 'degR') + P = prob.get_val(Dynamic.Atmosphere.STATIC_PRESSURE, 'lbf/ft**2') - dynamic_inputs.set_val(Dynamic.Mission.STATIC_PRESSURE, val=P, units='lbf/ft**2') - dynamic_inputs.set_val(Dynamic.Mission.TEMPERATURE, val=T, units='degR') + dynamic_inputs.set_val(Dynamic.Atmosphere.STATIC_PRESSURE, + val=P, units='lbf/ft**2') + dynamic_inputs.set_val(Dynamic.Atmosphere.TEMPERATURE, val=T, units='degR') prob = _run_computed_aero_harness(flops_inputs, dynamic_inputs, nn) @@ -556,7 +555,7 @@ def _computed_aero_drag_data(flops_inputs: AviaryValues, design_altitude, units) CD0_data = NamedValues() CD0_data.set_val(Dynamic.Mission.ALTITUDE, alt, 'ft') - CD0_data.set_val(Dynamic.Mission.MACH, seed) + CD0_data.set_val(Dynamic.Atmosphere.MACH, seed) CD0_data.set_val('zero_lift_drag_coefficient', CD0) return (CDI_data, CD0_data) diff --git a/aviary/subsystems/aerodynamics/flops_based/test/test_takeoff_aero_group.py b/aviary/subsystems/aerodynamics/flops_based/test/test_takeoff_aero_group.py index ffddd89f0..b57bd73e9 100644 --- a/aviary/subsystems/aerodynamics/flops_based/test/test_takeoff_aero_group.py +++ b/aviary/subsystems/aerodynamics/flops_based/test/test_takeoff_aero_group.py @@ -88,7 +88,7 @@ def make_problem(subsystem_options={}): prob.model.add_subsystem( name='atmosphere', subsys=Atmosphere(num_nodes=nn), - promotes=['*', (Dynamic.Mission.DYNAMIC_PRESSURE, 'skip')], + promotes=['*', (Dynamic.Atmosphere.DYNAMIC_PRESSURE, 'skip')], ) aero_builder = CoreAerodynamicsBuilder(code_origin=LegacyCode.FLOPS) @@ -132,22 +132,36 @@ def make_problem(subsystem_options={}): # - last generated 2023 June 8 # - generate new regression data if, and only if, takeoff aero group is updated with a # more trusted implementation -_regression_data = AviaryValues({ - Dynamic.Mission.LIFT: ( - [3028.138891962988, 4072.059743068957, 6240.85493286], _units_lift), - Dynamic.Mission.DRAG: ( - [434.6285684000267, 481.5245555324278, 586.0976806512001], _units_drag)}) +_regression_data = AviaryValues( + { + Dynamic.Vehicle.LIFT: ( + [3028.138891962988, 4072.059743068957, 6240.85493286], + _units_lift, + ), + Dynamic.Vehicle.DRAG: ( + [434.6285684000267, 481.5245555324278, 586.0976806512001], + _units_drag, + ), + } +) # NOTE: # - results from `generate_regression_data_spoiler()` # - last generated 2023 June 8 # - generate new regression data if, and only if, takeoff aero group is updated with a # more trusted implementation -_regression_data_spoiler = AviaryValues({ - Dynamic.Mission.LIFT: ( - [-1367.5937129210124, -323.67286181504335, 1845.1223279759993], _units_lift), - Dynamic.Mission.DRAG: ( - [895.9091503940268, 942.8051375264279, 1047.3782626452], _units_drag)}) +_regression_data_spoiler = AviaryValues( + { + Dynamic.Vehicle.LIFT: ( + [-1367.5937129210124, -323.67286181504335, 1845.1223279759993], + _units_lift, + ), + Dynamic.Vehicle.DRAG: ( + [895.9091503940268, 942.8051375264279, 1047.3782626452], + _units_drag, + ), + } +) def generate_regression_data(): @@ -202,8 +216,8 @@ def _generate_regression_data(subsystem_options={}): prob.run_model() - lift = prob.get_val(Dynamic.Mission.LIFT, _units_lift) - drag = prob.get_val(Dynamic.Mission.DRAG, _units_drag) + lift = prob.get_val(Dynamic.Vehicle.LIFT, _units_lift) + drag = prob.get_val(Dynamic.Vehicle.DRAG, _units_drag) prob.check_partials(compact_print=True, method="cs") diff --git a/aviary/subsystems/aerodynamics/gasp_based/common.py b/aviary/subsystems/aerodynamics/gasp_based/common.py index 8af9801d1..9f34627ba 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/common.py +++ b/aviary/subsystems/aerodynamics/gasp_based/common.py @@ -16,41 +16,52 @@ def setup(self): self.add_input("CL", 1.0, units="unitless", shape=nn, desc="Lift coefficient") self.add_input("CD", 1.0, units="unitless", shape=nn, desc="Drag coefficient") - self.add_input(Dynamic.Mission.DYNAMIC_PRESSURE, 1.0, - units="psf", shape=nn, desc="Dynamic pressure") + self.add_input( + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + 1.0, + units="psf", + shape=nn, + desc="Dynamic pressure", + ) add_aviary_input(self, Aircraft.Wing.AREA, val=1370.3) - self.add_output(Dynamic.Mission.LIFT, units="lbf", shape=nn, desc="Lift force") - self.add_output(Dynamic.Mission.DRAG, units="lbf", shape=nn, desc="Drag force") + self.add_output(Dynamic.Vehicle.LIFT, units="lbf", shape=nn, desc="Lift force") + self.add_output(Dynamic.Vehicle.DRAG, units="lbf", shape=nn, desc="Drag force") def setup_partials(self): nn = self.options["num_nodes"] arange = np.arange(nn) self.declare_partials( - Dynamic.Mission.LIFT, [ - "CL", Dynamic.Mission.DYNAMIC_PRESSURE], rows=arange, cols=arange) - self.declare_partials(Dynamic.Mission.LIFT, [Aircraft.Wing.AREA]) + Dynamic.Vehicle.LIFT, + ["CL", Dynamic.Atmosphere.DYNAMIC_PRESSURE], + rows=arange, + cols=arange, + ) + self.declare_partials(Dynamic.Vehicle.LIFT, [Aircraft.Wing.AREA]) self.declare_partials( - Dynamic.Mission.DRAG, [ - "CD", Dynamic.Mission.DYNAMIC_PRESSURE], rows=arange, cols=arange) - self.declare_partials(Dynamic.Mission.DRAG, [Aircraft.Wing.AREA]) + Dynamic.Vehicle.DRAG, + ["CD", Dynamic.Atmosphere.DYNAMIC_PRESSURE], + rows=arange, + cols=arange, + ) + self.declare_partials(Dynamic.Vehicle.DRAG, [Aircraft.Wing.AREA]) def compute(self, inputs, outputs): CL, CD, q, wing_area = inputs.values() - outputs[Dynamic.Mission.LIFT] = q * CL * wing_area - outputs[Dynamic.Mission.DRAG] = q * CD * wing_area + outputs[Dynamic.Vehicle.LIFT] = q * CL * wing_area + outputs[Dynamic.Vehicle.DRAG] = q * CD * wing_area def compute_partials(self, inputs, J): CL, CD, q, wing_area = inputs.values() - J[Dynamic.Mission.LIFT, "CL"] = q * wing_area - J[Dynamic.Mission.LIFT, Dynamic.Mission.DYNAMIC_PRESSURE] = CL * wing_area - J[Dynamic.Mission.LIFT, Aircraft.Wing.AREA] = q * CL + J[Dynamic.Vehicle.LIFT, "CL"] = q * wing_area + J[Dynamic.Vehicle.LIFT, Dynamic.Atmosphere.DYNAMIC_PRESSURE] = CL * wing_area + J[Dynamic.Vehicle.LIFT, Aircraft.Wing.AREA] = q * CL - J[Dynamic.Mission.DRAG, "CD"] = q * wing_area - J[Dynamic.Mission.DRAG, Dynamic.Mission.DYNAMIC_PRESSURE] = CD * wing_area - J[Dynamic.Mission.DRAG, Aircraft.Wing.AREA] = q * CD + J[Dynamic.Vehicle.DRAG, "CD"] = q * wing_area + J[Dynamic.Vehicle.DRAG, Dynamic.Atmosphere.DYNAMIC_PRESSURE] = CD * wing_area + J[Dynamic.Vehicle.DRAG, Aircraft.Wing.AREA] = q * CD class CLFromLift(om.ExplicitComponent): @@ -62,8 +73,13 @@ def initialize(self): def setup(self): nn = self.options["num_nodes"] self.add_input("lift_req", 1, units="lbf", shape=nn, desc="Lift force") - self.add_input(Dynamic.Mission.DYNAMIC_PRESSURE, 1.0, - units="psf", shape=nn, desc="Dynamic pressure") + self.add_input( + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + 1.0, + units="psf", + shape=nn, + desc="Dynamic pressure", + ) add_aviary_input(self, Aircraft.Wing.AREA, val=1370.3) @@ -72,7 +88,8 @@ def setup(self): def setup_partials(self): ar = np.arange(self.options["num_nodes"]) self.declare_partials( - "CL", ["lift_req", Dynamic.Mission.DYNAMIC_PRESSURE], rows=ar, cols=ar) + "CL", ["lift_req", Dynamic.Atmosphere.DYNAMIC_PRESSURE], rows=ar, cols=ar + ) self.declare_partials("CL", [Aircraft.Wing.AREA]) def compute(self, inputs, outputs): @@ -82,7 +99,7 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, J): lift_req, q, wing_area = inputs.values() J["CL", "lift_req"] = 1 / (q * wing_area) - J["CL", Dynamic.Mission.DYNAMIC_PRESSURE] = -lift_req / (q**2 * wing_area) + J["CL", Dynamic.Atmosphere.DYNAMIC_PRESSURE] = -lift_req / (q**2 * wing_area) J["CL", Aircraft.Wing.AREA] = -lift_req / (q * wing_area**2) diff --git a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/Cl_max.py b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/Cl_max.py index e9e174aed..81e8b1f38 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/Cl_max.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/Cl_max.py @@ -21,7 +21,7 @@ def setup(self): desc="VLAM8: sensitivity of flap clean wing maximum lift coefficient to wing sweep angle", ) self.add_input( - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.SPEED_OF_SOUND, val=1118.21948771, units="ft/s", desc="SA: speed of sound at sea level", @@ -72,10 +72,16 @@ def setup(self): desc="VLAM7: sensitivity of flap clean wing maximum lift coefficient to wing flap span", ) self.add_input( - "VLAM13", val=1.03512, units='unitless', desc="VLAM13: reynolds number correction factor" + "VLAM13", + val=1.03512, + units='unitless', + desc="VLAM13: reynolds number correction factor", ) self.add_input( - "VLAM14", val=0.99124, units='unitless', desc="VLAM14: mach number correction factor " + "VLAM14", + val=0.99124, + units='unitless', + desc="VLAM14: mach number correction factor ", ) # other inputs @@ -83,7 +89,10 @@ def setup(self): add_aviary_input(self, Aircraft.Wing.LOADING, val=128) self.add_input( - Dynamic.Mission.STATIC_PRESSURE, val=(14.696 * 144), units="lbf/ft**2", desc="P0: static pressure" + Dynamic.Atmosphere.STATIC_PRESSURE, + val=(14.696 * 144), + units="lbf/ft**2", + desc="P0: static pressure", ) add_aviary_input(self, Aircraft.Wing.AVERAGE_CHORD, val=12.61) @@ -114,16 +123,20 @@ def setup(self): units='unitless', desc="VLAM12: sensitivity of slat clean wing maximum lift coefficient to leading edge sweepback", ) - self.add_input("fus_lift", val=0.05498, units='unitless', - desc="DELCLF: fuselage lift increment") self.add_input( - Dynamic.Mission.KINEMATIC_VISCOSITY, + "fus_lift", + val=0.05498, + units='unitless', + desc="DELCLF: fuselage lift increment", + ) + self.add_input( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, val=0.15723e-03, units="ft**2/s", desc="XKV: kinematic viscosity", ) self.add_input( - Dynamic.Mission.TEMPERATURE, + Dynamic.Atmosphere.TEMPERATURE, val=518.67, units="degR", desc="T0: static temperature of air cross wing", @@ -131,12 +144,21 @@ def setup(self): # outputs - self.add_output("CL_max", val=2.8155, - desc="CLMAX: maximum lift coefficient", units="unitless") - self.add_output(Dynamic.Mission.MACH, val=0.17522, - units='unitless', desc="SMN: mach number") - self.add_output("reynolds", val=157.1111, units='unitless', - desc="RNW: reynolds number") + self.add_output( + "CL_max", + val=2.8155, + desc="CLMAX: maximum lift coefficient", + units="unitless", + ) + self.add_output( + Dynamic.Atmosphere.MACH, + val=0.17522, + units='unitless', + desc="SMN: mach number", + ) + self.add_output( + "reynolds", val=157.1111, units='unitless', desc="RNW: reynolds number" + ) def setup_partials(self): @@ -167,10 +189,10 @@ def setup_partials(self): step=1e-8, ) self.declare_partials( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, [ Aircraft.Wing.LOADING, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.STATIC_PRESSURE, Aircraft.Wing.MAX_LIFT_REF, "VLAM1", "VLAM2", @@ -197,10 +219,10 @@ def setup_partials(self): self.declare_partials( "reynolds", [ - Dynamic.Mission.KINEMATIC_VISCOSITY, - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, Aircraft.Wing.AVERAGE_CHORD, - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.STATIC_PRESSURE, Aircraft.Wing.LOADING, Aircraft.Wing.MAX_LIFT_REF, "VLAM1", @@ -243,11 +265,11 @@ def compute(self, inputs, outputs): VLAM13 = inputs["VLAM13"] VLAM14 = inputs["VLAM14"] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] wing_loading = inputs[Aircraft.Wing.LOADING] - P = inputs[Dynamic.Mission.STATIC_PRESSURE] + P = inputs[Dynamic.Atmosphere.STATIC_PRESSURE] avg_chord = inputs[Aircraft.Wing.AVERAGE_CHORD] - kinematic_viscosity = inputs[Dynamic.Mission.KINEMATIC_VISCOSITY] + kinematic_viscosity = inputs[Dynamic.Atmosphere.KINEMATIC_VISCOSITY] max_lift_reference = inputs[Aircraft.Wing.MAX_LIFT_REF] leading_lift_increment = inputs[Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM] fus_lift = inputs["fus_lift"] @@ -263,7 +285,7 @@ def compute(self, inputs, outputs): Q1 = wing_loading / CL_max - outputs[Dynamic.Mission.MACH] = mach = (Q1 / 0.7 / P) ** 0.5 + outputs[Dynamic.Atmosphere.MACH] = mach = (Q1 / 0.7 / P) ** 0.5 VK = mach * sos outputs["reynolds"] = reynolds = (avg_chord * VK / kinematic_viscosity) / 100000 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 3a4d9ad7d..0f35af711 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/flaps_model.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/flaps_model.py @@ -1,13 +1,17 @@ import openmdao.api as om -from aviary.subsystems.aerodynamics.gasp_based.flaps_model.basic_calculations import \ - BasicFlapsCalculations -from aviary.subsystems.aerodynamics.gasp_based.flaps_model.Cl_max import \ - CLmaxCalculation -from aviary.subsystems.aerodynamics.gasp_based.flaps_model.L_and_D_increments import \ - LiftAndDragIncrements -from aviary.subsystems.aerodynamics.gasp_based.flaps_model.meta_model import \ - MetaModelGroup +from aviary.subsystems.aerodynamics.gasp_based.flaps_model.basic_calculations import ( + BasicFlapsCalculations, +) +from aviary.subsystems.aerodynamics.gasp_based.flaps_model.Cl_max import ( + CLmaxCalculation, +) +from aviary.subsystems.aerodynamics.gasp_based.flaps_model.L_and_D_increments import ( + LiftAndDragIncrements, +) +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 @@ -22,8 +26,9 @@ class FlapsGroup(om.Group): def initialize(self): self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', ) # optimum trailing edge flap deflection angle defaults (ADELTO table in GASP) @@ -56,9 +61,9 @@ def setup(self): "CLmaxCalculation", CLmaxCalculation(), promotes_inputs=[ - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.STATIC_PRESSURE, - Dynamic.Mission.KINEMATIC_VISCOSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, "VLAM1", "VLAM2", "VLAM3", @@ -74,10 +79,10 @@ def setup(self): "VLAM13", "VLAM14", "fus_lift", - Dynamic.Mission.TEMPERATURE, + Dynamic.Atmosphere.TEMPERATURE, ] + ["aircraft:*"], - promotes_outputs=["CL_max", Dynamic.Mission.MACH, "reynolds"], + promotes_outputs=["CL_max", Dynamic.Atmosphere.MACH, "reynolds"], ) self.add_subsystem( @@ -88,7 +93,7 @@ def setup(self): "flap_defl", "slat_defl_ratio", "reynolds", - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, "body_to_span_ratio", "chord_to_body_ratio", ] @@ -146,7 +151,10 @@ 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["aviary_options"].get_val( + Aircraft.Wing.FLAP_TYPE, units='unitless' + ) + ], 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 5c9e00b4c..12b1d920a 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/meta_model.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/meta_model.py @@ -782,7 +782,7 @@ def setup(self): "VLAM14_interp", om.MetaModelStructuredComp(method="1D-slinear", extrapolate=True), promotes_inputs=[ - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, ], promotes_outputs=[ "VLAM14", @@ -790,7 +790,7 @@ def setup(self): ) VLAM14_interp.add_input( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, 0.17522, training_data=[0.0, 0.2, 0.4, 0.6, 0.8, 1.0], units="unitless", diff --git a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_Clmax.py b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_Clmax.py index fbc47559b..f95c1148d 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_Clmax.py +++ b/aviary/subsystems/aerodynamics/gasp_based/flaps_model/test/test_Clmax.py @@ -39,18 +39,22 @@ def setUp(self): self.prob.set_val("VLAM13", 1.03512) self.prob.set_val("VLAM14", 0.99124) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") # + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) # self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) self.prob.set_val(Aircraft.Wing.FLAP_LIFT_INCREMENT_OPTIMUM, 1.500) - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.7, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.7, units="degR") def test_case(self): @@ -63,7 +67,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.17522 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 157.19864 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 b7b78faed..a061652df 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 @@ -28,7 +28,7 @@ def setUp(self): self.prob.setup() self.prob.set_val(Aircraft.Wing.SWEEP, 25.0, units="deg") - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.67, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.67, units="degR") self.prob.set_val(Aircraft.Wing.ASPECT_RATIO, 10.13) self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) @@ -64,13 +64,17 @@ def setUp(self): self.prob.set_val("VDEL4", 0.93578) self.prob.set_val("VDEL5", 0.90761) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) @@ -97,7 +101,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.17522 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 157.1111 @@ -131,7 +135,7 @@ def setUp(self): self.prob.setup() self.prob.set_val(Aircraft.Wing.SWEEP, 25.0, units="deg") - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.67, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.67, units="degR") self.prob.set_val(Aircraft.Wing.ASPECT_RATIO, 10.13) self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) @@ -167,13 +171,17 @@ def setUp(self): self.prob.set_val("VDEL4", 0.93578) self.prob.set_val("VDEL5", 0.90761) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) @@ -200,7 +208,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.18368 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 164.78406 @@ -235,7 +243,7 @@ def setUp(self): self.prob.setup() self.prob.set_val(Aircraft.Wing.SWEEP, 25.0, units="deg") - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.67, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.67, units="degR") self.prob.set_val(Aircraft.Wing.ASPECT_RATIO, 10.13) self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) @@ -272,13 +280,17 @@ def setUp(self): self.prob.set_val("VDEL4", 0.93578) self.prob.set_val("VDEL5", 0.90761) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) @@ -305,7 +317,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.17522 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 157.1111 @@ -339,7 +351,7 @@ def setUp(self): self.prob.setup() self.prob.set_val(Aircraft.Wing.SWEEP, 25.0, units="deg") - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.67, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.67, units="degR") self.prob.set_val(Aircraft.Wing.ASPECT_RATIO, 10.13) self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) @@ -375,13 +387,17 @@ def setUp(self): self.prob.set_val("VDEL4", 0.93578) self.prob.set_val("VDEL5", 0.90761) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) @@ -408,7 +424,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.18368 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 164.78406 @@ -442,7 +458,7 @@ def setUp(self): self.prob.setup() self.prob.set_val(Aircraft.Wing.SWEEP, 25.0, units="deg") - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.67, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.67, units="degR") self.prob.set_val(Aircraft.Wing.ASPECT_RATIO, 10.13) self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) @@ -478,13 +494,17 @@ def setUp(self): self.prob.set_val("VDEL4", 0.93578) self.prob.set_val("VDEL5", 0.90761) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) @@ -511,7 +531,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.17168 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 154.02686 @@ -546,7 +566,7 @@ def setUp(self): self.prob.setup() self.prob.set_val(Aircraft.Wing.SWEEP, 25.0, units="deg") - self.prob.set_val(Dynamic.Mission.TEMPERATURE, 518.67, units="degR") + self.prob.set_val(Dynamic.Atmosphere.TEMPERATURE, 518.67, units="degR") self.prob.set_val(Aircraft.Wing.ASPECT_RATIO, 10.13) self.prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, 0.3) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) @@ -582,13 +602,17 @@ def setUp(self): self.prob.set_val("VDEL4", 0.93578) self.prob.set_val("VDEL5", 0.90761) - self.prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, 1118.21948771, units="ft/s") + self.prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, 1118.21948771, units="ft/s" + ) self.prob.set_val(Aircraft.Wing.LOADING, 128.0, units="lbf/ft**2") - self.prob.set_val(Dynamic.Mission.STATIC_PRESSURE, - (14.696 * 144), units="lbf/ft**2") + self.prob.set_val( + Dynamic.Atmosphere.STATIC_PRESSURE, (14.696 * 144), units="lbf/ft**2" + ) self.prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12.61, units="ft") - self.prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, - 0.15723e-3, units="ft**2/s") + self.prob.set_val( + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, 0.15723e-3, units="ft**2/s" + ) self.prob.set_val(Aircraft.Wing.MAX_LIFT_REF, 1.150) self.prob.set_val(Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, 0.930) self.prob.set_val("fus_lift", 0.05498) @@ -615,7 +639,7 @@ def test_case(self): assert_near_equal(ans, reg_data, tol) reg_data = 0.17168 - ans = self.prob[Dynamic.Mission.MACH] + ans = self.prob[Dynamic.Atmosphere.MACH] assert_near_equal(ans, reg_data, tol) reg_data = 154.02686 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 84581a8ea..3a0e37f04 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 @@ -34,7 +34,7 @@ def setUp(self): self.prob.set_val("slat_defl_ratio", 10 / 20) self.prob.set_val(Aircraft.Wing.SLAT_SPAN_RATIO, 0.89761) self.prob.set_val("reynolds", 164.78406) - self.prob.set_val(Dynamic.Mission.MACH, 0.18368) + self.prob.set_val(Dynamic.Atmosphere.MACH, 0.18368) self.prob.set_val(Aircraft.Wing.TAPER_RATIO, 0.33) self.prob.set_val(Aircraft.Wing.SLAT_SPAN_RATIO, 0.89761) self.prob.set_val("body_to_span_ratio", 0.09239) diff --git a/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py b/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py index abb839cbe..4542d9589 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py +++ b/aviary/subsystems/aerodynamics/gasp_based/gaspaero.py @@ -5,9 +5,11 @@ from openmdao.utils import cs_safe as cs from aviary.constants import GRAV_ENGLISH_LBM -from aviary.subsystems.aerodynamics.gasp_based.common import (AeroForces, - CLFromLift, - TanhRampComp) +from aviary.subsystems.aerodynamics.gasp_based.common import ( + AeroForces, + CLFromLift, + TanhRampComp, +) from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.functions import add_aviary_input from aviary.variable_info.variables import Aircraft, Dynamic, Mission @@ -181,14 +183,20 @@ def setup(self): add_aviary_input(self, Aircraft.Fuselage.AVG_DIAMETER, val=0.0) self.add_output( - "hbar", val=0.0, units="unitless", - desc="HBAR: Ratio of HGAP(?) to wing span") + "hbar", + val=0.0, + units="unitless", + desc="HBAR: Ratio of HGAP(?) to wing span", + ) self.add_output( - "bbar", units="unitless", desc="BBAR: Ratio of H tail area to wing area") + "bbar", units="unitless", desc="BBAR: Ratio of H tail area to wing area" + ) self.add_output( - "sbar", units="unitless", desc="SBAR: Ratio of H tail area to wing area") + "sbar", units="unitless", desc="SBAR: Ratio of H tail area to wing area" + ) self.add_output( - "cbar", units="unitless", desc="SBAR: Ratio of H tail chord to wing chord") + "cbar", units="unitless", desc="SBAR: Ratio of H tail chord to wing chord" + ) def setup_partials(self): self.declare_partials( @@ -253,8 +261,13 @@ def setup(self): nn = self.options["num_nodes"] # mission inputs - self.add_input(Dynamic.Mission.MACH, val=0.0, units="unitless", - shape=nn, desc="Mach number") + self.add_input( + Dynamic.Atmosphere.MACH, + val=0.0, + units="unitless", + shape=nn, + desc="Mach number", + ) # stability inputs @@ -276,24 +289,30 @@ def setup(self): # geometry from wing-tail ratios self.add_input( - "sbar", units="unitless", desc="SBAR: Ratio of H tail area to wing area") + "sbar", units="unitless", desc="SBAR: Ratio of H tail area to wing area" + ) self.add_input( - "cbar", units="unitless", desc="CBAR: Ratio of H tail chord to wing chord") + "cbar", units="unitless", desc="CBAR: Ratio of H tail chord to wing chord" + ) self.add_input( - "hbar", units="unitless", desc="HBAR: Ratio of HGAP(?) to wing span") + "hbar", units="unitless", desc="HBAR: Ratio of HGAP(?) to wing span" + ) self.add_input( - "bbar", units="unitless", desc="BBAR: Ratio of H tail area to wing area") + "bbar", units="unitless", desc="BBAR: Ratio of H tail area to wing area" + ) - self.add_output("lift_curve_slope", units="unitless", - shape=nn, desc="Lift-curve slope") + self.add_output( + "lift_curve_slope", units="unitless", shape=nn, desc="Lift-curve slope" + ) self.add_output("lift_ratio", units="unitless", shape=nn, desc="Lift ratio") def setup_partials(self): ar = np.arange(self.options["num_nodes"]) self.declare_partials("lift_ratio", "*", method="cs") - self.declare_partials("lift_ratio", Dynamic.Mission.MACH, - rows=ar, cols=ar, method="cs") + self.declare_partials( + "lift_ratio", Dynamic.Atmosphere.MACH, rows=ar, cols=ar, method="cs" + ) self.declare_partials("lift_curve_slope", "*", method="cs") self.declare_partials( "lift_curve_slope", @@ -310,8 +329,9 @@ def setup_partials(self): ], method="cs", ) - self.declare_partials("lift_curve_slope", Dynamic.Mission.MACH, - rows=ar, cols=ar, method="cs") + self.declare_partials( + "lift_curve_slope", Dynamic.Atmosphere.MACH, rows=ar, cols=ar, method="cs" + ) def compute(self, inputs, outputs): ( @@ -346,9 +366,7 @@ def compute(self, inputs, outputs): eps2 = 1 / np.pi / AR eps3 = cs.abs(xt) / (np.pi * AR * np.sqrt(xt**2 + h**2 + AR**2 / 4)) eps4 = 1 / np.pi / art - eps5 = cs.abs(xt) / ( - np.pi * art * np.sqrt(xt**2 + h**2 + art**2 * cbar**2 / 4) - ) + eps5 = cs.abs(xt) / (np.pi * art * np.sqrt(xt**2 + h**2 + art**2 * cbar**2 / 4)) claw = ( claw0 @@ -376,26 +394,33 @@ 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' + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', ) 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['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + ) self.add_input( - Dynamic.Mission.MACH, val=0.0, units="unitless", shape=nn, desc="Current Mach number") + Dynamic.Atmosphere.MACH, + val=0.0, + units="unitless", + shape=nn, + desc="Current Mach number", + ) self.add_input( - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.SPEED_OF_SOUND, val=1.0, units="ft/s", shape=nn, desc="Speed of sound at current altitude", ) self.add_input( - Dynamic.Mission.KINEMATIC_VISCOSITY, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, val=1.0, units="ft**2/s", shape=nn, @@ -411,8 +436,9 @@ def setup(self): add_aviary_input(self, Aircraft.Fuselage.FORM_FACTOR, val=1.25) - add_aviary_input(self, Aircraft.Nacelle.FORM_FACTOR, - val=np.full(num_engine_type, 1.5)) + add_aviary_input( + self, Aircraft.Nacelle.FORM_FACTOR, val=np.full(num_engine_type, 1.5) + ) add_aviary_input(self, Aircraft.VerticalTail.FORM_FACTOR, val=1.25) @@ -454,15 +480,17 @@ def setup(self): add_aviary_input(self, Aircraft.Fuselage.LENGTH, val=0.0) - add_aviary_input(self, Aircraft.Nacelle.AVG_LENGTH, - val=np.zeros(num_engine_type)) + add_aviary_input( + self, Aircraft.Nacelle.AVG_LENGTH, val=np.zeros(num_engine_type) + ) add_aviary_input(self, Aircraft.HorizontalTail.AREA, val=0.0) add_aviary_input(self, Aircraft.Fuselage.WETTED_AREA, val=0.0) - add_aviary_input(self, Aircraft.Nacelle.SURFACE_AREA, - val=np.zeros(num_engine_type)) + add_aviary_input( + self, Aircraft.Nacelle.SURFACE_AREA, val=np.zeros(num_engine_type) + ) add_aviary_input(self, Aircraft.Wing.AREA, val=1370.3) @@ -479,12 +507,16 @@ def setup(self): # outputs for i in range(7): - name = f"SA{i+1}" - self.add_output(name, units="unitless", shape=nn, desc=f"{name}: Drag param") + name = f"SA{i + 1}" + self.add_output( + name, units="unitless", shape=nn, desc=f"{name}: Drag param" + ) self.add_output( - "cf", units="unitless", shape=nn, - desc="CFIN: Skin friction coefficient at Re=1e7" + "cf", + units="unitless", + shape=nn, + desc="CFIN: Skin friction coefficient at Re=1e7", ) def setup_partials(self): @@ -528,21 +560,44 @@ def setup_partials(self): self.declare_partials( "SA4", [Aircraft.Wing.THICKNESS_TO_CHORD_UNWEIGHTED], method="cs" ) - self.declare_partials("cf", [Dynamic.Mission.MACH], - rows=ar, cols=ar, method="cs") + self.declare_partials( + "cf", [Dynamic.Atmosphere.MACH], rows=ar, cols=ar, method="cs" + ) # diag partials for SA5-SA7 self.declare_partials( - "SA5", [Dynamic.Mission.MACH, Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.KINEMATIC_VISCOSITY], rows=ar, cols=ar, method="cs" + "SA5", + [ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, + ], + rows=ar, + cols=ar, + method="cs", ) self.declare_partials( - "SA6", [Dynamic.Mission.MACH, Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.KINEMATIC_VISCOSITY], rows=ar, cols=ar, method="cs" + "SA6", + [ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, + ], + rows=ar, + cols=ar, + method="cs", ) self.declare_partials( - "SA7", [Dynamic.Mission.MACH, Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.KINEMATIC_VISCOSITY, "ufac"], rows=ar, cols=ar, method="cs" + "SA7", + [ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, + "ufac", + ], + rows=ar, + cols=ar, + method="cs", ) # dense partials for SA5-SA7 @@ -664,7 +719,8 @@ def compute(self, inputs, outputs): 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') + Aircraft.Wing.HAS_STRUT, units='unitless' + ) if include_strut: fstrtre = (np.log10(reli[good_mask] * strut_chord) / 7) ** -2.6 @@ -694,13 +750,7 @@ def compute(self, inputs, outputs): fe = few + fef + fevt + feht + fen + feiwf + festrt + cd0_inc * wing_area wfob = cabin_width / wingspan - siwb = ( - 1 - - 0.0088 * wfob - - 1.7364 * wfob**2 - - 2.303 * wfob**3 - + 6.0606 * wfob**4 - ) + siwb = 1 - 0.0088 * wfob - 1.7364 * wfob**2 - 2.303 * wfob**3 + 6.0606 * wfob**4 # wing-free profile drag coefficient cdpo = (fe - few) / wing_area @@ -747,8 +797,10 @@ 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') + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', + ) self.options.declare( "input_atmos", default=False, @@ -757,8 +809,9 @@ def initialize(self): "computing them with an atmospherics component. For testing.", ) self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', ) def setup(self): @@ -777,25 +830,22 @@ def setup(self): self.add_subsystem("interp", interp, promotes=["*"]) self.add_subsystem( - "ufac_calc", - om.ExecComp( + "ufac_calc", om.ExecComp( "ufac=(1 + lift_ratio)**2 / (sigstr*(lift_ratio/bbar)**2 + 2*sigma*lift_ratio/bbar + 1)", lift_ratio={'units': "unitless", "shape": nn}, bbar={'units': "unitless"}, sigma={'units': "unitless"}, sigstr={'units': "unitless"}, ufac={'units': "unitless", "shape": nn}, - has_diag_partials=True - ), - promotes=["*"], - ) + has_diag_partials=True,), + promotes=["*"],) if not self.options["input_atmos"]: # self.add_subsystem( # "atmos", # USatm1976Comp(num_nodes=nn), # promotes_inputs=[("h", Dynamic.Mission.ALTITUDE)], - # promotes_outputs=["rho", Dynamic.Mission.SPEED_OF_SOUND, "viscosity"], + # promotes_outputs=["rho", Dynamic.Atmosphere.SPEED_OF_SOUND, "viscosity"], # ) self.add_subsystem( "kin_visc", @@ -806,12 +856,18 @@ def setup(self): nu={"units": "ft**2/s", "shape": nn}, has_diag_partials=True, ), - promotes=["*", ('rho', Dynamic.Mission.DENSITY), - ('nu', Dynamic.Mission.KINEMATIC_VISCOSITY)], + promotes=[ + "*", + ('rho', Dynamic.Atmosphere.DENSITY), + ('nu', Dynamic.Atmosphere.KINEMATIC_VISCOSITY), + ], ) - self.add_subsystem("geom", AeroGeom( - num_nodes=nn, aviary_options=aviary_options), promotes=["*"]) + self.add_subsystem( + "geom", + AeroGeom(num_nodes=nn, aviary_options=aviary_options), + promotes=["*"], + ) class DragCoef(om.ExplicitComponent): @@ -829,10 +885,16 @@ def setup(self): nn = self.options["num_nodes"] # mission inputs - self.add_input(Dynamic.Mission.ALTITUDE, val=0.0, - units="ft", shape=nn, desc="Altitude") self.add_input( - "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient") + Dynamic.Mission.ALTITUDE, + val=0.0, + units="ft", + shape=nn, + desc="Altitude", + ) + self.add_input( + "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient" + ) # user inputs @@ -850,19 +912,27 @@ def setup(self): # from flaps self.add_input( - "dCL_flaps_model", val=0.0, units="unitless", - desc="Delta CL from flaps model") + "dCL_flaps_model", + val=0.0, + units="unitless", + desc="Delta CL from flaps model", + ) self.add_input( - "dCD_flaps_model", val=0.0, units="unitless", - desc="Delta CD from flaps model") + "dCD_flaps_model", + val=0.0, + units="unitless", + desc="Delta CD from flaps model", + ) self.add_input( "dCL_flaps_coef", - val=1.0, units="unitless", + val=1.0, + units="unitless", desc="SIGMTO | SIGMLD: Coefficient applied to delta CL from flaps model", ) self.add_input( "CDI_factor", - val=1.0, units="unitless", + val=1.0, + units="unitless", desc="VDEL6T | VDEL6L: Factor applied to induced drag with flaps", ) @@ -876,19 +946,28 @@ def setup(self): # from aero setup self.add_input( - "cf", units="unitless", shape=nn, - desc="CFIN: Skin friction coefficient at Re=1e7") + "cf", + units="unitless", + shape=nn, + desc="CFIN: Skin friction coefficient at Re=1e7", + ) self.add_input("SA5", units="unitless", shape=nn, desc="SA5: Drag param") self.add_input("SA6", units="unitless", shape=nn, desc="SA6: Drag param") self.add_input("SA7", units="unitless", shape=nn, desc="SA7: Drag param") self.add_output("CD_base", units="unitless", shape=nn, desc="Drag coefficient") self.add_output( - "dCD_flaps_full", units="unitless", shape=nn, - desc="CD increment with full flap deflection") + "dCD_flaps_full", + units="unitless", + shape=nn, + desc="CD increment with full flap deflection", + ) self.add_output( - "dCD_gear_full", units="unitless", - shape=nn, desc="CD increment with landing gear down") + "dCD_gear_full", + units="unitless", + shape=nn, + desc="CD increment with landing gear down", + ) def setup_partials(self): # self.declare_coloring(method="cs", show_summary=False) @@ -971,19 +1050,33 @@ def setup(self): nn = self.options["num_nodes"] # mission inputs - self.add_input(Dynamic.Mission.MACH, val=0.0, units="unitless", - shape=nn, desc="Mach number") self.add_input( - "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient") + Dynamic.Atmosphere.MACH, + val=0.0, + units="unitless", + shape=nn, + desc="Mach number", + ) + self.add_input( + "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient" + ) # user inputs - add_aviary_input(self, Aircraft.Design.SUPERCRITICAL_DIVERGENCE_SHIFT, val=0.033) + add_aviary_input(self, Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, val=1.0) + add_aviary_input(self, Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, val=1.0) + add_aviary_input( + self, Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, val=1.0 + ) + add_aviary_input(self, Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, val=1.0) # from aero setup self.add_input( - "cf", units="unitless", shape=nn, - desc="CFIN: Skin friction coefficient at Re=1e7") + "cf", + units="unitless", + shape=nn, + desc="CFIN: Skin friction coefficient at Re=1e7", + ) self.add_input("SA1", units="unitless", shape=nn, desc="SA1: Drag param") self.add_input("SA2", units="unitless", shape=nn, desc="SA2: Drag param") self.add_input("SA5", units="unitless", shape=nn, desc="SA5: Drag param") @@ -997,7 +1090,7 @@ def setup_partials(self): self.declare_partials( "CD", - [Dynamic.Mission.MACH, "CL", "cf", "SA1", "SA2", "SA5", "SA6", "SA7"], + [Dynamic.Atmosphere.MACH, "CL", "cf", "SA1", "SA2", "SA5", "SA6", "SA7"], rows=ar, cols=ar, method="cs", @@ -1007,7 +1100,21 @@ def setup_partials(self): ) def compute(self, inputs, outputs): - mach, CL, div_drag_supercrit, cf, SA1, SA2, SA5, SA6, SA7 = inputs.values() + ( + mach, + CL, + div_drag_supercrit, + subsonic_factor, + supersonic_factor, + lift_factor, + zero_lift_factor, + cf, + SA1, + SA2, + SA5, + SA6, + SA7, + ) = inputs.values() mach_div = SA1 + SA2 * CL + div_drag_supercrit @@ -1023,7 +1130,14 @@ def compute(self, inputs, outputs): # induced drag cdi = SA7 * CL**2 - outputs["CD"] = cd0 + cdi + delcdm + CD = cd0 * zero_lift_factor + cdi * lift_factor + delcdm + + # scale drag + idx_sup = np.where(mach >= 1.0) + CD_scaled = CD * subsonic_factor + CD_scaled[idx_sup] = CD[idx_sup] * supersonic_factor + + outputs["CD"] = CD_scaled class LiftCoeff(om.ExplicitComponent): @@ -1037,10 +1151,16 @@ def setup(self): # mission inputs self.add_input("alpha", val=0.0, units="deg", shape=nn, desc="Angle of attack") - self.add_input(Dynamic.Mission.ALTITUDE, val=0.0, - units="ft", shape=nn, desc="Altitude") - self.add_input("lift_curve_slope", units="unitless", - shape=nn, desc="Lift-curve slope") + self.add_input( + Dynamic.Mission.ALTITUDE, + val=0.0, + units="ft", + shape=nn, + desc="Altitude", + ) + self.add_input( + "lift_curve_slope", units="unitless", shape=nn, desc="Lift-curve slope" + ) self.add_input("lift_ratio", units="unitless", shape=nn, desc="Lift ratio") # user inputs @@ -1065,12 +1185,16 @@ def setup(self): # from flaps self.add_input( - "CL_max_flaps", units="unitless", + "CL_max_flaps", + units="unitless", desc="CLMWTO | CLMWLD: Max lift coefficient from flaps model", ) self.add_input( - "dCL_flaps_model", val=0.0, units="unitless", - desc="Delta CL from flaps model") + "dCL_flaps_model", + val=0.0, + units="unitless", + desc="Delta CL from flaps model", + ) # from sizing @@ -1079,30 +1203,40 @@ def setup(self): add_aviary_input(self, Aircraft.Wing.SPAN, val=0.0) self.add_output( - "CL_base", units="unitless", shape=nn, desc="Base lift coefficient") + "CL_base", units="unitless", shape=nn, desc="Base lift coefficient" + ) self.add_output( - "dCL_flaps_full", units="unitless", shape=nn, - desc="CL increment with full flap deflection" + "dCL_flaps_full", + units="unitless", + shape=nn, + desc="CL increment with full flap deflection", ) self.add_output( "alpha_stall", units="deg", shape=nn, desc="Stall angle of attack" ) self.add_output( - "CL_max", units="unitless", shape=nn, desc="Max lift coefficient") + "CL_max", units="unitless", shape=nn, desc="Max lift coefficient" + ) def setup_partials(self): # self.declare_coloring(method="cs", show_summary=False) self.declare_partials("*", "*", dependent=False) ar = np.arange(self.options["num_nodes"]) - dynvars = ["alpha", Dynamic.Mission.ALTITUDE, "lift_curve_slope", "lift_ratio"] + dynvars = [ + "alpha", + Dynamic.Mission.ALTITUDE, + "lift_curve_slope", + "lift_ratio", + ] self.declare_partials("CL_base", ["*"], method="cs") self.declare_partials("CL_base", dynvars, rows=ar, cols=ar, method="cs") self.declare_partials("dCL_flaps_full", ["dCL_flaps_model"], method="cs") self.declare_partials( - "dCL_flaps_full", ["lift_ratio"], rows=ar, cols=ar, method="cs") + "dCL_flaps_full", ["lift_ratio"], rows=ar, cols=ar, method="cs" + ) self.declare_partials("alpha_stall", ["*"], method="cs") self.declare_partials("alpha_stall", dynvars, rows=ar, cols=ar, method="cs") @@ -1149,13 +1283,14 @@ def compute(self, inputs, outputs): ) kclge = np.clip(kclge, 1.0, None) - outputs["CL_base"] = kclge * lift_curve_slope * \ - deg2rad(alpha - alpha0) * (1 + lift_ratio) + outputs["CL_base"] = ( + kclge * lift_curve_slope * deg2rad(alpha - alpha0) * (1 + lift_ratio) + ) outputs["dCL_flaps_full"] = dCL_flaps_model * (1 + lift_ratio) outputs["alpha_stall"] = ( - rad2deg((CL_max_flaps - dCL_flaps_model) / - (kclge * lift_curve_slope)) + alpha0 + rad2deg((CL_max_flaps - dCL_flaps_model) / (kclge * lift_curve_slope)) + + alpha0 ) outputs["CL_max"] = CL_max_flaps * (1 + lift_ratio) @@ -1180,16 +1315,19 @@ def setup(self): "alpha", val=0.0, units="deg", shape=nn, desc="Angle of attack" ) self.add_input( - "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient") + "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient" + ) else: self.add_input( "alpha", val=0.0, units="deg", shape=nn, desc="Angle of attack" ) self.add_output( - "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient") + "CL", val=1.0, units="unitless", shape=nn, desc="Lift coefficient" + ) - self.add_input("lift_curve_slope", units="unitless", - shape=nn, desc="Lift-curve slope") + self.add_input( + "lift_curve_slope", units="unitless", shape=nn, desc="Lift-curve slope" + ) self.add_input("lift_ratio", units="unitless", shape=nn, desc="Lift ratio") add_aviary_input(self, Aircraft.Wing.ZERO_LIFT_ANGLE, val=-1.2) @@ -1198,7 +1336,8 @@ def setup(self): self.add_output("alpha_stall", shape=nn, desc="Stall angle of attack") self.add_output( - "CL_max", units="unitless", shape=nn, desc="Max lift coefficient") + "CL_max", units="unitless", shape=nn, desc="Max lift coefficient" + ) def setup_partials(self): # self.declare_coloring(method="cs", show_summary=False) @@ -1207,17 +1346,26 @@ def setup_partials(self): if self.options["output_alpha"]: self.declare_partials( - "alpha", ["CL", "lift_ratio", "lift_curve_slope"], rows=ar, cols=ar, method="cs" + "alpha", + ["CL", "lift_ratio", "lift_curve_slope"], + rows=ar, + cols=ar, + method="cs", ) self.declare_partials("alpha", [Aircraft.Wing.ZERO_LIFT_ANGLE], method="cs") else: self.declare_partials( - "CL", ["lift_curve_slope", "alpha", "lift_ratio"], rows=ar, cols=ar, method="cs" + "CL", + ["lift_curve_slope", "alpha", "lift_ratio"], + rows=ar, + cols=ar, + method="cs", ) self.declare_partials("CL", [Aircraft.Wing.ZERO_LIFT_ANGLE], method="cs") self.declare_partials( - "alpha_stall", ["lift_curve_slope"], rows=ar, cols=ar, method="cs") + "alpha_stall", ["lift_curve_slope"], rows=ar, cols=ar, method="cs" + ) self.declare_partials( "alpha_stall", [ @@ -1240,7 +1388,9 @@ def compute(self, inputs, outputs): outputs["alpha"] = rad2deg(clw / lift_curve_slope) + alpha0 else: alpha = inputs["alpha"] - outputs["CL"] = lift_curve_slope * deg2rad(alpha - alpha0) * (1 + lift_ratio) + outputs["CL"] = ( + lift_curve_slope * deg2rad(alpha - alpha0) * (1 + lift_ratio) + ) outputs["alpha_stall"] = rad2deg(CL_max_flaps / lift_curve_slope) + alpha0 outputs["CL_max"] = CL_max_flaps * (1 + lift_ratio) @@ -1252,8 +1402,10 @@ 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') + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', + ) self.options.declare( "output_alpha", @@ -1269,8 +1421,9 @@ def initialize(self): "computing them with an atmospherics component. For testing.", ) self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', ) def setup(self): @@ -1278,8 +1431,11 @@ def setup(self): 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"]), + AeroSetup( + num_nodes=nn, + aviary_options=aviary_options, + input_atmos=self.options["input_atmos"], + ), promotes=["*"], ) if self.options["output_alpha"]: @@ -1300,8 +1456,10 @@ 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') + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', + ) self.options.declare( "retract_gear", default=True, @@ -1331,8 +1489,9 @@ def initialize(self): "computing them with an atmospherics component. For testing.", ) self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', ) def setup(self): @@ -1341,28 +1500,40 @@ def setup(self): 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"]), + AeroSetup( + num_nodes=nn, + aviary_options=aviary_options, + input_atmos=self.options["input_atmos"], + ), promotes=["*"], ) aero_ramps = TanhRampComp(time_units='s', num_nodes=nn) - aero_ramps.add_ramp('flap_factor', output_units='unitless', - initial_val=1.0 if self.options['retract_flaps'] else 0.0, - final_val=0.0 if self.options['retract_flaps'] else 1.0) - aero_ramps.add_ramp('gear_factor', output_units='unitless', - initial_val=1.0 if self.options['retract_gear'] else 0.0, - final_val=0.0 if self.options['retract_gear'] else 1.0) - - self.add_subsystem("aero_ramps", - aero_ramps, - promotes_inputs=[("time", "t_curr"), - ("flap_factor:t_init", "t_init_flaps"), - ("flap_factor:t_duration", "dt_flaps"), - ("gear_factor:t_init", "t_init_gear"), - ("gear_factor:t_duration", "dt_gear")], - promotes_outputs=['flap_factor', - 'gear_factor']) + aero_ramps.add_ramp( + 'flap_factor', + output_units='unitless', + initial_val=1.0 if self.options['retract_flaps'] else 0.0, + final_val=0.0 if self.options['retract_flaps'] else 1.0, + ) + aero_ramps.add_ramp( + 'gear_factor', + output_units='unitless', + initial_val=1.0 if self.options['retract_gear'] else 0.0, + final_val=0.0 if self.options['retract_gear'] else 1.0, + ) + + self.add_subsystem( + "aero_ramps", + aero_ramps, + promotes_inputs=[ + ("time", "t_curr"), + ("flap_factor:t_init", "t_init_flaps"), + ("flap_factor:t_duration", "dt_flaps"), + ("gear_factor:t_init", "t_init_gear"), + ("gear_factor:t_duration", "dt_gear"), + ], + promotes_outputs=['flap_factor', 'gear_factor'], + ) if output_alpha: # lift_req -> CL @@ -1380,7 +1551,7 @@ def setup(self): "lift_coef", LiftCoeff(num_nodes=nn), promotes_inputs=["*"], - promotes_outputs=["*"] + promotes_outputs=["*"], ) self.add_subsystem( @@ -1397,7 +1568,7 @@ def setup(self): # dCL_flaps=dict(shape=nn, units='unitless'), flap_factor=dict(shape=nn, units='unitless'), dCL_flaps_full=dict(shape=nn, units='unitless'), - has_diag_partials=True + has_diag_partials=True, ), promotes=["*"], ) @@ -1426,7 +1597,7 @@ def setup(self): gear_factor=dict(shape=nn, units='unitless'), dCD_gear_full=dict(shape=nn, units='unitless'), dCD_flaps_full=dict(shape=nn, units='unitless'), - has_diag_partials=True + has_diag_partials=True, ), promotes=["*"], ) diff --git a/aviary/subsystems/aerodynamics/gasp_based/interference.py b/aviary/subsystems/aerodynamics/gasp_based/interference.py index 2a1fb74ad..4169849f5 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/interference.py +++ b/aviary/subsystems/aerodynamics/gasp_based/interference.py @@ -307,10 +307,9 @@ def setup(self): add_aviary_input(self, Aircraft.Wing.FORM_FACTOR, 1.25) add_aviary_input(self, Aircraft.Wing.AVERAGE_CHORD) - add_aviary_input(self, Dynamic.Mission.MACH, shape=nn) - add_aviary_input(self, Dynamic.Mission.TEMPERATURE, shape=nn) - add_aviary_input(self, Dynamic.Mission.KINEMATIC_VISCOSITY, - shape=nn) + add_aviary_input(self, Dynamic.Atmosphere.MACH, shape=nn) + add_aviary_input(self, Dynamic.Atmosphere.TEMPERATURE, shape=nn) + add_aviary_input(self, Dynamic.Atmosphere.KINEMATIC_VISCOSITY, shape=nn) self.add_input('interference_independent_of_shielded_area') self.add_input('drag_loss_due_to_shielded_wing_area') @@ -321,11 +320,15 @@ def setup_partials(self): nn = self.options["num_nodes"] arange = np.arange(nn) self.declare_partials( - 'wing_fuselage_interference_flat_plate_equivalent', [ - Dynamic.Mission.MACH, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.KINEMATIC_VISCOSITY], - rows=arange, cols=arange) + 'wing_fuselage_interference_flat_plate_equivalent', + [ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, + ], + rows=arange, + cols=arange, + ) self.declare_partials( 'wing_fuselage_interference_flat_plate_equivalent', [ Aircraft.Wing.FORM_FACTOR, @@ -368,16 +371,54 @@ def compute_partials(self, inputs, J): J['wing_fuselage_interference_flat_plate_equivalent', Aircraft.Wing.AVERAGE_CHORD] = \ 2.6*CDWI * CKW * ((np.log10(RELI * CBARW)/7.)**(-3.6))*AREASHIELDWF \ * 1/(np.log(10)*(CBARW)*7) - J['wing_fuselage_interference_flat_plate_equivalent', Dynamic.Mission.MACH] = -CKW * AREASHIELDWF * (((np.log10(RELI * CBARW)/7.)**(-2.6)) * ( - FCFWC*FCFWT * dCFIN_dEM) + CFIN*(-2.6*((np.log10(RELI * CBARW)/7.)**(-3.6)) / (np.log(10)*(RELI)*7)*(dRELI_dEM))) - J['wing_fuselage_interference_flat_plate_equivalent', Dynamic.Mission.TEMPERATURE] = \ - -CDWI * CKW * -2.6*((np.log10(RELI * CBARW)/7.)**(-3.6))*AREASHIELDWF \ - * 1/(np.log(10)*(RELI)*7) * np.sqrt(1.4*GRAV_ENGLISH_GASP*53.32) \ - * EM * .5/(XKV*np.sqrt(T0)) - J['wing_fuselage_interference_flat_plate_equivalent', Dynamic.Mission.KINEMATIC_VISCOSITY] = \ - CDWI * CKW * -2.6*((np.log10(RELI * CBARW)/7.)**(-3.6))*AREASHIELDWF \ - * 1/(np.log(10)*(RELI)*7) * np.sqrt(1.4*GRAV_ENGLISH_GASP*53.32) \ - * EM * np.sqrt(T0) / XKV**2 + J[ + 'wing_fuselage_interference_flat_plate_equivalent', Dynamic.Atmosphere.MACH + ] = ( + -CKW + * AREASHIELDWF + * ( + ((np.log10(RELI * CBARW) / 7.0) ** (-2.6)) * (FCFWC * FCFWT * dCFIN_dEM) + + CFIN + * ( + -2.6 + * ((np.log10(RELI * CBARW) / 7.0) ** (-3.6)) + / (np.log(10) * (RELI) * 7) + * (dRELI_dEM) + ) + ) + ) + J[ + 'wing_fuselage_interference_flat_plate_equivalent', + Dynamic.Atmosphere.TEMPERATURE, + ] = ( + -CDWI + * CKW + * -2.6 + * ((np.log10(RELI * CBARW) / 7.0) ** (-3.6)) + * AREASHIELDWF + * 1 + / (np.log(10) * (RELI) * 7) + * np.sqrt(1.4 * GRAV_ENGLISH_GASP * 53.32) + * EM + * 0.5 + / (XKV * np.sqrt(T0)) + ) + J[ + 'wing_fuselage_interference_flat_plate_equivalent', + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, + ] = ( + CDWI + * CKW + * -2.6 + * ((np.log10(RELI * CBARW) / 7.0) ** (-3.6)) + * AREASHIELDWF + * 1 + / (np.log(10) * (RELI) * 7) + * np.sqrt(1.4 * GRAV_ENGLISH_GASP * 53.32) + * EM + * np.sqrt(T0) + / XKV**2 + ) J['wing_fuselage_interference_flat_plate_equivalent', 'interference_independent_of_shielded_area'] = \ -CDWI * CKW * ((np.log10(RELI * CBARW)/7.)**(-2.6)) diff --git a/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py b/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py index 213b10b9d..c22a99ff1 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py +++ b/aviary/subsystems/aerodynamics/gasp_based/premission_aero.py @@ -23,8 +23,9 @@ class PreMissionAero(om.Group): def initialize(self): self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options' + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', ) def setup(self): @@ -60,9 +61,11 @@ def setup(self): rho={"units": "slug/ft**3"}, kinematic_viscosity={"units": "ft**2/s"}, ), - promotes=["viscosity", - ("kinematic_viscosity", Dynamic.Mission.KINEMATIC_VISCOSITY), - ("rho", Dynamic.Mission.DENSITY)], + promotes=[ + "viscosity", + ("kinematic_viscosity", Dynamic.Atmosphere.KINEMATIC_VISCOSITY), + ("rho", Dynamic.Atmosphere.DENSITY), + ], ) self.add_subsystem( @@ -79,8 +82,11 @@ def setup(self): "flaps_takeoff", FlapsGroup(aviary_options=aviary_options), # slat deflection same for takeoff and landing - promotes_inputs=["*", ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_TAKEOFF), - ("slat_defl", Aircraft.Wing.MAX_SLAT_DEFLECTION_TAKEOFF)], + promotes_inputs=[ + "*", + ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_TAKEOFF), + ("slat_defl", Aircraft.Wing.MAX_SLAT_DEFLECTION_TAKEOFF), + ], promotes_outputs=[ ("CL_max", Mission.Takeoff.LIFT_COEFFICIENT_MAX), ( @@ -96,8 +102,11 @@ def setup(self): self.add_subsystem( "flaps_landing", FlapsGroup(aviary_options=aviary_options), - promotes_inputs=["*", ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_LANDING), - ("slat_defl", Aircraft.Wing.MAX_SLAT_DEFLECTION_LANDING)], + promotes_inputs=[ + "*", + ("flap_defl", Aircraft.Wing.FLAP_DEFLECTION_LANDING), + ("slat_defl", Aircraft.Wing.MAX_SLAT_DEFLECTION_LANDING), + ], promotes_outputs=[ ("CL_max", Mission.Landing.LIFT_COEFFICIENT_MAX), ( diff --git a/aviary/subsystems/aerodynamics/gasp_based/table_based.py b/aviary/subsystems/aerodynamics/gasp_based/table_based.py index 670dfb0f9..5c0d33a5c 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/table_based.py +++ b/aviary/subsystems/aerodynamics/gasp_based/table_based.py @@ -19,16 +19,17 @@ # spaces are replaced with underscores when data tables are read) # "Repeated" aliases allows variables with different cases to match with desired # all-lowercase name -aliases = {Dynamic.Mission.ALTITUDE: ['h', 'alt', 'altitude'], - Dynamic.Mission.MACH: ['m', 'mach'], - 'angle_of_attack': ['alpha', 'angle_of_attack', 'AoA'], - 'flap_deflection': ['flap_deflection'], - 'hob': ['hob'], - 'lift_coefficient': ['cl', 'lift_coefficient'], - 'drag_coefficient': ['cd', 'drag_coefficient'], - 'delta_lift_coefficient': ['delta_cl', 'dcl'], - 'delta_drag_coefficient': ['delta_cd', 'dcd'] - } +aliases = { + Dynamic.Mission.ALTITUDE: ['h', 'alt', 'altitude'], + Dynamic.Atmosphere.MACH: ['m', 'mach'], + 'angle_of_attack': ['alpha', 'angle_of_attack', 'AoA'], + 'flap_deflection': ['flap_deflection'], + 'hob': ['hob'], + 'lift_coefficient': ['cl', 'lift_coefficient'], + 'drag_coefficient': ['cd', 'drag_coefficient'], + 'delta_lift_coefficient': ['delta_cl', 'dcl'], + 'delta_drag_coefficient': ['delta_cd', 'dcd'], +} class TabularCruiseAero(om.Group): @@ -71,17 +72,21 @@ def setup(self): structured=structured, extrapolate=extrapolate) - self.add_subsystem('free_aero_interp', - subsys=interp_comp, - promotes_inputs=[Dynamic.Mission.ALTITUDE, - Dynamic.Mission.MACH, - ('angle_of_attack', 'alpha')] - + extra_promotes, - promotes_outputs=[('lift_coefficient', 'CL'), ('drag_coefficient', 'CD')]) + self.add_subsystem( + 'free_aero_interp', + subsys=interp_comp, + promotes_inputs=[ + Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.MACH, + ('angle_of_attack', 'alpha'), + ] + + extra_promotes, + promotes_outputs=[('lift_coefficient', 'CL'), ('drag_coefficient', 'CD')], + ) self.add_subsystem("forces", AeroForces(num_nodes=nn), promotes=["*"]) - self.set_input_defaults(Dynamic.Mission.MACH, np.zeros(nn)) + self.set_input_defaults(Dynamic.Atmosphere.MACH, np.zeros(nn)) class TabularLowSpeedAero(om.Group): @@ -168,8 +173,11 @@ def setup(self): self.add_subsystem( "interp_free", free_aero_interp, - promotes_inputs=[Dynamic.Mission.ALTITUDE, - Dynamic.Mission.MACH, ('angle_of_attack', 'alpha')], + promotes_inputs=[ + Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.MACH, + ('angle_of_attack', 'alpha'), + ], promotes_outputs=[ ("lift_coefficient", "CL_free"), ("drag_coefficient", "CD_free"), @@ -186,8 +194,11 @@ def setup(self): self.add_subsystem( "interp_flaps", flaps_aero_interp, - promotes_inputs=[('flap_deflection', 'flap_defl'), - Dynamic.Mission.MACH, ('angle_of_attack', 'alpha')], + promotes_inputs=[ + ('flap_deflection', 'flap_defl'), + Dynamic.Atmosphere.MACH, + ('angle_of_attack', 'alpha'), + ], promotes_outputs=[ ("delta_lift_coefficient", "dCL_flaps_full"), ("delta_drag_coefficient", "dCD_flaps_full"), @@ -204,7 +215,11 @@ def setup(self): self.add_subsystem( "interp_ground", ground_aero_interp, - promotes_inputs=[Dynamic.Mission.MACH, ('angle_of_attack', 'alpha'), 'hob'], + promotes_inputs=[ + Dynamic.Atmosphere.MACH, + ('angle_of_attack', 'alpha'), + 'hob', + ], promotes_outputs=[ ("delta_lift_coefficient", "dCL_ground"), ("delta_drag_coefficient", "dCD_ground"), @@ -290,10 +305,10 @@ def setup(self): promotes_inputs=[ "CL", "CD", - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, ] + ["aircraft:*"], - promotes_outputs=[Dynamic.Mission.LIFT, Dynamic.Mission.DRAG], + promotes_outputs=[Dynamic.Vehicle.LIFT, Dynamic.Vehicle.DRAG], ) if self.options["retract_gear"]: @@ -313,7 +328,7 @@ def setup(self): # TODO default flap duration for landing? self.set_input_defaults(Dynamic.Mission.ALTITUDE, np.zeros(nn)) - self.set_input_defaults(Dynamic.Mission.MACH, np.zeros(nn)) + self.set_input_defaults(Dynamic.Atmosphere.MACH, np.zeros(nn)) class GearDragIncrement(om.ExplicitComponent): @@ -396,8 +411,11 @@ def _build_free_aero_interp(num_nodes=0, aero_data=None, connect_training_data=F interp_data = _structure_special_grid(interp_data) - required_inputs = {Dynamic.Mission.ALTITUDE, Dynamic.Mission.MACH, - 'angle_of_attack'} + required_inputs = { + Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.MACH, + 'angle_of_attack', + } required_outputs = {'lift_coefficient', 'drag_coefficient'} missing_variables = [] @@ -439,10 +457,13 @@ def _build_free_aero_interp(num_nodes=0, aero_data=None, connect_training_data=F meta_1d = om.MetaModelStructuredComp(method='1D-lagrange2', vec_size=num_nodes, extrapolate=extrapolate) - meta_1d.add_input(Dynamic.Mission.MACH, 0.0, units="unitless", - shape=num_nodes, - training_data=interp_data.get_val(Dynamic.Mission.MACH, - 'unitless')) + meta_1d.add_input( + Dynamic.Atmosphere.MACH, + 0.0, + units="unitless", + shape=num_nodes, + training_data=interp_data.get_val(Dynamic.Atmosphere.MACH, 'unitless'), + ) meta_1d.add_output('lift_coefficient_max', units="unitless", shape=num_nodes, training_data=cl_max) @@ -468,7 +489,7 @@ def _build_flaps_aero_interp(num_nodes=0, aero_data=None, connect_training_data= interp_data = _structure_special_grid(interp_data) - required_inputs = {'flap_deflection', Dynamic.Mission.MACH, 'angle_of_attack'} + required_inputs = {'flap_deflection', Dynamic.Atmosphere.MACH, 'angle_of_attack'} required_outputs = {'delta_lift_coefficient', 'delta_drag_coefficient'} missing_variables = [] @@ -487,7 +508,7 @@ def _build_flaps_aero_interp(num_nodes=0, aero_data=None, connect_training_data= ) # units don't matter, not using values alpha = np.unique(interp_data.get_val('angle_of_attack', 'deg') ) # units don't matter, not using values - mach = np.unique(interp_data.get_val(Dynamic.Mission.MACH, 'unitless')) + mach = np.unique(interp_data.get_val(Dynamic.Atmosphere.MACH, 'unitless')) dcl_max = np.zeros_like(dcl) shape = (defl.size, mach.size, alpha.size) @@ -522,7 +543,7 @@ def _build_ground_aero_interp(num_nodes=0, aero_data=None, connect_training_data # aero_data is modified in-place, deepcopy required interp_data = aero_data.deepcopy() - required_inputs = {'hob', Dynamic.Mission.MACH, 'angle_of_attack'} + required_inputs = {'hob', Dynamic.Atmosphere.MACH, 'angle_of_attack'} required_outputs = {'delta_lift_coefficient', 'delta_drag_coefficient'} missing_variables = [] @@ -539,7 +560,7 @@ def _build_ground_aero_interp(num_nodes=0, aero_data=None, connect_training_data dcl = interp_data.get_val('delta_lift_coefficient', 'unitless') alpha = np.unique(interp_data.get_val('angle_of_attack', 'deg') ) # units don't matter, not using values - mach = np.unique(interp_data.get_val(Dynamic.Mission.MACH, 'unitless')) + mach = np.unique(interp_data.get_val(Dynamic.Atmosphere.MACH, 'unitless')) hob = np.unique(interp_data.get_val('hob', 'unitless')) dcl_max = np.zeros_like(dcl) diff --git a/aviary/subsystems/aerodynamics/gasp_based/test/test_common.py b/aviary/subsystems/aerodynamics/gasp_based/test/test_common.py index 3ccd22329..674c41ce3 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/test/test_common.py +++ b/aviary/subsystems/aerodynamics/gasp_based/test/test_common.py @@ -21,13 +21,13 @@ def testAeroForces(self): prob.set_val("CL", [1.0, 0.9, 0.8]) prob.set_val("CD", [1.0, 0.95, 0.85]) - prob.set_val(Dynamic.Mission.DYNAMIC_PRESSURE, 1, units="psf") + prob.set_val(Dynamic.Atmosphere.DYNAMIC_PRESSURE, 1, units="psf") prob.set_val(Aircraft.Wing.AREA, 1370.3, units="ft**2") prob.run_model() - lift = prob.get_val(Dynamic.Mission.LIFT) - drag = prob.get_val(Dynamic.Mission.DRAG) + lift = prob.get_val(Dynamic.Vehicle.LIFT) + drag = prob.get_val(Dynamic.Vehicle.DRAG) assert_near_equal(lift, [1370.3, 1233.27, 1096.24]) assert_near_equal(drag, [1370.3, 1301.785, 1164.755]) diff --git a/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py b/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py index 9e97710a3..410df07eb 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py +++ b/aviary/subsystems/aerodynamics/gasp_based/test/test_gaspaero.py @@ -29,7 +29,11 @@ class GASPAeroTest(unittest.TestCase): def test_cruise(self): prob = om.Problem() prob.model.add_subsystem( - "aero", CruiseAero(num_nodes=2, aviary_options=get_option_defaults(), input_atmos=True), promotes=["*"] + "aero", + CruiseAero( + num_nodes=2, aviary_options=get_option_defaults(), input_atmos=True + ), + promotes=["*"], ) prob.setup(check=False, force_alloc_complex=True) @@ -48,10 +52,10 @@ def test_cruise(self): with self.subTest(alt=alt, mach=mach, alpha=alpha): # prob.set_val(Dynamic.Mission.ALTITUDE, alt) - prob.set_val(Dynamic.Mission.MACH, mach) + prob.set_val(Dynamic.Atmosphere.MACH, mach) prob.set_val("alpha", alpha) - prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, row["sos"]) - prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, row["nu"]) + prob.set_val(Dynamic.Atmosphere.SPEED_OF_SOUND, row["sos"]) + prob.set_val(Dynamic.Atmosphere.KINEMATIC_VISCOSITY, row["nu"]) prob.run_model() @@ -65,7 +69,11 @@ def test_cruise(self): def test_ground(self): prob = om.Problem() prob.model.add_subsystem( - "aero", LowSpeedAero(num_nodes=2, aviary_options=get_option_defaults(), input_atmos=True), promotes=["*"] + "aero", + LowSpeedAero( + num_nodes=2, aviary_options=get_option_defaults(), input_atmos=True + ), + promotes=["*"], ) prob.setup(check=False, force_alloc_complex=True) @@ -85,11 +93,11 @@ def test_ground(self): alpha = row["alpha"] with self.subTest(ilift=ilift, alt=alt, mach=mach, alpha=alpha): - prob.set_val(Dynamic.Mission.MACH, mach) + prob.set_val(Dynamic.Atmosphere.MACH, mach) prob.set_val(Dynamic.Mission.ALTITUDE, alt) prob.set_val("alpha", alpha) - prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, row["sos"]) - prob.set_val(Dynamic.Mission.KINEMATIC_VISCOSITY, row["nu"]) + prob.set_val(Dynamic.Atmosphere.SPEED_OF_SOUND, row["sos"]) + prob.set_val(Dynamic.Atmosphere.KINEMATIC_VISCOSITY, row["nu"]) # note we're just letting the time ramps for flaps/gear default to the # takeoff config such that the default times correspond to full flap and @@ -100,8 +108,8 @@ def test_ground(self): prob.set_val("CL_max_flaps", setup_data["clmwto"]) prob.set_val("dCL_flaps_model", setup_data["dclto"]) prob.set_val("dCD_flaps_model", setup_data["dcdto"]) - prob.set_val("aero_ramps.flap_factor:final_val", 1.) - prob.set_val("aero_ramps.gear_factor:final_val", 1.) + prob.set_val("aero_ramps.flap_factor:final_val", 1.0) + prob.set_val("aero_ramps.gear_factor:final_val", 1.0) else: # landing flaps config prob.set_val("flap_defl", setup_data["delfld"]) @@ -124,7 +132,7 @@ def test_ground_alpha_out(self): "alpha_in", LowSpeedAero(aviary_options=get_option_defaults()), promotes_inputs=["*", ("alpha", "alpha_in")], - promotes_outputs=[(Dynamic.Mission.LIFT, "lift_req")], + promotes_outputs=[(Dynamic.Vehicle.LIFT, "lift_req")], ) prob.model.add_subsystem( @@ -144,7 +152,7 @@ def test_ground_alpha_out(self): prob.set_val(Aircraft.Wing.FLAP_CHORD_RATIO, setup_data["cfoc"]) prob.set_val(Mission.Design.GROSS_MASS, setup_data["wgto"]) - prob.set_val(Dynamic.Mission.MACH, 0.1) + prob.set_val(Dynamic.Atmosphere.MACH, 0.1) prob.set_val(Dynamic.Mission.ALTITUDE, 10) prob.set_val("alpha_in", 5) prob.run_model() diff --git a/aviary/subsystems/aerodynamics/gasp_based/test/test_interference.py b/aviary/subsystems/aerodynamics/gasp_based/test/test_interference.py index 06a532520..e301f8524 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/test/test_interference.py +++ b/aviary/subsystems/aerodynamics/gasp_based/test/test_interference.py @@ -147,7 +147,7 @@ def test_complete_group(self): USatm1976Comp(num_nodes=nn), promotes_inputs=[("h", Dynamic.Mission.ALTITUDE)], promotes_outputs=['rho', "viscosity", - ("temp", Dynamic.Mission.TEMPERATURE)], + ("temp", Dynamic.Atmosphere.TEMPERATURE)], ) prob.model.add_subsystem( "kin_visc", @@ -158,7 +158,7 @@ def test_complete_group(self): nu={"units": "ft**2/s", "shape": nn}, has_diag_partials=True, ), - promotes=["*", ('nu', Dynamic.Mission.KINEMATIC_VISCOSITY)], + promotes=["*", ('nu', Dynamic.Atmosphere.KINEMATIC_VISCOSITY)], ) prob.model.add_subsystem( "comp", WingFuselageInterferenceMission(num_nodes=nn), @@ -167,7 +167,7 @@ def test_complete_group(self): prob.set_val(Aircraft.Wing.FORM_FACTOR, 1.25) prob.set_val(Aircraft.Wing.AVERAGE_CHORD, 12) - prob.set_val(Dynamic.Mission.MACH, (.6, .65)) + prob.set_val(Dynamic.Atmosphere.MACH, (.6, .65)) prob.set_val(Dynamic.Mission.ALTITUDE, (30000, 30000)) prob.set_val('interference_independent_of_shielded_area', 0.35794891) prob.set_val('drag_loss_due_to_shielded_wing_area', 83.53366) diff --git a/aviary/subsystems/aerodynamics/gasp_based/test/test_table_based.py b/aviary/subsystems/aerodynamics/gasp_based/test/test_table_based.py index cfa949f19..3d9ad91cb 100644 --- a/aviary/subsystems/aerodynamics/gasp_based/test/test_table_based.py +++ b/aviary/subsystems/aerodynamics/gasp_based/test/test_table_based.py @@ -25,12 +25,13 @@ def test_climb(self): prob.setup(force_alloc_complex=True) prob.set_val( - Dynamic.Mission.MACH, [ - 0.381, 0.384, 0.391, 0.399, 0.8, 0.8, 0.8, 0.8]) + Dynamic.Atmosphere.MACH, [0.381, 0.384, 0.391, 0.399, 0.8, 0.8, 0.8, 0.8] + ) prob.set_val("alpha", [5.19, 5.19, 5.19, 5.18, 3.58, 3.81, 4.05, 4.18]) prob.set_val( - Dynamic.Mission.ALTITUDE, [ - 500, 1000, 2000, 3000, 35000, 36000, 37000, 37500]) + Dynamic.Mission.ALTITUDE, + [500, 1000, 2000, 3000, 35000, 36000, 37000, 37500], + ) prob.run_model() cl_exp = np.array( @@ -55,7 +56,7 @@ def test_cruise(self): prob.model = TabularCruiseAero(num_nodes=2, aero_data=fp) prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.MACH, [0.8, 0.8]) + prob.set_val(Dynamic.Atmosphere.MACH, [0.8, 0.8]) prob.set_val("alpha", [4.216, 3.146]) prob.set_val(Dynamic.Mission.ALTITUDE, [37500, 37500]) prob.run_model() @@ -101,7 +102,7 @@ def test_groundroll(self): prob.set_val("t_curr", [0.0, 1.0, 2.0, 3.0]) prob.set_val(Dynamic.Mission.ALTITUDE, 0) - prob.set_val(Dynamic.Mission.MACH, [0.0, 0.009, 0.018, 0.026]) + prob.set_val(Dynamic.Atmosphere.MACH, [0.0, 0.009, 0.018, 0.026]) prob.set_val("alpha", 0) # TODO set q if we want to test lift/drag forces @@ -143,8 +144,9 @@ def test_takeoff(self): alts = [44.2, 62.7, 84.6, 109.7, 373.0, 419.4, 465.3, 507.8] prob.set_val(Dynamic.Mission.ALTITUDE, alts) prob.set_val( - Dynamic.Mission.MACH, [ - 0.257, 0.260, 0.263, 0.265, 0.276, 0.277, 0.279, 0.280]) + Dynamic.Atmosphere.MACH, + [0.257, 0.260, 0.263, 0.265, 0.276, 0.277, 0.279, 0.280], + ) prob.set_val("alpha", [8.94, 8.74, 8.44, 8.24, 6.45, 6.34, 6.76, 7.59]) # TODO set q if we want to test lift/drag forces diff --git a/aviary/subsystems/atmosphere/atmosphere.py b/aviary/subsystems/atmosphere/atmosphere.py index 2e47e5974..efefcb4b2 100644 --- a/aviary/subsystems/atmosphere/atmosphere.py +++ b/aviary/subsystems/atmosphere/atmosphere.py @@ -21,7 +21,7 @@ def initialize(self): self.options.declare( 'h_def', values=('geopotential', 'geodetic'), - default='geopotential', + default='geodetic', desc='The definition of altitude provided as input to the component. If ' '"geodetic", it will be converted to geopotential based on Equation 19 in ' 'the original standard.', @@ -57,10 +57,10 @@ def setup(self): promotes_inputs=[('h', Dynamic.Mission.ALTITUDE)], promotes_outputs=[ '*', - ('sos', Dynamic.Mission.SPEED_OF_SOUND), - ('rho', Dynamic.Mission.DENSITY), - ('temp', Dynamic.Mission.TEMPERATURE), - ('pres', Dynamic.Mission.STATIC_PRESSURE), + ('sos', Dynamic.Atmosphere.SPEED_OF_SOUND), + ('rho', Dynamic.Atmosphere.DENSITY), + ('temp', Dynamic.Atmosphere.TEMPERATURE), + ('pres', Dynamic.Atmosphere.STATIC_PRESSURE), ], ) diff --git a/aviary/subsystems/atmosphere/flight_conditions.py b/aviary/subsystems/atmosphere/flight_conditions.py index 66b12a217..a83d535d5 100644 --- a/aviary/subsystems/atmosphere/flight_conditions.py +++ b/aviary/subsystems/atmosphere/flight_conditions.py @@ -27,20 +27,20 @@ def setup(self): arange = np.arange(self.options["num_nodes"]) self.add_input( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, val=np.zeros(nn), units="slug/ft**3", desc="density of air", ) self.add_input( - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.SPEED_OF_SOUND, val=np.zeros(nn), units="ft/s", desc="speed of sound", ) self.add_output( - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, val=np.zeros(nn), units="lbf/ft**2", desc="dynamic pressure", @@ -60,27 +60,27 @@ def setup(self): desc="equivalent air speed", ) self.add_output( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless", desc="mach number", ) self.declare_partials( - Dynamic.Mission.DYNAMIC_PRESSURE, - [Dynamic.Mission.DENSITY, Dynamic.Mission.VELOCITY], + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + [Dynamic.Atmosphere.DENSITY, Dynamic.Mission.VELOCITY], rows=arange, cols=arange, ) self.declare_partials( - Dynamic.Mission.MACH, - [Dynamic.Mission.SPEED_OF_SOUND, Dynamic.Mission.VELOCITY], + Dynamic.Atmosphere.MACH, + [Dynamic.Atmosphere.SPEED_OF_SOUND, Dynamic.Mission.VELOCITY], rows=arange, cols=arange, ) self.declare_partials( "EAS", - [Dynamic.Mission.VELOCITY, Dynamic.Mission.DENSITY], + [Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.DENSITY], rows=arange, cols=arange, ) @@ -98,37 +98,37 @@ def setup(self): desc="true air speed", ) self.add_output( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless", desc="mach number", ) self.declare_partials( - Dynamic.Mission.DYNAMIC_PRESSURE, - [Dynamic.Mission.DENSITY, "EAS"], + Dynamic.Atmosphere.DYNAMIC_PRESSURE, + [Dynamic.Atmosphere.DENSITY, "EAS"], rows=arange, cols=arange, ) self.declare_partials( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, [ - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.SPEED_OF_SOUND, "EAS", - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, ], rows=arange, cols=arange, ) self.declare_partials( Dynamic.Mission.VELOCITY, - [Dynamic.Mission.DENSITY, "EAS"], + [Dynamic.Atmosphere.DENSITY, "EAS"], rows=arange, cols=arange, ) elif in_type is SpeedType.MACH: self.add_input( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, val=np.zeros(nn), units="unitless", desc="mach number", @@ -147,27 +147,27 @@ def setup(self): ) self.declare_partials( - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, [ - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.MACH, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DENSITY, ], rows=arange, cols=arange, ) self.declare_partials( Dynamic.Mission.VELOCITY, - [Dynamic.Mission.SPEED_OF_SOUND, Dynamic.Mission.MACH], + [Dynamic.Atmosphere.SPEED_OF_SOUND, Dynamic.Atmosphere.MACH], rows=arange, cols=arange, ) self.declare_partials( "EAS", [ - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.MACH, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.DENSITY, ], rows=arange, cols=arange, @@ -177,50 +177,54 @@ def compute(self, inputs, outputs): in_type = self.options["input_speed_type"] - rho = inputs[Dynamic.Mission.DENSITY] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + rho = inputs[Dynamic.Atmosphere.DENSITY] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] if in_type is SpeedType.TAS: TAS = inputs[Dynamic.Mission.VELOCITY] - outputs[Dynamic.Mission.MACH] = mach = TAS / sos + outputs[Dynamic.Atmosphere.MACH] = mach = TAS / sos outputs["EAS"] = TAS * (rho / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 - outputs[Dynamic.Mission.DYNAMIC_PRESSURE] = 0.5 * rho * TAS**2 + outputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] = 0.5 * rho * TAS**2 elif in_type is SpeedType.EAS: EAS = inputs["EAS"] outputs[Dynamic.Mission.VELOCITY] = TAS = ( EAS / (rho / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 ) - outputs[Dynamic.Mission.MACH] = mach = TAS / sos - outputs[Dynamic.Mission.DYNAMIC_PRESSURE] = ( + outputs[Dynamic.Atmosphere.MACH] = mach = TAS / sos + outputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] = ( 0.5 * EAS**2 * constants.RHO_SEA_LEVEL_ENGLISH ) elif in_type is SpeedType.MACH: - mach = inputs[Dynamic.Mission.MACH] + mach = inputs[Dynamic.Atmosphere.MACH] outputs[Dynamic.Mission.VELOCITY] = TAS = sos * mach outputs["EAS"] = TAS * (rho / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 - outputs[Dynamic.Mission.DYNAMIC_PRESSURE] = 0.5 * rho * sos**2 * mach**2 + outputs[Dynamic.Atmosphere.DYNAMIC_PRESSURE] = 0.5 * rho * sos**2 * mach**2 def compute_partials(self, inputs, J): in_type = self.options["input_speed_type"] - rho = inputs[Dynamic.Mission.DENSITY] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + rho = inputs[Dynamic.Atmosphere.DENSITY] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] if in_type is SpeedType.TAS: TAS = inputs[Dynamic.Mission.VELOCITY] - J[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.VELOCITY] = rho * TAS - J[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.DENSITY] = 0.5 * TAS**2 + J[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Mission.VELOCITY] = rho * TAS + J[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.DENSITY] = ( + 0.5 * TAS**2 + ) - J[Dynamic.Mission.MACH, Dynamic.Mission.VELOCITY] = 1 / sos - J[Dynamic.Mission.MACH, Dynamic.Mission.SPEED_OF_SOUND] = -TAS / sos**2 + J[Dynamic.Atmosphere.MACH, Dynamic.Mission.VELOCITY] = 1 / sos + J[Dynamic.Atmosphere.MACH, Dynamic.Atmosphere.SPEED_OF_SOUND] = ( + -TAS / sos**2 + ) J["EAS", Dynamic.Mission.VELOCITY] = ( rho / constants.RHO_SEA_LEVEL_ENGLISH ) ** 0.5 - J["EAS", Dynamic.Mission.DENSITY] = ( + J["EAS", Dynamic.Atmosphere.DENSITY] = ( TAS * 0.5 * (rho ** (-0.5) / constants.RHO_SEA_LEVEL_ENGLISH**0.5) ) @@ -231,36 +235,38 @@ def compute_partials(self, inputs, J): dTAS_dRho = -0.5 * EAS * constants.RHO_SEA_LEVEL_ENGLISH**0.5 / rho**1.5 dTAS_dEAS = 1 / (rho / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 - J[Dynamic.Mission.DYNAMIC_PRESSURE, "EAS"] = ( + J[Dynamic.Atmosphere.DYNAMIC_PRESSURE, "EAS"] = ( EAS * constants.RHO_SEA_LEVEL_ENGLISH ) - J[Dynamic.Mission.MACH, "EAS"] = dTAS_dEAS / sos - J[Dynamic.Mission.MACH, Dynamic.Mission.DENSITY] = dTAS_dRho / sos - J[Dynamic.Mission.MACH, Dynamic.Mission.SPEED_OF_SOUND] = -TAS / sos**2 - J[Dynamic.Mission.VELOCITY, Dynamic.Mission.DENSITY] = dTAS_dRho + J[Dynamic.Atmosphere.MACH, "EAS"] = dTAS_dEAS / sos + J[Dynamic.Atmosphere.MACH, Dynamic.Atmosphere.DENSITY] = dTAS_dRho / sos + J[Dynamic.Atmosphere.MACH, Dynamic.Atmosphere.SPEED_OF_SOUND] = ( + -TAS / sos**2 + ) + J[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.DENSITY] = dTAS_dRho J[Dynamic.Mission.VELOCITY, "EAS"] = dTAS_dEAS elif in_type is SpeedType.MACH: - mach = inputs[Dynamic.Mission.MACH] + mach = inputs[Dynamic.Atmosphere.MACH] TAS = sos * mach - J[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.SPEED_OF_SOUND] = ( - rho * sos * mach**2 - ) - J[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.MACH] = ( + J[ + Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.SPEED_OF_SOUND + ] = (rho * sos * mach**2) + J[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.MACH] = ( rho * sos**2 * mach ) - J[Dynamic.Mission.DYNAMIC_PRESSURE, Dynamic.Mission.DENSITY] = ( + J[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.DENSITY] = ( 0.5 * sos**2 * mach**2 ) - J[Dynamic.Mission.VELOCITY, Dynamic.Mission.SPEED_OF_SOUND] = mach - J[Dynamic.Mission.VELOCITY, Dynamic.Mission.MACH] = sos - J["EAS", Dynamic.Mission.SPEED_OF_SOUND] = ( + J[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.SPEED_OF_SOUND] = mach + J[Dynamic.Mission.VELOCITY, Dynamic.Atmosphere.MACH] = sos + J["EAS", Dynamic.Atmosphere.SPEED_OF_SOUND] = ( mach * (rho / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 ) - J["EAS", Dynamic.Mission.MACH] = ( + J["EAS", Dynamic.Atmosphere.MACH] = ( sos * (rho / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 ) - J["EAS", Dynamic.Mission.DENSITY] = ( + J["EAS", Dynamic.Atmosphere.DENSITY] = ( TAS * (1 / constants.RHO_SEA_LEVEL_ENGLISH) ** 0.5 * 0.5 * rho ** (-0.5) ) diff --git a/aviary/subsystems/atmosphere/test/test_flight_conditions.py b/aviary/subsystems/atmosphere/test/test_flight_conditions.py index 4cfc41c09..e4b6b8ce1 100644 --- a/aviary/subsystems/atmosphere/test/test_flight_conditions.py +++ b/aviary/subsystems/atmosphere/test/test_flight_conditions.py @@ -21,10 +21,10 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, val=1.22 * np.ones(2), units="kg/m**3" + Dynamic.Atmosphere.DENSITY, val=1.22 * np.ones(2), units="kg/m**3" ) self.prob.model.set_input_defaults( - Dynamic.Mission.SPEED_OF_SOUND, val=344 * np.ones(2), units="m/s" + Dynamic.Atmosphere.SPEED_OF_SOUND, val=344 * np.ones(2), units="m/s" ) self.prob.model.set_input_defaults( Dynamic.Mission.VELOCITY, val=344 * np.ones(2), units="m/s" @@ -37,9 +37,9 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.DYNAMIC_PRESSURE], 1507.6 * np.ones(2), tol + self.prob[Dynamic.Atmosphere.DYNAMIC_PRESSURE], 1507.6 * np.ones(2), tol ) - assert_near_equal(self.prob[Dynamic.Mission.MACH], np.ones(2), tol) + assert_near_equal(self.prob[Dynamic.Atmosphere.MACH], np.ones(2), tol) assert_near_equal( self.prob.get_val("EAS", units="m/s"), 343.3 * np.ones(2), tol ) @@ -60,10 +60,10 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, val=1.05 * np.ones(2), units="kg/m**3" + Dynamic.Atmosphere.DENSITY, val=1.05 * np.ones(2), units="kg/m**3" ) self.prob.model.set_input_defaults( - Dynamic.Mission.SPEED_OF_SOUND, val=344 * np.ones(2), units="m/s" + Dynamic.Atmosphere.SPEED_OF_SOUND, val=344 * np.ones(2), units="m/s" ) self.prob.model.set_input_defaults( "EAS", val=318.4821143 * np.ones(2), units="m/s" @@ -76,12 +76,12 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.DYNAMIC_PRESSURE], 1297.54 * np.ones(2), tol + self.prob[Dynamic.Atmosphere.DYNAMIC_PRESSURE], 1297.54 * np.ones(2), tol ) assert_near_equal( self.prob[Dynamic.Mission.VELOCITY], 1128.61 * np.ones(2), tol ) - assert_near_equal(self.prob[Dynamic.Mission.MACH], np.ones(2), tol) + assert_near_equal(self.prob[Dynamic.Atmosphere.MACH], np.ones(2), tol) partial_data = self.prob.check_partials(out_stream=None, method="cs") assert_check_partials(partial_data, atol=1e-8, rtol=1e-8) @@ -98,13 +98,13 @@ def setUp(self): ) self.prob.model.set_input_defaults( - Dynamic.Mission.DENSITY, val=1.05 * np.ones(2), units="kg/m**3" + Dynamic.Atmosphere.DENSITY, val=1.05 * np.ones(2), units="kg/m**3" ) self.prob.model.set_input_defaults( - Dynamic.Mission.SPEED_OF_SOUND, val=344 * np.ones(2), units="m/s" + Dynamic.Atmosphere.SPEED_OF_SOUND, val=344 * np.ones(2), units="m/s" ) self.prob.model.set_input_defaults( - Dynamic.Mission.MACH, val=np.ones(2), units="unitless" + Dynamic.Atmosphere.MACH, val=np.ones(2), units="unitless" ) self.prob.setup(check=False, force_alloc_complex=True) @@ -114,7 +114,7 @@ def test_case1(self): self.prob.run_model() assert_near_equal( - self.prob[Dynamic.Mission.DYNAMIC_PRESSURE], 1297.54 * np.ones(2), tol + self.prob[Dynamic.Atmosphere.DYNAMIC_PRESSURE], 1297.54 * np.ones(2), tol ) assert_near_equal( self.prob[Dynamic.Mission.VELOCITY], 1128.61 * np.ones(2), tol diff --git a/aviary/subsystems/energy/battery_builder.py b/aviary/subsystems/energy/battery_builder.py index ffc25bd20..8a8012e18 100644 --- a/aviary/subsystems/energy/battery_builder.py +++ b/aviary/subsystems/energy/battery_builder.py @@ -19,9 +19,9 @@ class BatteryBuilder(SubsystemBuilderBase): get_mass_names(self) -> list: Returns the name of variable Aircraft.Battery.MASS as a list get_states(self) -> dict: - Returns a dictionary of the subsystem's states, where the keys are the names - of the state variables, and the values are dictionaries that contain the units - for the state variable and any additional keyword arguments required by OpenMDAO + Returns a dictionary of the subsystem's states, where the keys are the names + of the state variables, and the values are dictionaries that contain the units + for the state variable and any additional keyword arguments required by OpenMDAO for the state variable. get_constraints(self) -> dict: Returns a dictionary of constraints for the battery subsystem. @@ -39,43 +39,77 @@ def get_mass_names(self): def build_mission(self, num_nodes, aviary_inputs=None) -> om.Group: battery_group = om.Group() # Here, the efficiency variable is used as an overall efficiency for the battery - soc = om.ExecComp('state_of_charge = (energy_capacity - (cumulative_electric_energy_used/efficiency)) / energy_capacity', - state_of_charge={'val': np.zeros( - num_nodes), 'units': 'unitless'}, - energy_capacity={'val': 10.0, 'units': 'kJ'}, - cumulative_electric_energy_used={ - 'val': np.zeros(num_nodes), 'units': 'kJ'}, - efficiency={'val': 0.95, 'units': 'unitless'}, - has_diag_partials=True) - - battery_group.add_subsystem('state_of_charge', - subsys=soc, - promotes_inputs=[('energy_capacity', Aircraft.Battery.ENERGY_CAPACITY), - ('cumulative_electric_energy_used', - Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED), - ('efficiency', Aircraft.Battery.EFFICIENCY)], - promotes_outputs=[('state_of_charge', Dynamic.Mission.BATTERY_STATE_OF_CHARGE)]) + soc = om.ExecComp( + 'state_of_charge = (energy_capacity - (cumulative_electric_energy_used/efficiency)) / energy_capacity', + state_of_charge={ + 'val': np.zeros(num_nodes), + 'units': 'unitless'}, + energy_capacity={ + 'val': 10.0, + 'units': 'kJ'}, + cumulative_electric_energy_used={ + 'val': np.zeros(num_nodes), + 'units': 'kJ'}, + efficiency={ + 'val': 0.95, + 'units': 'unitless'}, + has_diag_partials=True) + + battery_group.add_subsystem( + 'state_of_charge', + subsys=soc, + promotes_inputs=[ + ('energy_capacity', Aircraft.Battery.ENERGY_CAPACITY), + ( + 'cumulative_electric_energy_used', + Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED, + ), + ('efficiency', Aircraft.Battery.EFFICIENCY), + ], + promotes_outputs=[ + ('state_of_charge', Dynamic.Vehicle.BATTERY_STATE_OF_CHARGE) + ], + ) return battery_group def get_states(self): - state_dict = {Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED: {'fix_initial': True, - 'fix_final': False, - 'lower': 0.0, - 'ref': 1e4, - 'defect_ref': 1e6, - 'units': 'kJ', - 'rate_source': Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, - 'input_initial': 0.0}} + # need to add subsystem name to target name ('battery.') for state due + # to issue where non aircraft or mission variables are not fully promoted + # TODO fix this by not promoting only 'aircraft:*' and 'mission:*' + state_dict = { + Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED: { + 'fix_initial': True, + 'fix_final': False, + 'lower': 0.0, + 'ref': 1e4, + 'defect_ref': 1e6, + 'units': 'kJ', + 'rate_source': Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, + 'input_initial': 0.0, + 'targets': f'{self.name}.{Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED}', + }} return state_dict def get_constraints(self): constraint_dict = { - # Can add constraints here; state of charge is a common one in many battery applications - f'battery.{Dynamic.Mission.BATTERY_STATE_OF_CHARGE}': - {'type': 'boundary', - 'loc': 'final', - 'lower': 0.2}, + # Can add constraints here; state of charge is a common one in many + # battery applications + f'{self.name}.{Dynamic.Vehicle.BATTERY_STATE_OF_CHARGE}': { + 'type': 'boundary', + 'loc': 'final', + 'lower': 0.2, + }, } return constraint_dict + + def get_parameters(self, aviary_inputs=None, phase_info=None): + + params = { + Aircraft.Battery.ENERGY_CAPACITY: { + 'val': 0.0, + 'units': 'kJ', + }, + } + return params diff --git a/aviary/subsystems/energy/test/test_battery.py b/aviary/subsystems/energy/test/test_battery.py index 8d6ad7245..307335bc0 100644 --- a/aviary/subsystems/energy/test/test_battery.py +++ b/aviary/subsystems/energy/test/test_battery.py @@ -54,15 +54,18 @@ def test_battery_mission(self): av.Aircraft.Battery.ENERGY_CAPACITY, 10_000, units='kJ') prob.model.set_input_defaults( av.Aircraft.Battery.EFFICIENCY, efficiency, units='unitless') - prob.model.set_input_defaults(av.Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED, [ - 0, 2_000, 5_000, 9_500], units='kJ') + prob.model.set_input_defaults( + av.Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED, + [0, 2_000, 5_000, 9_500], + units='kJ', + ) prob.setup(force_alloc_complex=True) prob.run_model() soc_expected = np.array([1., 0.7894736842105263, 0.4736842105263159, 0.]) - soc = prob.get_val(av.Dynamic.Mission.BATTERY_STATE_OF_CHARGE, 'unitless') + soc = prob.get_val(av.Dynamic.Vehicle.BATTERY_STATE_OF_CHARGE, 'unitless') assert_near_equal(soc, soc_expected, tolerance=1e-10) diff --git a/aviary/subsystems/mass/flops_based/engine.py b/aviary/subsystems/mass/flops_based/engine.py index 34c792f6c..ac9644327 100644 --- a/aviary/subsystems/mass/flops_based/engine.py +++ b/aviary/subsystems/mass/flops_based/engine.py @@ -7,7 +7,7 @@ # TODO should additional misc mass be separated out into a separate component? - +# TODO include estimation for baseline (unscaled) mass if not provided (NTRS paper on FLOPS equations pg. 30) class EngineMass(om.ExplicitComponent): ''' diff --git a/aviary/subsystems/mass/gasp_based/test/test_fixed.py b/aviary/subsystems/mass/gasp_based/test/test_fixed.py index 522d7d469..064e3e1a3 100644 --- a/aviary/subsystems/mass/gasp_based/test/test_fixed.py +++ b/aviary/subsystems/mass/gasp_based/test/test_fixed.py @@ -1682,7 +1682,7 @@ def test_case1(self): if __name__ == "__main__": - unittest.main() + # unittest.main() # test = GearTestCaseMultiengine() - # test = EngineTestCaseMultiEngine() - # test.test_case_1() + test = EngineTestCaseMultiEngine() + test.test_case_1() diff --git a/aviary/subsystems/propulsion/engine_deck.py b/aviary/subsystems/propulsion/engine_deck.py index bd059e3ab..024d98a9d 100644 --- a/aviary/subsystems/propulsion/engine_deck.py +++ b/aviary/subsystems/propulsion/engine_deck.py @@ -893,14 +893,18 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: alt_table, packed_data[ALTITUDE][M, A, 0]) # add inputs and outputs to interpolator - interp_throttles.add_input(Dynamic.Mission.MACH, - mach_table, - units='unitless', - desc='Current flight Mach number') - interp_throttles.add_input(Dynamic.Mission.ALTITUDE, - alt_table, - units=units[ALTITUDE], - desc='Current flight altitude') + interp_throttles.add_input( + Dynamic.Atmosphere.MACH, + mach_table, + units='unitless', + desc='Current flight Mach number', + ) + interp_throttles.add_input( + Dynamic.Mission.ALTITUDE, + alt_table, + units=units[ALTITUDE], + desc='Current flight altitude', + ) if not self.global_throttle: interp_throttles.add_output('throttle_max', self.throttle_max, @@ -919,14 +923,18 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: max_thrust_engine = om.MetaModelSemiStructuredComp( method=interp_method, extrapolate=False, vec_size=num_nodes) - max_thrust_engine.add_input(Dynamic.Mission.MACH, - self.data[MACH], - units='unitless', - desc='Current flight Mach number') - max_thrust_engine.add_input(Dynamic.Mission.ALTITUDE, - self.data[ALTITUDE], - units=units[ALTITUDE], - desc='Current flight altitude') + max_thrust_engine.add_input( + Dynamic.Atmosphere.MACH, + self.data[MACH], + units='unitless', + desc='Current flight Mach number', + ) + max_thrust_engine.add_input( + Dynamic.Mission.ALTITUDE, + self.data[ALTITUDE], + units=units[ALTITUDE], + desc='Current flight altitude', + ) # replace throttle coming from mission with max value based on flight condition max_thrust_engine.add_input('throttle_max', self.data[THROTTLE], @@ -958,7 +966,7 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: # add created subsystems to engine_group outputs = [] if getattr(self, 'use_t4', False): - outputs.append(Dynamic.Mission.TEMPERATURE_T4) + outputs.append(Dynamic.Vehicle.Propulsion.TEMPERATURE_T4) engine_group.add_subsystem('interpolation', engine, @@ -974,9 +982,9 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: 'uncorrect_shaft_power', subsys=UncorrectData(num_nodes=num_nodes, aviary_options=self.options), promotes_inputs=[ - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, - Dynamic.Mission.MACH, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, ], ) @@ -1009,9 +1017,9 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: num_nodes=num_nodes, aviary_options=self.options ), promotes_inputs=[ - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE, - Dynamic.Mission.MACH, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + Dynamic.Atmosphere.MACH, ], ) @@ -1030,7 +1038,7 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: aviary_options=self.options, engine_variables=engine_outputs, ), - promotes_inputs=[Aircraft.Engine.SCALE_FACTOR, Dynamic.Mission.MACH], + promotes_inputs=[Aircraft.Engine.SCALE_FACTOR, Dynamic.Atmosphere.MACH], promotes_outputs=['*'], ) @@ -1070,7 +1078,13 @@ def build_mission(self, num_nodes, aviary_inputs) -> om.Group: return engine_group def get_parameters(self): - params = {Aircraft.Engine.SCALE_FACTOR: {'static_target': True}} + params = { + Aircraft.Engine.SCALE_FACTOR: { + 'val': 1.0, + 'units': 'unitless', + 'static_target': True, + } + } return params def report(self, problem, reports_file, **kwargs): diff --git a/aviary/subsystems/propulsion/engine_scaling.py b/aviary/subsystems/propulsion/engine_scaling.py index 2366aff8a..556df4603 100644 --- a/aviary/subsystems/propulsion/engine_scaling.py +++ b/aviary/subsystems/propulsion/engine_scaling.py @@ -56,8 +56,12 @@ def setup(self): add_aviary_input(self, Aircraft.Engine.SCALE_FACTOR, val=1.0) - self.add_input(Dynamic.Mission.MACH, val=np.zeros(nn), - desc='current Mach number', units='unitless') + self.add_input( + Dynamic.Atmosphere.MACH, + val=np.zeros(nn), + desc='current Mach number', + units='unitless', + ) # loop through all variables, special handling for fuel flow to output negative version # add outputs for 'max' counterpart of variables that have them @@ -71,7 +75,7 @@ def setup(self): if variable is FUEL_FLOW: self.add_output( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, val=np.zeros(nn), units=engine_variables[variable], ) @@ -113,7 +117,7 @@ def compute(self, inputs, outputs): # thrust-based engine scaling factor engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] - mach_number = inputs[Dynamic.Mission.MACH] + mach_number = inputs[Dynamic.Atmosphere.MACH] scale_factor = 1 fuel_flow_scale_factor = np.ones(nn, dtype=engine_scale_factor.dtype) @@ -144,7 +148,7 @@ def compute(self, inputs, outputs): for variable in engine_variables: if variable not in skip_variables: if variable is FUEL_FLOW: - outputs[Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE] = -( + outputs[Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE] = -( inputs['fuel_flow_rate_unscaled'] * fuel_flow_scale_factor + constant_fuel_flow ) @@ -170,13 +174,13 @@ def setup_partials(self): if variable not in skip_variables: if variable is FUEL_FLOW: self.declare_partials( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, Aircraft.Engine.SCALE_FACTOR, rows=r, cols=c, ) self.declare_partials( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, 'fuel_flow_rate_unscaled', rows=r, cols=r, @@ -223,7 +227,7 @@ def compute_partials(self, inputs, J): linear_fuel_term = options.get_val(Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM) mission_fuel_scaler = options.get_val(Mission.Summary.FUEL_FLOW_SCALER) - mach_number = inputs[Dynamic.Mission.MACH] + mach_number = inputs[Dynamic.Atmosphere.MACH] engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] # determine which mach-based fuel flow scaler is applied at each node @@ -270,11 +274,11 @@ def compute_partials(self, inputs, J): if variable not in skip_variables: if variable is FUEL_FLOW: J[ - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, 'fuel_flow_rate_unscaled', ] = fuel_flow_deriv J[ - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, Aircraft.Engine.SCALE_FACTOR, ] = fuel_flow_scale_deriv else: diff --git a/aviary/subsystems/propulsion/engine_sizing.py b/aviary/subsystems/propulsion/engine_sizing.py index 379c5272b..1dbb04cd3 100644 --- a/aviary/subsystems/propulsion/engine_sizing.py +++ b/aviary/subsystems/propulsion/engine_sizing.py @@ -21,9 +21,9 @@ def initialize(self): desc='collection of Aircraft/Mission specific options') def setup(self): - add_aviary_input(self, Aircraft.Engine.SCALED_SLS_THRUST, val=0.0) + add_aviary_input(self, Aircraft.Engine.SCALE_FACTOR, val=1.0) - add_aviary_output(self, Aircraft.Engine.SCALE_FACTOR, val=0.0) + add_aviary_output(self, Aircraft.Engine.SCALED_SLS_THRUST, val=0.0) # variables that also may require scaling # TODO - inlet_weight @@ -41,29 +41,27 @@ def compute(self, inputs, outputs): reference_sls_thrust = options.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, units='lbf') - scaled_sls_thrust = inputs[Aircraft.Engine.SCALED_SLS_THRUST] + engine_scale_factor = inputs[Aircraft.Engine.SCALE_FACTOR] # Engine is only scaled if required # engine scale factor is ratio of scaled thrust target and reference thrust - engine_scale_factor = 1 if scale_engine: - engine_scale_factor = scaled_sls_thrust / reference_sls_thrust + scaled_sls_thrust = engine_scale_factor * reference_sls_thrust + else: + scaled_sls_thrust = reference_sls_thrust - outputs[Aircraft.Engine.SCALE_FACTOR] = engine_scale_factor + outputs[Aircraft.Engine.SCALED_SLS_THRUST] = scaled_sls_thrust def setup_partials(self): - self.declare_partials(Aircraft.Engine.SCALE_FACTOR, - Aircraft.Engine.SCALED_SLS_THRUST) + self.declare_partials( + Aircraft.Engine.SCALED_SLS_THRUST, Aircraft.Engine.SCALE_FACTOR + ) def compute_partials(self, inputs, J): 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') - deriv_scale_factor = 0 - if scale_engine: - deriv_scale_factor = 1.0 / reference_sls_thrust - - J[Aircraft.Engine.SCALE_FACTOR, - Aircraft.Engine.SCALED_SLS_THRUST] = deriv_scale_factor + 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 f850f3870..94c2f6b81 100644 --- a/aviary/subsystems/propulsion/gearbox/gearbox_builder.py +++ b/aviary/subsystems/propulsion/gearbox/gearbox_builder.py @@ -35,23 +35,22 @@ def build_mission(self, num_nodes, aviary_inputs): def get_design_vars(self): """ Design vars are only tested to see if they exist in pre_mission - Returns a dictionary of design variables for the gearbox subsystem, where the keys are the - names of the design variables, and the values are dictionaries that contain the units for - the design variable, the lower and upper bounds for the design variable, and any + Returns a dictionary of design variables for the gearbox subsystem, where the keys are the + names of the design variables, and the values are dictionaries that contain the units for + the design variable, the lower and upper bounds for the design variable, and any additional keyword arguments required by OpenMDAO for the design variable. """ DVs = { Aircraft.Engine.Gearbox.GEAR_RATIO: { - 'opt': True, 'units': 'unitless', 'lower': 1.0, 'upper': 20.0, - 'val': 10 # initial value + # 'val': 10 # initial value }, # This var appears in both mission and pre-mission Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN: { - 'val': 10000, + # 'val': 10000, 'units': 'kW', 'lower': 1.0, 'upper': None, @@ -62,11 +61,11 @@ def get_design_vars(self): def get_parameters(self, aviary_inputs=None, phase_info=None): """ Parameters are only tested to see if they exist in mission. - A value the doesn't change throught the mission mission - Returns a dictionary of fixed values for the gearbox subsystem, where the keys are the names - of the fixed values, and the values are dictionaries that contain the fixed value for the - variable, the units for the variable, and any additional keyword arguments required by - OpenMDAO for the variable. + The value doesn't change throughout the mission. + Returns a dictionary of fixed values for the gearbox subsystem, where the keys + are the names of the fixed values, and the values are dictionaries that contain + the fixed value for the variable, the units for the variable, and any additional + keyword arguments required by OpenMDAO for the variable. Returns ------- @@ -75,9 +74,21 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): """ parameters = { Aircraft.Engine.Gearbox.EFFICIENCY: { - 'val': 0.98, + 'val': 1.0, 'units': 'unitless', + 'static_target': True, }, + Aircraft.Engine.Gearbox.GEAR_RATIO: { + 'val': 1.0, + 'units': 'unitless', + 'static_target': True, + }, + Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN: { + 'val': 1.0, + 'units': 'kW', + 'lower': 1.0, + 'upper': None, + } } return parameters @@ -87,10 +98,10 @@ def get_mass_names(self): def get_outputs(self): return [ - Dynamic.Mission.SHAFT_POWER + '_out', - Dynamic.Mission.SHAFT_POWER_MAX + '_out', - Dynamic.Mission.RPM + '_out', - Dynamic.Mission.TORQUE + '_out', + Dynamic.Vehicle.Propulsion.SHAFT_POWER + '_out', + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX + '_out', + Dynamic.Vehicle.Propulsion.RPM + '_out', + Dynamic.Vehicle.Propulsion.TORQUE + '_out', Mission.Constraints.GEARBOX_SHAFT_POWER_RESIDUAL, ] diff --git a/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py b/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py index 62a9587b4..df0b4f97b 100644 --- a/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py +++ b/aviary/subsystems/propulsion/gearbox/model/gearbox_mission.py @@ -33,10 +33,10 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('rpm_in', Dynamic.Mission.RPM + '_in'), + ('rpm_in', Dynamic.Vehicle.Propulsion.RPM + '_in'), ('gear_ratio', Aircraft.Engine.Gearbox.GEAR_RATIO), ], - promotes_outputs=[('rpm_out', Dynamic.Mission.RPM + '_out')], + promotes_outputs=[('rpm_out', Dynamic.Vehicle.Propulsion.RPM + '_out')], ) self.add_subsystem( @@ -49,11 +49,11 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('shaft_power_in', Dynamic.Mission.SHAFT_POWER + '_in'), + ('shaft_power_in', Dynamic.Vehicle.Propulsion.SHAFT_POWER + '_in'), ('efficiency', Aircraft.Engine.Gearbox.EFFICIENCY), ], promotes_outputs=[ - ('shaft_power_out', Dynamic.Mission.SHAFT_POWER + '_out') + ('shaft_power_out', Dynamic.Vehicle.Propulsion.SHAFT_POWER + '_out') ], ) @@ -66,15 +66,16 @@ def setup(self): rpm_out={'val': np.ones(n), 'units': 'rad/s'}, has_diag_partials=True, ), - promotes_outputs=[('torque_out', Dynamic.Mission.TORQUE + '_out')], + promotes_outputs=[ + ('torque_out', Dynamic.Vehicle.Propulsion.TORQUE + '_out')], ) self.connect( - f'{Dynamic.Mission.SHAFT_POWER}_out', + f'{Dynamic.Vehicle.Propulsion.SHAFT_POWER}_out', f'torque_comp.shaft_power_out', ) self.connect( - f'{Dynamic.Mission.RPM}_out', + f'{Dynamic.Vehicle.Propulsion.RPM}_out', f'torque_comp.rpm_out', ) @@ -90,11 +91,11 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('shaft_power_in', Dynamic.Mission.SHAFT_POWER_MAX + '_in'), + ('shaft_power_in', Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX + '_in'), ('efficiency', Aircraft.Engine.Gearbox.EFFICIENCY), ], promotes_outputs=[ - ('shaft_power_out', Dynamic.Mission.SHAFT_POWER_MAX + '_out') + ('shaft_power_out', Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX + '_out') ], ) @@ -113,7 +114,7 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('shaft_power_max', Dynamic.Mission.SHAFT_POWER_MAX + '_in'), + ('shaft_power_max', Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX + '_in'), ('shaft_power_design', Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN), ], promotes_outputs=[ diff --git a/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py b/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py index d43c08b63..503ba933f 100644 --- a/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py +++ b/aviary/subsystems/propulsion/gearbox/model/gearbox_premission.py @@ -9,7 +9,7 @@ class GearboxPreMission(om.Group): """ Calculate gearbox mass for a single gearbox. - Gearbox design assumes collective control which means that RPM coming into the + Gearbox design assumes collective control which means that RPM coming into the gearbox is fixed and RPM going out of the gearbox is fixed over the whole mission. """ @@ -23,29 +23,42 @@ def initialize(self, ): self.name = 'gearbox_premission' def setup(self): - self.add_subsystem('gearbox_PRM', - om.ExecComp('RPM_out = RPM_in / gear_ratio', - RPM_out={'val': 0.0, 'units': 'rpm'}, - gear_ratio={'val': 1.0, 'units': 'unitless'}, - RPM_in={'val': 0.0, 'units': 'rpm'}, - has_diag_partials=True), - promotes_inputs=[('RPM_in', Aircraft.Engine.RPM_DESIGN), - ('gear_ratio', Aircraft.Engine.Gearbox.GEAR_RATIO)], - promotes_outputs=['RPM_out']) + self.add_subsystem( + 'gearbox_RPM', + om.ExecComp( + 'RPM_out = RPM_in / gear_ratio', + RPM_out={'val': 0.0, 'units': 'rpm'}, + gear_ratio={'val': 1.0, 'units': 'unitless'}, + RPM_in={'val': 0.0, 'units': 'rpm'}, + has_diag_partials=True, + ), + promotes_inputs=[ + ('RPM_in', Aircraft.Engine.RPM_DESIGN), + ('gear_ratio', Aircraft.Engine.Gearbox.GEAR_RATIO), + ], + # promotes_outputs=['RPM_out'], + ) # max torque is calculated based on input shaft power and output RPM - self.add_subsystem('torque_comp', - om.ExecComp('torque_max = shaft_power / RPM_out', - shaft_power={'val': 1.0, 'units': 'kW'}, - torque_max={'val': 1.0, 'units': 'kN*m'}, - RPM_out={'val': 1.0, 'units': 'rad/s'}, - has_diag_partials=True), - promotes_inputs=[('shaft_power', Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN), - 'RPM_out'], - promotes_outputs=['torque_max']) + self.add_subsystem( + 'torque_comp', + om.ExecComp( + 'torque_max = shaft_power / RPM_out', + shaft_power={'val': 1.0, 'units': 'kW'}, + torque_max={'val': 1.0, 'units': 'kN*m'}, + RPM_out={'val': 1.0, 'units': 'rad/s'}, + has_diag_partials=True, + ), + promotes_inputs=[ + ('shaft_power', Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN) + ], + # 'RPM_out'], + # promotes_outputs=['torque_max'], + ) if self.options["simple_mass"]: - # Simple gearbox mass will always produce positive values for mass based on a fixed specific torque + # Simple gearbox mass will always produce positive values for mass based + # on a fixed specific torque self.add_subsystem( 'mass_comp', om.ExecComp( @@ -56,7 +69,7 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - 'torque_max', + # 'torque_max', ('specific_torque', Aircraft.Engine.Gearbox.SPECIFIC_TORQUE), ], promotes_outputs=[('gearbox_mass', Aircraft.Engine.Gearbox.MASS)], @@ -66,13 +79,26 @@ def setup(self): # This gearbox mass calc can work for large systems but can produce negative weights for some inputs # Gearbox mass from "An N+3 Technolgoy Level Reference Propulsion System" by Scott Jones, William Haller, and Michael Tong # NASA TM 2017-219501 - self.add_subsystem('gearbox_mass', - om.ExecComp('gearbox_mass = (shaftpower / RPM_out)**(0.75) * (RPM_in / RPM_out)**(0.15)', - gearbox_mass={'val': 0.0, 'units': 'lb'}, - shaftpower={'val': 0.0, 'units': 'hp'}, - RPM_out={'val': 0.0, 'units': 'rpm'}, - RPM_in={'val': 0.0, 'units': 'rpm'}, - has_diag_partials=True), - promotes_inputs=[('shaftpower', Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN), - 'RPM_out', ('RPM_in', Aircraft.Engine.RPM_DESIGN)], - promotes_outputs=[('gearbox_mass', Aircraft.Engine.Gearbox.MASS)]) + self.add_subsystem( + 'gearbox_mass', + om.ExecComp( + 'gearbox_mass = (shaftpower / RPM_out)**(0.75) * (RPM_in / RPM_out)**(0.15)', + gearbox_mass={'val': 0.0, 'units': 'lb'}, + shaftpower={'val': 0.0, 'units': 'hp'}, + RPM_out={'val': 0.0, 'units': 'rpm'}, + RPM_in={'val': 0.0, 'units': 'rpm'}, + has_diag_partials=True, + ), + promotes_inputs=[ + ('shaftpower', Aircraft.Engine.Gearbox.SHAFT_POWER_DESIGN), + # 'RPM_out', + ('RPM_in', Aircraft.Engine.RPM_DESIGN), + ], + promotes_outputs=[('gearbox_mass', Aircraft.Engine.Gearbox.MASS)], + ) + + self.connect('gearbox_RPM.RPM_out', 'torque_comp.RPM_out') + if self.options["simple_mass"]: + self.connect('torque_comp.torque_max', 'mass_comp.torque_max') + else: + self.connect('gearbox_RPM.RPM_out', 'gearbox_mass.RPM_out') diff --git a/aviary/subsystems/propulsion/gearbox/test/test_gearbox.py b/aviary/subsystems/propulsion/gearbox/test/test_gearbox.py index 816b8ac03..4806844a9 100644 --- a/aviary/subsystems/propulsion/gearbox/test/test_gearbox.py +++ b/aviary/subsystems/propulsion/gearbox/test/test_gearbox.py @@ -33,7 +33,7 @@ def test_gearbox_premission(self): prob.run_model() mass = prob.get_val(av.Aircraft.Engine.Gearbox.MASS, 'lb') - torque_max = prob.get_val('torque_max', 'lbf*ft') + torque_max = prob.get_val('gearbox_premission.torque_comp.torque_max', 'lbf*ft') torque_max_expected = 4005.84967696 mass_expected = 116.25002688 @@ -53,38 +53,38 @@ def test_gearbox_mission(self): prob.setup(force_alloc_complex=True) - prob.set_val(av.Dynamic.Mission.RPM + '_in', [5000, 6195, 6195], units='rpm') - prob.set_val( - av.Dynamic.Mission.SHAFT_POWER + '_in', [100, 200, 375], units='hp' - ) - prob.set_val( - av.Dynamic.Mission.SHAFT_POWER_MAX + '_in', [375, 300, 375], units='hp' - ) + prob.set_val(av.Dynamic.Vehicle.Propulsion.RPM + '_in', + [5000, 6195, 6195], units='rpm') + prob.set_val(av.Dynamic.Vehicle.Propulsion.SHAFT_POWER + '_in', + [100, 200, 375], units='hp') + prob.set_val(av.Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX + '_in', + [375, 300, 375], units='hp') prob.set_val(av.Aircraft.Engine.Gearbox.GEAR_RATIO, 12.6, units=None) prob.set_val(av.Aircraft.Engine.Gearbox.EFFICIENCY, 0.98, units=None) prob.run_model() - SHAFT_POWER_GEARBOX = prob.get_val( - av.Dynamic.Mission.SHAFT_POWER + '_out', 'hp' + shaft_power = prob.get_val( + av.Dynamic.Vehicle.Propulsion.SHAFT_POWER + '_out', 'hp' ) - RPM_GEARBOX = prob.get_val(av.Dynamic.Mission.RPM + '_out', 'rpm') - TORQUE_GEARBOX = prob.get_val(av.Dynamic.Mission.TORQUE + '_out', 'ft*lbf') - SHAFT_POWER_MAX_GEARBOX = prob.get_val( - av.Dynamic.Mission.SHAFT_POWER_MAX + '_out', 'hp' + rpm = prob.get_val(av.Dynamic.Vehicle.Propulsion.RPM + '_out', 'rpm') + torque = prob.get_val( + av.Dynamic.Vehicle.Propulsion.TORQUE + '_out', 'ft*lbf') + shaft_power_max = prob.get_val( + av.Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX + '_out', 'hp' ) - SHAFT_POWER_GEARBOX_expected = [98., 196., 367.5] - RPM_GEARBOX_expected = [396.82539683, 491.66666667, 491.66666667] - TORQUE_GEARBOX_expected = [1297.0620786, 2093.72409783, 3925.73268342] - SHAFT_POWER_MAX_GEARBOX_expected = [367.5, 294., 367.5] - - assert_near_equal(SHAFT_POWER_GEARBOX, - SHAFT_POWER_GEARBOX_expected, tolerance=1e-6) - assert_near_equal(RPM_GEARBOX, RPM_GEARBOX_expected, tolerance=1e-6) - assert_near_equal(TORQUE_GEARBOX, TORQUE_GEARBOX_expected, tolerance=1e-6) - assert_near_equal(SHAFT_POWER_MAX_GEARBOX, - SHAFT_POWER_MAX_GEARBOX_expected, tolerance=1e-6) + shaft_power_expected = [98., 196., 367.5] + rpm_expected = [396.82539683, 491.66666667, 491.66666667] + torque_expected = [1297.0620786, 2093.72409783, 3925.73268342] + shaft_power_max_expected = [367.5, 294., 367.5] + + assert_near_equal(shaft_power, + shaft_power_expected, tolerance=1e-6) + assert_near_equal(rpm, rpm_expected, tolerance=1e-6) + assert_near_equal(torque, torque_expected, tolerance=1e-6) + assert_near_equal(shaft_power_max, + shaft_power_max_expected, tolerance=1e-6) partial_data = prob.check_partials(out_stream=None, method="cs") assert_check_partials(partial_data, atol=1e-9, rtol=1e-9) diff --git a/aviary/subsystems/propulsion/motor/model/motor_map.py b/aviary/subsystems/propulsion/motor/model/motor_map.py index 894c154f8..8e3be4114 100644 --- a/aviary/subsystems/propulsion/motor/model/motor_map.py +++ b/aviary/subsystems/propulsion/motor/model/motor_map.py @@ -4,7 +4,9 @@ from aviary.variable_info.variables import Dynamic, Aircraft - +# block auto-formatting of tables +# autopep8: off +# fmt: off motor_map = np.array([ # speed---- .0 .083333 .16667 .25 .33333.41667 .5, .58333 .66667 .75, .83333, .91667 1. [.871, .872, .862, .853, .845, .838, .832, .825, .819, .813, .807, .802, .796], # 0 @@ -25,31 +27,33 @@ [.807, .808, .884, .912, .927, .936, .942, .947, .950, .952, .954, .955, .956], # 0.936 [.795, .796, .877, .907, .923, .933, .939, .944, .948, .950, .952, .953, .954] # 1.000 ]).T +# autopep8: on +# fmt: on class MotorMap(om.Group): - ''' This function takes in 0-1 values for electric motor throttle, scales those values into 0 to max_torque on the motor map this also allows us to solve for motor efficiency then we scale the torque up based on the actual scale factor of the motor. This avoids the need to rescale the map values, and still allows for the motor scale to be optimized. - Scaling only effects Torque. RPM is not scaled and is assumed to be maxed at 6,000 rpm. + Scaling only effects torque (and therefore shaft power production, and electric power consumption). + RPM is not scaled and is assumed to be maxed at 6,000 rpm. The original maps were put together for a 746kw (1,000 hp) electric motor published in the TTBW paper: https://ntrs.nasa.gov/api/citations/20230016987/downloads/TTBW_SciTech_2024_Final_12_5_2023.pdf The map is shown in Figure 4. Inputs ---------- - Dynamic.Mission.THROTTLE : float (unitless) (0 to 1) + Dynamic.Vehicle.Propulsion.THROTTLE : float (unitless) (0 to 1) The throttle command which will be translated into torque output from the engine - Aircraft.Engine.SCALE_FACTOR : float (unitless) (positive) + Aircraft.Engine.SCALE_FACTOR : float (unitless) (positive) Aircraft.Motor.RPM : float (rpm) (0 to 6000) Outputs ---------- - Dynamic.Mission.TORQUE : float (positive) + Dynamic.Vehicle.Propulsion.TORQUE : float (positive) Dynamic.Mission.Motor.EFFICIENCY : float (positive) ''' @@ -61,25 +65,37 @@ def setup(self): n = self.options["num_nodes"] # Training data + # autopep8: off + # fmt: off rpm_vals = np.array([0, .083333, .16667, .25, .33333, .41667, .5, - .58333, .66667, .75, .83333, .91667, 1.])*6000 + .58333, .66667, .75, .83333, .91667, 1.]) * 6000 torque_vals = np.array([0.0, 0.040, 0.104, 0.168, 0.232, 0.296, 0.360, 0.424, 0.488, 0.552, 0.616, 0.680, 0.744, 0.808, - 0.872, 0.936, 1.000])*1800 - + 0.872, 0.936, 1.000]) * 1800 + # autopep8: on + # fmt: on # Create a structured metamodel to compute motor efficiency from rpm - motor = om.MetaModelStructuredComp(method="slinear", - vec_size=n, - extrapolate=True) - motor.add_input(Dynamic.Mission.RPM, val=np.ones(n), - training_data=rpm_vals, - units="rpm") - motor.add_input("torque_unscaled", val=np.ones(n), # unscaled torque - training_data=torque_vals, - units="N*m") - motor.add_output("motor_efficiency", val=np.ones(n), - training_data=motor_map, - units='unitless') + motor = om.MetaModelStructuredComp( + method="slinear", vec_size=n, extrapolate=True + ) + motor.add_input( + Dynamic.Vehicle.Propulsion.RPM, + val=np.ones(n), + training_data=rpm_vals, + units="rpm", + ) + motor.add_input( + "torque_unscaled", + val=np.ones(n), # unscaled torque + training_data=torque_vals, + units="N*m", + ) + motor.add_output( + "motor_efficiency", + val=np.ones(n), + training_data=motor_map, + units='unitless', + ) self.add_subsystem( 'throttle_to_torque', @@ -90,15 +106,18 @@ def setup(self): throttle={'val': np.ones(n), 'units': 'unitless'}, has_diag_partials=True, ), - promotes=["torque_unscaled", ("throttle", Dynamic.Mission.THROTTLE)], + promotes=[("throttle", Dynamic.Vehicle.Propulsion.THROTTLE)], ) - self.add_subsystem(name="motor_efficiency", - subsys=motor, - promotes_inputs=[Dynamic.Mission.RPM, "torque_unscaled"], - promotes_outputs=["motor_efficiency"]) + self.add_subsystem( + name="motor_efficiency", + subsys=motor, + promotes_inputs=[Dynamic.Vehicle.Propulsion.RPM], + promotes_outputs=["motor_efficiency"], + ) - # now that we know the efficiency, scale up the torque correctly for the engine size selected + # Now that we know the efficiency, scale up the torque correctly for the engine + # size selected # Note: This allows the optimizer to optimize the motor size if desired self.add_subsystem( 'scale_motor_torque', @@ -110,8 +129,12 @@ def setup(self): has_diag_partials=True, ), promotes=[ - ("torque", Dynamic.Mission.TORQUE), - "torque_unscaled", + ("torque", Dynamic.Vehicle.Propulsion.TORQUE), ("scale_factor", Aircraft.Engine.SCALE_FACTOR), ], ) + + self.connect( + 'throttle_to_torque.torque_unscaled', + ['motor_efficiency.torque_unscaled', 'scale_motor_torque.torque_unscaled'], + ) diff --git a/aviary/subsystems/propulsion/motor/model/motor_mission.py b/aviary/subsystems/propulsion/motor/model/motor_mission.py index 843603727..19df04708 100644 --- a/aviary/subsystems/propulsion/motor/model/motor_mission.py +++ b/aviary/subsystems/propulsion/motor/model/motor_mission.py @@ -8,7 +8,6 @@ class MotorMission(om.Group): - ''' Calculates the mission performance (ODE) of a single electric motor. ''' @@ -16,7 +15,8 @@ class MotorMission(om.Group): def initialize(self): self.options.declare("num_nodes", types=int) self.options.declare( - 'aviary_inputs', types=AviaryValues, + 'aviary_inputs', + types=AviaryValues, desc='collection of Aircraft/Mission specific options', default=None, ) @@ -36,12 +36,12 @@ def setup(self): 'motor_map', MotorMap(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.THROTTLE, + Dynamic.Vehicle.Propulsion.THROTTLE, Aircraft.Engine.SCALE_FACTOR, - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.RPM, ], promotes_outputs=[ - Dynamic.Mission.TORQUE, + Dynamic.Vehicle.Propulsion.TORQUE, 'motor_efficiency', ], ) @@ -55,13 +55,13 @@ def setup(self): RPM={'val': np.ones(nn), 'units': 'rad/s'}, has_diag_partials=True, ), # fixed RPM system - promotes_inputs=[('RPM', Dynamic.Mission.RPM)], - promotes_outputs=[('shaft_power', Dynamic.Mission.SHAFT_POWER)], + promotes_inputs=[('RPM', Dynamic.Vehicle.Propulsion.RPM)], + promotes_outputs=[('shaft_power', Dynamic.Vehicle.Propulsion.SHAFT_POWER)], ) # Can't promote torque as an input, as it will create a feedback loop with # propulsion mux component. Connect it here instead - motor_group.connect(Dynamic.Mission.TORQUE, 'power_comp.torque') + motor_group.connect(Dynamic.Vehicle.Propulsion.TORQUE, 'power_comp.torque') motor_group.add_subsystem( 'energy_comp', @@ -73,16 +73,20 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[('efficiency', 'motor_efficiency')], - promotes_outputs=[('power_elec', Dynamic.Mission.ELECTRIC_POWER_IN)], + promotes_outputs=[ + ('power_elec', Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN) + ], ) # Can't promote shaft power as an input, as it will create a feedback loop with # propulsion mux component. Connect it here instead - motor_group.connect(Dynamic.Mission.SHAFT_POWER, 'energy_comp.shaft_power') + motor_group.connect( + Dynamic.Vehicle.Propulsion.SHAFT_POWER, 'energy_comp.shaft_power' + ) - self.add_subsystem('motor_group', motor_group, - promotes_inputs=['*'], - promotes_outputs=['*']) + self.add_subsystem( + 'motor_group', motor_group, promotes_inputs=['*'], promotes_outputs=['*'] + ) # Determine the maximum power available at this flight condition # this is used for excess power constraints @@ -93,12 +97,15 @@ def setup(self): 'motor_map_max', MotorMap(num_nodes=nn), promotes_inputs=[ - (Dynamic.Mission.THROTTLE, 'max_throttle'), + (Dynamic.Vehicle.Propulsion.THROTTLE, 'max_throttle'), Aircraft.Engine.SCALE_FACTOR, - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.RPM, ], promotes_outputs=[ - (Dynamic.Mission.TORQUE, Dynamic.Mission.TORQUE_MAX), + ( + Dynamic.Vehicle.Propulsion.TORQUE, + Dynamic.Vehicle.Propulsion.TORQUE_MAX, + ), 'motor_efficiency', ], ) @@ -113,10 +120,12 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('max_torque', Dynamic.Mission.TORQUE_MAX), - ('RPM', Dynamic.Mission.RPM), + ('max_torque', Dynamic.Vehicle.Propulsion.TORQUE_MAX), + ('RPM', Dynamic.Vehicle.Propulsion.RPM), + ], + promotes_outputs=[ + ('max_power', Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX) ], - promotes_outputs=[('max_power', Dynamic.Mission.SHAFT_POWER_MAX)], ) self.add_subsystem( @@ -124,9 +133,11 @@ def setup(self): motor_group_max, promotes_inputs=['*', 'max_throttle'], promotes_outputs=[ - Dynamic.Mission.SHAFT_POWER_MAX, - Dynamic.Mission.TORQUE_MAX, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, + Dynamic.Vehicle.Propulsion.TORQUE_MAX, ], ) - self.set_input_defaults(Dynamic.Mission.RPM, val=np.ones(nn), units='rpm') + self.set_input_defaults( + Dynamic.Vehicle.Propulsion.RPM, val=np.ones(nn), units='rpm' + ) diff --git a/aviary/subsystems/propulsion/motor/model/motor_premission.py b/aviary/subsystems/propulsion/motor/model/motor_premission.py index c6964d41d..a5e872074 100644 --- a/aviary/subsystems/propulsion/motor/model/motor_premission.py +++ b/aviary/subsystems/propulsion/motor/model/motor_premission.py @@ -13,7 +13,8 @@ class MotorPreMission(om.Group): def initialize(self): self.options.declare( - "aviary_inputs", types=AviaryValues, + "aviary_inputs", + types=AviaryValues, desc="collection of Aircraft/Mission specific options", default=None, ) @@ -31,7 +32,7 @@ def setup(self): Aircraft.Engine.RPM_DESIGN, units='rpm' ) - self.set_input_defaults(Dynamic.Mission.THROTTLE, 1.0, units=None) + self.set_input_defaults(Dynamic.Vehicle.Propulsion.THROTTLE, 1.0, units=None) self.set_input_defaults('design_rpm', design_rpm, units='rpm') self.add_subsystem( @@ -39,11 +40,11 @@ def setup(self): MotorMap(num_nodes=1), promotes_inputs=[ Aircraft.Engine.SCALE_FACTOR, - Dynamic.Mission.THROTTLE, - (Dynamic.Mission.RPM, 'design_rpm'), + Dynamic.Vehicle.Propulsion.THROTTLE, + (Dynamic.Vehicle.Propulsion.RPM, 'design_rpm'), ], promotes_outputs=[ - (Dynamic.Mission.TORQUE, Aircraft.Engine.Motor.TORQUE_MAX) + (Dynamic.Vehicle.Propulsion.TORQUE, Aircraft.Engine.Motor.TORQUE_MAX) ], ) diff --git a/aviary/subsystems/propulsion/motor/motor_builder.py b/aviary/subsystems/propulsion/motor/motor_builder.py index 3f199bcb7..963ac693f 100644 --- a/aviary/subsystems/propulsion/motor/motor_builder.py +++ b/aviary/subsystems/propulsion/motor/motor_builder.py @@ -6,11 +6,16 @@ class MotorBuilder(SubsystemBuilderBase): ''' - Define the builder for a single motor subsystem that provides methods to define the motor subsystem's states, design variables, fixed values, initial guesses, and mass names. + Define the builder for a single motor subsystem that provides methods to define the + motor subsystem's states, design variables, fixed values, initial guesses, and mass + names. - It also provides methods to build OpenMDAO systems for the pre-mission and mission computations of the subsystem, to get the constraints for the subsystem, and to preprocess the inputs for the subsystem. + It also provides methods to build OpenMDAO systems for the pre-mission and mission + computations of the subsystem, to get the constraints for the subsystem, and to + preprocess the inputs for the subsystem. - This is meant to be computations for a single motor, so there is no notion of "num_motors" in this code. + This is meant to be computations for a single motor, so there is no notion of + "num_motors" in this code. Attributes ---------- @@ -22,7 +27,10 @@ class MotorBuilder(SubsystemBuilderBase): __init__(self, name='motor'): Initializes the MotorBuilder object with a given name. get_states(self) -> dict: - Returns a dictionary of the subsystem's states, where the keys are the names of the state variables, and the values are dictionaries that contain the units for the state variable and any additional keyword arguments required by OpenMDAO for the state variable. + Returns a dictionary of the subsystem's states, where the keys are the names of + the state variables, and the values are dictionaries that contain the units for + the state variable and any additional keyword arguments required by OpenMDAO for + the state variable. get_linked_variables(self) -> list: Links voltage input from the battery subsystem build_pre_mission(self) -> openmdao.core.System: @@ -30,25 +38,38 @@ class MotorBuilder(SubsystemBuilderBase): build_mission(self, num_nodes, aviary_inputs) -> openmdao.core.System: Builds an OpenMDAO system for the mission computations of the subsystem. get_constraints(self) -> dict: - Returns a dictionary of constraints for the motor subsystem, where the keys are the names of the variables to be constrained, and the values are dictionaries that contain the lower and upper bounds for the constraint and any additional keyword arguments accepted by Dymos for the constraint. + Returns a dictionary of constraints for the motor subsystem, where the keys are + the names of the variables to be constrained, and the values are dictionaries + that contain the lower and upper bounds for the constraint and any additional + keyword arguments accepted by Dymos for the constraint. get_design_vars(self) -> dict: - Returns a dictionary of design variables for the motor subsystem, where the keys are the names of the design variables, and the values are dictionaries that contain the units for the design variable, the lower and upper bounds for the design variable, and any additional keyword arguments required by OpenMDAO for the design variable. + Returns a dictionary of design variables for the motor subsystem, where the keys + are the names of the design variables, and the values are dictionaries that + contain the units for the design variable, the lower and upper bounds for the + design variable, and any additional keyword arguments required by OpenMDAO for + the design variable. get_parameters(self) -> dict: - Returns a dictionary of fixed values for the motor subsystem, where the keys are the names of the fixed values, and the values are dictionaries that contain the fixed value for the variable, the units for the variable, and any additional keyword arguments required by OpenMDAO for the variable. + Returns a dictionary of fixed values for the motor subsystem, where the keys are + the names of the fixed values, and the values are dictionaries that contain the + fixed value for the variable, the units for the variable, and any additional + keyword arguments required by OpenMDAO for the variable. get_initial_guesses(self) -> dict: - Returns a dictionary of initial guesses for the motor subsystem, where the keys are the names of the initial guesses, and the values are dictionaries that contain the initial guess value, the type of variable (state or control), and any additional keyword arguments required by OpenMDAO for the variable. + Returns a dictionary of initial guesses for the motor subsystem, where the keys + are the names of the initial guesses, and the values are dictionaries that + contain the initial guess value, the type of variable (state or control), and any + additional keyword arguments required by OpenMDAO for the variable. get_mass_names(self) -> list: Returns a list of names for the motor subsystem mass. preprocess_inputs(self, aviary_inputs) -> aviary_inputs: No preprocessing needed for the motor subsystem. ''' - def __init__(self, name='motor', include_constraints=True): - self.include_constraints = include_constraints + def __init__(self, name='motor'): # , include_constraints=True): + # self.include_constraints = include_constraints super().__init__(name) def build_pre_mission(self, aviary_inputs): - return MotorPreMission(aviary_inputs=aviary_inputs, simple_mass=True) + return MotorPreMission(aviary_inputs=aviary_inputs) # , simple_mass=True) def build_mission(self, num_nodes, aviary_inputs): return MotorMission(num_nodes=num_nodes, aviary_inputs=aviary_inputs) @@ -56,11 +77,7 @@ def build_mission(self, num_nodes, aviary_inputs): # def get_constraints(self): # if self.include_constraints: # constraints = { - # Dynamic.Mission.Motor.TORQUE_CON: { - # 'upper': 0.0, - # 'type': 'path' - # } - # TBD Gearbox torque constraint + # Dynamic.Mission.Motor.TORQUE_CON: {'upper': 0.0, 'type': 'path'} # } # else: # constraints = {} @@ -72,17 +89,22 @@ def get_design_vars(self): Aircraft.Engine.SCALE_FACTOR: { 'units': 'unitless', 'lower': 0.001, - 'upper': None + 'upper': None, }, - Aircraft.Engine.Gearbox.GEAR_RATIO: { - 'units': None, - 'lower': 1.0, - 'upper': 1.0, - } } return DVs + def get_parameters(self): + params = { + Aircraft.Engine.SCALE_FACTOR: { + 'val': 1.0, + 'units': 'unitless', + 'static_target': True, + } + } + return params + # def get_initial_guesses(self): # initial_guess_dict = { # Aircraft.Motor.RPM: { @@ -117,8 +139,8 @@ def get_outputs(self): ''' return [ - Dynamic.Mission.TORQUE, - Dynamic.Mission.SHAFT_POWER, - Dynamic.Mission.SHAFT_POWER_MAX, - Dynamic.Mission.ELECTRIC_POWER_IN, + Dynamic.Vehicle.Propulsion.TORQUE, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, ] diff --git a/aviary/subsystems/propulsion/motor/test/test_motor_map.py b/aviary/subsystems/propulsion/motor/test/test_motor_map.py index 20256022f..4be1d9429 100644 --- a/aviary/subsystems/propulsion/motor/test/test_motor_map.py +++ b/aviary/subsystems/propulsion/motor/test/test_motor_map.py @@ -21,14 +21,13 @@ def test_motor_map(self): prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.THROTTLE, np.linspace(0, 1, nn)) - prob.set_val(Dynamic.Mission.RPM, np.linspace(0, 6000, nn)) - prob.set_val('torque_unscaled', np.linspace(0, 1800, nn), 'N*m') + prob.set_val(Dynamic.Vehicle.Propulsion.THROTTLE, np.linspace(0, 1, nn)) + prob.set_val(Dynamic.Vehicle.Propulsion.RPM, np.linspace(0, 6000, nn)) prob.set_val(Aircraft.Engine.SCALE_FACTOR, 1.12) prob.run_model() - torque = prob.get_val(Dynamic.Mission.TORQUE) + torque = prob.get_val(Dynamic.Vehicle.Propulsion.TORQUE) efficiency = prob.get_val('motor_efficiency') torque_expected = np.array([0.0, 900.0, 1800.0]) * 1.12 diff --git a/aviary/subsystems/propulsion/motor/test/test_motor_mission.py b/aviary/subsystems/propulsion/motor/test/test_motor_mission.py index 0b1b27871..646b861bf 100644 --- a/aviary/subsystems/propulsion/motor/test/test_motor_mission.py +++ b/aviary/subsystems/propulsion/motor/test/test_motor_mission.py @@ -23,19 +23,19 @@ def test_motor_map(self): prob.setup(force_alloc_complex=True) - prob.set_val(Dynamic.Mission.THROTTLE, np.linspace(0, 1, nn)) - prob.set_val(Dynamic.Mission.RPM, np.linspace(0, 6000, nn)) + prob.set_val(Dynamic.Vehicle.Propulsion.THROTTLE, np.linspace(0, 1, nn)) + prob.set_val(Dynamic.Vehicle.Propulsion.RPM, np.linspace(0, 6000, nn)) # prob.set_val('torque_unscaled', np.linspace(0, 1800, nn), 'N*m') prob.set_val(Aircraft.Engine.SCALE_FACTOR, 1.12) prob.run_model() - torque = prob.get_val(Dynamic.Mission.TORQUE, 'N*m') - max_torque = prob.get_val(Dynamic.Mission.TORQUE_MAX, 'N*m') + torque = prob.get_val(Dynamic.Vehicle.Propulsion.TORQUE, 'N*m') + max_torque = prob.get_val(Dynamic.Vehicle.Propulsion.TORQUE_MAX, 'N*m') efficiency = prob.get_val('motor_efficiency') - shp = prob.get_val(Dynamic.Mission.SHAFT_POWER) - max_shp = prob.get_val(Dynamic.Mission.SHAFT_POWER_MAX) - power = prob.get_val(Dynamic.Mission.ELECTRIC_POWER_IN, 'kW') + shp = prob.get_val(Dynamic.Vehicle.Propulsion.SHAFT_POWER) + max_shp = prob.get_val(Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX) + power = prob.get_val(Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, 'kW') torque_expected = np.array([0.0, 900.0, 1800.0]) * 1.12 max_torque_expected = [2016, 2016, 2016] diff --git a/aviary/subsystems/propulsion/motor/test/test_motor_premission.py b/aviary/subsystems/propulsion/motor/test/test_motor_premission.py index b9ec5a567..6864f25ef 100644 --- a/aviary/subsystems/propulsion/motor/test/test_motor_premission.py +++ b/aviary/subsystems/propulsion/motor/test/test_motor_premission.py @@ -24,7 +24,6 @@ def test_motor_map(self): prob.setup(force_alloc_complex=True) - # prob.set_val('torque_unscaled', np.linspace(0, 1800, nn), 'N*m') prob.set_val(Aircraft.Engine.SCALE_FACTOR, 1.12) prob.run_model() diff --git a/aviary/subsystems/propulsion/propeller/hamilton_standard.py b/aviary/subsystems/propulsion/propeller/hamilton_standard.py index 6091a10f4..b9f245b28 100644 --- a/aviary/subsystems/propulsion/propeller/hamilton_standard.py +++ b/aviary/subsystems/propulsion/propeller/hamilton_standard.py @@ -88,7 +88,7 @@ def _unint(xa, ya, x): def _biquad(T, i, xi, yi): """ - This routine interpolates over a 4 point interval using a + This routine interpolates over a 4 point interval using a variation of 2nd degree interpolation to produce a continuity of slope between adjacent intervals. @@ -249,7 +249,7 @@ def _biquad(T, i, xi, yi): return z, lmt -# DO NOT AUTO-FORMAT TABLES +# block auto-formatting of tables # autopep8: off # fmt: off CP_Angle_table = np.array([ @@ -485,19 +485,22 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] - add_aviary_input(self, Aircraft.Engine.PROPELLER_DIAMETER, val=0.0, units='ft') + add_aviary_input(self, Aircraft.Engine.Propeller.DIAMETER, val=0.0, units='ft') add_aviary_input( - self, Dynamic.Mission.PROPELLER_TIP_SPEED, val=np.zeros(nn), units='ft/s' + self, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + val=np.zeros(nn), + units='ft/s', ) add_aviary_input( - self, Dynamic.Mission.SHAFT_POWER, val=np.zeros(nn), units='hp' + self, Dynamic.Vehicle.Propulsion.SHAFT_POWER, val=np.zeros(nn), units='hp' ) add_aviary_input( - self, Dynamic.Mission.DENSITY, val=np.zeros(nn), units='slug/ft**3' + self, Dynamic.Atmosphere.DENSITY, val=np.zeros(nn), units='slug/ft**3' ) add_aviary_input(self, Dynamic.Mission.VELOCITY, val=np.zeros(nn), units='ft/s') add_aviary_input( - self, Dynamic.Mission.SPEED_OF_SOUND, val=np.zeros(nn), units='ft/s' + self, Dynamic.Atmosphere.SPEED_OF_SOUND, val=np.zeros(nn), units='ft/s' ) self.add_output('power_coefficient', val=np.zeros(nn), units='unitless') @@ -511,57 +514,72 @@ def setup_partials(self): arange = np.arange(self.options['num_nodes']) # self.declare_partials( - # 'density_ratio', Dynamic.Mission.DENSITY, rows=arange, cols=arange) + # 'density_ratio', Dynamic.Atmosphere.DENSITY, rows=arange, cols=arange) self.declare_partials( 'tip_mach', [ - Dynamic.Mission.PROPELLER_TIP_SPEED, - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + Dynamic.Atmosphere.SPEED_OF_SOUND, ], rows=arange, cols=arange, ) - self.declare_partials('advance_ratio', [ - Dynamic.Mission.VELOCITY, - Dynamic.Mission.PROPELLER_TIP_SPEED, - ], rows=arange, cols=arange) - self.declare_partials('power_coefficient', [ - Dynamic.Mission.SHAFT_POWER, - Dynamic.Mission.DENSITY, - Dynamic.Mission.PROPELLER_TIP_SPEED, - ], rows=arange, cols=arange) - self.declare_partials('power_coefficient', Aircraft.Engine.PROPELLER_DIAMETER) + self.declare_partials( + 'advance_ratio', + [ + Dynamic.Mission.VELOCITY, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + ], + rows=arange, + cols=arange, + ) + self.declare_partials( + 'power_coefficient', + [ + Dynamic.Vehicle.Propulsion.SHAFT_POWER, + Dynamic.Atmosphere.DENSITY, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + ], + rows=arange, + cols=arange, + ) + self.declare_partials('power_coefficient', Aircraft.Engine.Propeller.DIAMETER) def compute(self, inputs, outputs): - diam_prop = inputs[Aircraft.Engine.PROPELLER_DIAMETER] - shp = inputs[Dynamic.Mission.SHAFT_POWER] + diam_prop = inputs[Aircraft.Engine.Propeller.DIAMETER] + shp = inputs[Dynamic.Vehicle.Propulsion.SHAFT_POWER] vtas = inputs[Dynamic.Mission.VELOCITY] - tipspd = inputs[Dynamic.Mission.PROPELLER_TIP_SPEED] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + tipspd = inputs[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] # arbitrarily small number to keep advance ratio nonzero, which allows for static thrust prediction vtas[np.where(vtas <= 1e-6)] = 1e-6 - density_ratio = inputs[Dynamic.Mission.DENSITY] / RHO_SEA_LEVEL_ENGLISH + density_ratio = inputs[Dynamic.Atmosphere.DENSITY] / RHO_SEA_LEVEL_ENGLISH if diam_prop <= 0.0: raise om.AnalysisError( - "Aircraft.Engine.PROPELLER_DIAMETER must be positive.") + "Aircraft.Engine.Propeller.DIAMETER must be positive.") if any(tipspd) <= 0.0: raise om.AnalysisError( - "Dynamic.Mission.PROPELLER_TIP_SPEED must be positive.") + "Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED must be positive." + ) if any(sos) <= 0.0: raise om.AnalysisError( - "Dynamic.Mission.SPEED_OF_SOUND must be positive.") + "Dynamic.Atmosphere.SPEED_OF_SOUND must be positive." + ) if any(density_ratio) <= 0.0: - raise om.AnalysisError("Dynamic.Mission.DENSITY must be positive.") + raise om.AnalysisError("Dynamic.Atmosphere.DENSITY must be positive.") if any(shp) < 0.0: - raise om.AnalysisError("Dynamic.Mission.SHAFT_POWER must be non-negative.") + raise om.AnalysisError( + "Dynamic.Vehicle.Propulsion.SHAFT_POWER must be non-negative." + ) # outputs['density_ratio'] = density_ratio # TODO tip mach was already calculated, revisit this outputs['tip_mach'] = tipspd / sos outputs['advance_ratio'] = math.pi * vtas / tipspd # TODO back out what is going on with unit conversion factor 10e10/(2*6966) + outputs['power_coefficient'] = ( shp * 10.0e10 @@ -572,37 +590,37 @@ def compute(self, inputs, outputs): def compute_partials(self, inputs, partials): vtas = inputs[Dynamic.Mission.VELOCITY] - tipspd = inputs[Dynamic.Mission.PROPELLER_TIP_SPEED] - rho = inputs[Dynamic.Mission.DENSITY] - diam_prop = inputs[Aircraft.Engine.PROPELLER_DIAMETER] - shp = inputs[Dynamic.Mission.SHAFT_POWER] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] + tipspd = inputs[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] + rho = inputs[Dynamic.Atmosphere.DENSITY] + diam_prop = inputs[Aircraft.Engine.Propeller.DIAMETER] + shp = inputs[Dynamic.Vehicle.Propulsion.SHAFT_POWER] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] unit_conversion_const = 10.E10 / (2 * 6966.) - # partials["density_ratio", Dynamic.Mission.DENSITY] = 1 / RHO_SEA_LEVEL_ENGLISH - partials["tip_mach", Dynamic.Mission.PROPELLER_TIP_SPEED] = 1 / sos - partials["tip_mach", Dynamic.Mission.SPEED_OF_SOUND] = -tipspd / sos**2 + # partials["density_ratio", Dynamic.Atmosphere.DENSITY] = 1 / RHO_SEA_LEVEL_ENGLISH + partials["tip_mach", Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] = 1 / sos + partials["tip_mach", Dynamic.Atmosphere.SPEED_OF_SOUND] = -tipspd / sos**2 partials["advance_ratio", Dynamic.Mission.VELOCITY] = math.pi / tipspd - partials["advance_ratio", Dynamic.Mission.PROPELLER_TIP_SPEED] = ( + partials["advance_ratio", Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] = ( -math.pi * vtas / (tipspd * tipspd) ) - partials["power_coefficient", Dynamic.Mission.SHAFT_POWER] = unit_conversion_const * \ + partials["power_coefficient", Dynamic.Vehicle.Propulsion.SHAFT_POWER] = unit_conversion_const * \ RHO_SEA_LEVEL_ENGLISH / (rho * tipspd**3*diam_prop**2) - partials["power_coefficient", Dynamic.Mission.DENSITY] = -unit_conversion_const * shp * \ + partials["power_coefficient", Dynamic.Atmosphere.DENSITY] = -unit_conversion_const * shp * \ RHO_SEA_LEVEL_ENGLISH / (rho * rho * tipspd**3*diam_prop**2) - partials["power_coefficient", Dynamic.Mission.PROPELLER_TIP_SPEED] = -3 * \ + partials["power_coefficient", Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] = -3 * \ unit_conversion_const * shp * RHO_SEA_LEVEL_ENGLISH / \ (rho * tipspd**4*diam_prop**2) - partials["power_coefficient", Aircraft.Engine.PROPELLER_DIAMETER] = -2 * \ + partials["power_coefficient", Aircraft.Engine.Propeller.DIAMETER] = -2 * \ unit_conversion_const * shp * RHO_SEA_LEVEL_ENGLISH / \ (rho * tipspd**3*diam_prop**3) class HamiltonStandard(om.ExplicitComponent): """ - This is Hamilton Standard component rewritten from Fortran code. - The original documentation is available at + This is Hamilton Standard component rewritten from Fortran code. + The original documentation is available at https://ntrs.nasa.gov/api/citations/19720010354/downloads/19720010354.pdf It computes the thrust coefficient of a propeller blade. """ @@ -618,14 +636,16 @@ def setup(self): self.add_input('power_coefficient', val=np.zeros(nn), units='unitless') self.add_input('advance_ratio', val=np.zeros(nn), units='unitless') - add_aviary_input(self, Dynamic.Mission.MACH, val=np.zeros(nn), units='unitless') + add_aviary_input( + self, Dynamic.Atmosphere.MACH, val=np.zeros(nn), units='unitless' + ) self.add_input('tip_mach', val=np.zeros(nn), units='unitless') add_aviary_input( - self, Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, val=0.0, units='unitless' + self, Aircraft.Engine.Propeller.ACTIVITY_FACTOR, val=0.0, units='unitless' ) # Actitivty Factor per Blade add_aviary_input( self, - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, val=0.0, units='unitless', ) # blade integrated lift coeff @@ -638,10 +658,10 @@ def setup(self): def compute(self, inputs, outputs): verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) - act_factor = inputs[Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR][0] - cli = inputs[Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT][0] + 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.NUM_PROPELLER_BLADES + Aircraft.Engine.Propeller.NUM_BLADES ) # TODO verify this works with multiple engine models (i.e. prop mission is # properly slicing these inputs) @@ -757,10 +777,15 @@ def compute(self, inputs, outputs): CP_CLi_table[CL_tab_idx][:cli_len], XPCLI[CL_tab_idx], CPE1X) if (run_flag == 1): ichck = ichck + 1 - if verbosity >= Verbosity.DEBUG or ichck <= 1: + if verbosity == Verbosity.DEBUG or ichck <= Verbosity.BRIEF: if (run_flag == 1): warnings.warn( - f"Mach,VTMACH,J,power_coefficient,CP_Eff =: {inputs[Dynamic.Mission.MACH][i_node]},{inputs['tip_mach'][i_node]},{inputs['advance_ratio'][i_node]},{power_coefficient},{CP_Eff}") + f"Mach = {inputs[Dynamic.Atmosphere.MACH][i_node]}\n" + f"VTMACH = {inputs['tip_mach'][i_node]}\n" + f"J = {inputs['advance_ratio'][i_node]}\n" + f"power_coefficient = {power_coefficient}\n" + f"CP_Eff = {CP_Eff}" + ) if (kl == 4 and CPE1 < 0.010): print( f"Extrapolated data is being used for CLI=.6--CPE1,PXCLI,L= , {CPE1},{PXCLI[kl]},{idx_blade} Suggest inputting CLI=.5") @@ -774,7 +799,7 @@ def compute(self, inputs, outputs): CL_tab_idx = CL_tab_idx+1 if (CL_tab_idx_flg != 1): PCLI, run_flag = _unint( - CL_arr[CL_tab_idx_begin:CL_tab_idx_begin+4], PXCLI[CL_tab_idx_begin:CL_tab_idx_begin+4], inputs[Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT][0]) + CL_arr[CL_tab_idx_begin:CL_tab_idx_begin+4], PXCLI[CL_tab_idx_begin:CL_tab_idx_begin+4], inputs[Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT][0]) else: PCLI = PXCLI[CL_tab_idx_begin] # PCLI = CLI adjustment to power_coefficient @@ -795,9 +820,9 @@ def compute(self, inputs, outputs): "interp failed for CTT (thrust coefficient) in hamilton_standard.py") if run_flag > 1: NERPT = 2 - if verbosity >= Verbosity.DEBUG: - print( - f"ERROR IN PROP. PERF.-- NERPT={NERPT}, run_flag={run_flag}") + print( + f"ERROR IN PROP. PERF.-- NERPT={NERPT}, run_flag={run_flag}" + ) BLLL[ibb], run_flag = _unint( advance_ratio_array[J_begin:J_begin+4], BLL[J_begin:J_begin+4], inputs['advance_ratio'][i_node]) @@ -831,13 +856,14 @@ def compute(self, inputs, outputs): NERPT = 5 if (run_flag == 1): # off lower bound only. - if verbosity >= Verbosity.DEBUG: - print( - f"ERROR IN PROP. PERF.-- NERPT={NERPT}, run_flag={run_flag}, il = {il}, kl = {kl}") + print( + f"ERROR IN PROP. PERF.-- NERPT={NERPT}, " + f"run_flag={run_flag}, il={il}, kl = {kl}" + ) if (inputs['advance_ratio'][i_node] != 0.0): ZMCRT, run_flag = _unint( advance_ratio_array2, mach_corr_table[CL_tab_idx], inputs['advance_ratio'][i_node]) - DMN = inputs[Dynamic.Mission.MACH][i_node] - ZMCRT + DMN = inputs[Dynamic.Atmosphere.MACH][i_node] - ZMCRT else: ZMCRT = mach_tip_corr_arr[CL_tab_idx] DMN = inputs['tip_mach'][i_node] - ZMCRT @@ -847,7 +873,7 @@ def compute(self, inputs, outputs): XFFT[kl], run_flag = _biquad(comp_mach_CT_arr, 1, DMN, CTE2) CL_tab_idx = CL_tab_idx + 1 if (CL_tab_idx_flg != 1): - cli = inputs[Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT][0] + cli = inputs[Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT][0] TCLII, run_flag = _unint( CL_arr[CL_tab_idx_begin:CL_tab_idx_begin+4], TXCLI[CL_tab_idx_begin:CL_tab_idx_begin+4], cli) xft, run_flag = _unint( @@ -887,7 +913,7 @@ def compute(self, inputs, outputs): xft, run_flag = _unint(num_blades_arr, XXXFT, num_blades) # NOTE this could be handled via the metamodel comps (extrapolate flag) - if verbosity >= Verbosity.DEBUG and ichck > 0: + if ichck > 0: print(f" table look-up error = {ichck} (if you go outside the tables.)") outputs['thrust_coefficient'][i_node] = ct @@ -905,21 +931,26 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] - add_aviary_input(self, Aircraft.Engine.PROPELLER_DIAMETER, val=0.0, units='ft') + add_aviary_input(self, Aircraft.Engine.Propeller.DIAMETER, val=0.0, units='ft') self.add_input('install_loss_factor', val=np.zeros(nn), units='unitless') self.add_input('thrust_coefficient', val=np.zeros(nn), units='unitless') self.add_input('comp_tip_loss_factor', val=np.zeros(nn), units='unitless') add_aviary_input( - self, Dynamic.Mission.PROPELLER_TIP_SPEED, val=np.zeros(nn), units='ft/s' + self, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + val=np.zeros(nn), + units='ft/s', ) - self.add_input(Dynamic.Mission.DENSITY, val=np.zeros(nn), units='slug/ft**3') + self.add_input(Dynamic.Atmosphere.DENSITY, val=np.zeros(nn), units='slug/ft**3') self.add_input('advance_ratio', val=np.zeros(nn), units='unitless') self.add_input('power_coefficient', val=np.zeros(nn), units='unitless') self.add_output('thrust_coefficient_comp_loss', val=np.zeros(nn), units='unitless') - add_aviary_output(self, Dynamic.Mission.THRUST, val=np.zeros(nn), units='lbf') + add_aviary_output( + self, Dynamic.Vehicle.Propulsion.THRUST, val=np.zeros(nn), units='lbf' + ) # keep them for reporting but don't seem to be required self.add_output('propeller_efficiency', val=np.zeros(nn), units='unitless') self.add_output('install_efficiency', val=np.zeros(nn), units='unitless') @@ -932,20 +963,23 @@ def setup_partials(self): 'comp_tip_loss_factor', ], rows=arange, cols=arange) self.declare_partials( - Dynamic.Mission.THRUST, + Dynamic.Vehicle.Propulsion.THRUST, [ 'thrust_coefficient', 'comp_tip_loss_factor', - Dynamic.Mission.PROPELLER_TIP_SPEED, - Dynamic.Mission.DENSITY, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + Dynamic.Atmosphere.DENSITY, 'install_loss_factor', ], rows=arange, cols=arange, ) - self.declare_partials(Dynamic.Mission.THRUST, [ - Aircraft.Engine.PROPELLER_DIAMETER, - ]) + self.declare_partials( + Dynamic.Vehicle.Propulsion.THRUST, + [ + Aircraft.Engine.Propeller.DIAMETER, + ] + ) self.declare_partials('propeller_efficiency', [ 'advance_ratio', 'power_coefficient', @@ -963,12 +997,11 @@ def setup_partials(self): def compute(self, inputs, outputs): ctx = inputs['thrust_coefficient']*inputs['comp_tip_loss_factor'] outputs['thrust_coefficient_comp_loss'] = ctx - diam_prop = inputs[Aircraft.Engine.PROPELLER_DIAMETER] - tipspd = inputs[Dynamic.Mission.PROPELLER_TIP_SPEED] + diam_prop = inputs[Aircraft.Engine.Propeller.DIAMETER] + tipspd = inputs[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] install_loss_factor = inputs['install_loss_factor'] - density_ratio = inputs[Dynamic.Mission.DENSITY] / RHO_SEA_LEVEL_ENGLISH - - outputs[Dynamic.Mission.THRUST] = ( + density_ratio = inputs[Dynamic.Atmosphere.DENSITY] / RHO_SEA_LEVEL_ENGLISH + outputs[Dynamic.Vehicle.Propulsion.THRUST] = ( ctx * tipspd**2 * diam_prop**2 @@ -991,16 +1024,16 @@ def compute_partials(self, inputs, partials): nn = self.options['num_nodes'] XFT = inputs['comp_tip_loss_factor'] ctx = inputs['thrust_coefficient']*XFT - diam_prop = inputs[Aircraft.Engine.PROPELLER_DIAMETER] + diam_prop = inputs[Aircraft.Engine.Propeller.DIAMETER] install_loss_factor = inputs['install_loss_factor'] - tipspd = inputs[Dynamic.Mission.PROPELLER_TIP_SPEED] - density_ratio = inputs[Dynamic.Mission.DENSITY] / RHO_SEA_LEVEL_ENGLISH + tipspd = inputs[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] + density_ratio = inputs[Dynamic.Atmosphere.DENSITY] / RHO_SEA_LEVEL_ENGLISH unit_conversion_factor = 364.76 / 1.515E06 partials["thrust_coefficient_comp_loss", 'thrust_coefficient'] = XFT partials["thrust_coefficient_comp_loss", 'comp_tip_loss_factor'] = inputs['thrust_coefficient'] - partials[Dynamic.Mission.THRUST, 'thrust_coefficient'] = ( + partials[Dynamic.Vehicle.Propulsion.THRUST, 'thrust_coefficient'] = ( XFT * tipspd**2 * diam_prop**2 @@ -1008,7 +1041,7 @@ def compute_partials(self, inputs, partials): * unit_conversion_factor * (1.0 - install_loss_factor) ) - partials[Dynamic.Mission.THRUST, 'comp_tip_loss_factor'] = ( + partials[Dynamic.Vehicle.Propulsion.THRUST, 'comp_tip_loss_factor'] = ( inputs['thrust_coefficient'] * tipspd**2 * diam_prop**2 @@ -1016,7 +1049,7 @@ def compute_partials(self, inputs, partials): * unit_conversion_factor * (1.0 - install_loss_factor) ) - partials[Dynamic.Mission.THRUST, Dynamic.Mission.PROPELLER_TIP_SPEED] = ( + partials[Dynamic.Vehicle.Propulsion.THRUST, Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] = ( 2 * ctx * tipspd @@ -1025,7 +1058,7 @@ def compute_partials(self, inputs, partials): * unit_conversion_factor * (1.0 - install_loss_factor) ) - partials[Dynamic.Mission.THRUST, Aircraft.Engine.PROPELLER_DIAMETER] = ( + partials[Dynamic.Vehicle.Propulsion.THRUST, Aircraft.Engine.Propeller.DIAMETER] = ( 2 * ctx * tipspd**2 @@ -1034,14 +1067,14 @@ def compute_partials(self, inputs, partials): * unit_conversion_factor * (1.0 - install_loss_factor) ) - partials[Dynamic.Mission.THRUST, Dynamic.Mission.DENSITY] = ( + partials[Dynamic.Vehicle.Propulsion.THRUST, Dynamic.Atmosphere.DENSITY] = ( ctx * tipspd**2 * diam_prop**2 * unit_conversion_factor * (1.0 - install_loss_factor) / RHO_SEA_LEVEL_ENGLISH ) - partials[Dynamic.Mission.THRUST, 'install_loss_factor'] = ( + partials[Dynamic.Vehicle.Propulsion.THRUST, 'install_loss_factor'] = ( -ctx * tipspd**2 * diam_prop**2 * density_ratio * unit_conversion_factor ) diff --git a/aviary/subsystems/propulsion/propeller/propeller_builder.py b/aviary/subsystems/propulsion/propeller/propeller_builder.py new file mode 100644 index 000000000..ddcb60e83 --- /dev/null +++ b/aviary/subsystems/propulsion/propeller/propeller_builder.py @@ -0,0 +1,124 @@ +from aviary.subsystems.subsystem_builder_base import SubsystemBuilderBase +from aviary.subsystems.propulsion.propeller.propeller_performance import ( + PropellerPerformance, +) +from aviary.variable_info.variables import Aircraft, Dynamic, Mission + + +class PropellerBuilder(SubsystemBuilderBase): + """ + Define the builder for a propeller model using the Hamilton Standard methodology that + provides methods to define the propeller subsystem's states, design variables, + fixed values, initial guesses, and mass names. It also provides methods to build + OpenMDAO systems for the pre-mission and mission computations of the subsystem, + to get the constraints for the subsystem, and to preprocess the inputs for + the subsystem. + """ + + def __init__(self, name='HS_propeller'): + """Initializes the PropellerBuilder object with a given name.""" + super().__init__(name) + + def build_pre_mission(self, aviary_inputs): + """Builds an OpenMDAO system for the pre-mission computations of the subsystem.""" + return + + def build_mission(self, num_nodes, aviary_inputs): + """Builds an OpenMDAO system for the mission computations of the subsystem.""" + return PropellerPerformance(num_nodes=num_nodes, aviary_options=aviary_inputs) + + def get_design_vars(self): + """ + Design vars are only tested to see if they exist in pre_mission + Returns a dictionary of design variables for the gearbox subsystem, where the keys are the + names of the design variables, and the values are dictionaries that contain the units for + the design variable, the lower and upper bounds for the design variable, and any + additional keyword arguments required by OpenMDAO for the design variable. + + Returns + ------- + parameters : dict + A dict of names for the propeller subsystem. + """ + + # TODO bounds are rough placeholders + DVs = { + Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR: { + 'units': 'unitless', + 'lower': 100, + 'upper': 200, + # 'val': 100, # initial value + }, + Aircraft.Engine.PROPELLER_DIAMETER: { + 'units': 'ft', + 'lower': 0.0, + 'upper': None, + # 'val': 8, # initial value + }, + Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT: { + 'units': 'unitless', + 'lower': 0.0, + 'upper': 0.5, + # 'val': 0.5, + }, + } + return DVs + + def get_parameters(self, aviary_inputs=None, phase_info=None): + """ + Parameters are only tested to see if they exist in mission. + The value doesn't change throughout the mission. + Returns a dictionary of fixed values for the propeller subsystem, where the keys + are the names of the fixed values, and the values are dictionaries that contain + the fixed value for the variable, the units for the variable, and any additional + keyword arguments required by OpenMDAO for the variable. + + Returns + ------- + parameters : dict + A dict of names for the propeller subsystem. + """ + parameters = { + Aircraft.Engine.PROPELLER_TIP_MACH_MAX: { + 'val': 1.0, + 'units': 'unitless', + }, + Aircraft.Engine.PROPELLER_TIP_SPEED_MAX: { + 'val': 0.0, + 'units': 'unitless', + }, + Aircraft.Engine.PROPELLER_TIP_SPEED_MAX: { + 'val': 0.0, + 'units': 'ft/s', + }, + Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT: { + 'val': 0.0, + 'units': 'unitless', + }, + Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR: { + 'val': 0.0, + 'units': 'unitless', + }, + Aircraft.Engine.PROPELLER_DIAMETER: { + 'val': 0.0, + 'units': 'ft', + }, + Aircraft.Nacelle.AVG_DIAMETER: { + 'val': 0.0, + 'units': 'ft', + }, + } + + return parameters + + def get_mass_names(self): + return [Aircraft.Engine.Gearbox.MASS] + + def get_outputs(self): + return [ + Dynamic.Mission.SHAFT_POWER + '_out', + Dynamic.Mission.SHAFT_POWER_MAX + '_out', + Dynamic.Mission.RPM + '_out', + Dynamic.Mission.TORQUE + '_out', + Mission.Constraints.GEARBOX_SHAFT_POWER_RESIDUAL, + ] diff --git a/aviary/subsystems/propulsion/propeller/propeller_map.py b/aviary/subsystems/propulsion/propeller/propeller_map.py index 29cdd7a8b..204bc9de0 100644 --- a/aviary/subsystems/propulsion/propeller/propeller_map.py +++ b/aviary/subsystems/propulsion/propeller/propeller_map.py @@ -50,7 +50,7 @@ def __init__(self, name='propeller', options: AviaryValues = None, # Create dict for variables present in propeller data with associated units self.propeller_variables = {} - data_file = options.get_val(Aircraft.Engine.PROPELLER_DATA_FILE) + data_file = options.get_val(Aircraft.Engine.Propeller.DATA_FILE) self._read_data(data_file) def _read_data(self, data_file): @@ -122,7 +122,7 @@ def build_propeller_interpolator(self, num_nodes, options=None): method=interp_method, extrapolate=True, vec_size=num_nodes) # add inputs and outputs to interpolator - # depending on p, selected_mach can be Mach number (Dynamic.Mission.MACH) or helical Mach number + # depending on p, selected_mach can be Mach number (Dynamic.Atmosphere.MACH) or helical Mach number propeller.add_input('selected_mach', self.data[MACH], units='unitless', diff --git a/aviary/subsystems/propulsion/propeller/propeller_performance.py b/aviary/subsystems/propulsion/propeller/propeller_performance.py index 9d952eb60..e124ffe69 100644 --- a/aviary/subsystems/propulsion/propeller/propeller_performance.py +++ b/aviary/subsystems/propulsion/propeller/propeller_performance.py @@ -73,23 +73,26 @@ def setup(self): self, Dynamic.Mission.VELOCITY, val=np.zeros(num_nodes), units='ft/s' ) add_aviary_input( - self, Dynamic.Mission.SPEED_OF_SOUND, val=np.zeros(num_nodes), units='ft/s' + self, + Dynamic.Atmosphere.SPEED_OF_SOUND, + val=np.zeros(num_nodes), + units='ft/s', ) add_aviary_input( - self, Dynamic.Mission.RPM, val=np.zeros(num_nodes), units='rpm' + self, Dynamic.Vehicle.Propulsion.RPM, val=np.zeros(num_nodes), units='rpm' ) add_aviary_input( - self, Aircraft.Engine.PROPELLER_TIP_MACH_MAX, val=1.0, units='unitless' + self, Aircraft.Engine.Propeller.TIP_MACH_MAX, val=1.0, units='unitless' ) add_aviary_input( - self, Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, val=0.0, units='ft/s' + self, Aircraft.Engine.Propeller.TIP_SPEED_MAX, val=0.0, units='ft/s' ) - add_aviary_input(self, Aircraft.Engine.PROPELLER_DIAMETER, val=0.0, units='ft') + add_aviary_input(self, Aircraft.Engine.Propeller.DIAMETER, val=0.0, units='ft') add_aviary_output( self, - Dynamic.Mission.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, val=np.zeros(num_nodes), units='ft/s', ) @@ -107,7 +110,7 @@ def setup_partials(self): 'propeller_tip_speed_limit', [ Dynamic.Mission.VELOCITY, - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.SPEED_OF_SOUND, ], rows=r, cols=r, @@ -115,24 +118,24 @@ def setup_partials(self): self.declare_partials( 'propeller_tip_speed_limit', [ - Aircraft.Engine.PROPELLER_TIP_MACH_MAX, - Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, + Aircraft.Engine.Propeller.TIP_MACH_MAX, + Aircraft.Engine.Propeller.TIP_SPEED_MAX, ], ) self.declare_partials( - Dynamic.Mission.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, [ - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.RPM, ], rows=r, cols=r, ) self.declare_partials( - Dynamic.Mission.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, [ - Aircraft.Engine.PROPELLER_DIAMETER, + Aircraft.Engine.Propeller.DIAMETER, ], ) @@ -140,11 +143,11 @@ def compute(self, inputs, outputs): num_nodes = self.options['num_nodes'] velocity = inputs[Dynamic.Mission.VELOCITY] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] - tip_mach_max = inputs[Aircraft.Engine.PROPELLER_TIP_MACH_MAX] - tip_speed_max = inputs[Aircraft.Engine.PROPELLER_TIP_SPEED_MAX] - rpm = inputs[Dynamic.Mission.RPM] - diam = inputs[Aircraft.Engine.PROPELLER_DIAMETER] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] + tip_mach_max = inputs[Aircraft.Engine.Propeller.TIP_MACH_MAX] + tip_speed_max = inputs[Aircraft.Engine.Propeller.TIP_SPEED_MAX] + rpm = inputs[Dynamic.Vehicle.Propulsion.RPM] + diam = inputs[Aircraft.Engine.Propeller.DIAMETER] tip_speed_mach_limit = ((sos * tip_mach_max) ** 2 - velocity**2) ** 0.5 # use KSfunction for smooth derivitive across minimum @@ -154,18 +157,18 @@ def compute(self, inputs, outputs): ).flatten() propeller_tip_speed = rpm * diam * math.pi / 60 - outputs[Dynamic.Mission.PROPELLER_TIP_SPEED] = propeller_tip_speed + outputs[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED] = propeller_tip_speed outputs['propeller_tip_speed_limit'] = propeller_tip_speed_limit def compute_partials(self, inputs, J): num_nodes = self.options['num_nodes'] velocity = inputs[Dynamic.Mission.VELOCITY] - sos = inputs[Dynamic.Mission.SPEED_OF_SOUND] - rpm = inputs[Dynamic.Mission.RPM] - tip_mach_max = inputs[Aircraft.Engine.PROPELLER_TIP_MACH_MAX] - tip_speed_max = inputs[Aircraft.Engine.PROPELLER_TIP_SPEED_MAX] - diam = inputs[Aircraft.Engine.PROPELLER_DIAMETER] + sos = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] + rpm = inputs[Dynamic.Vehicle.Propulsion.RPM] + tip_mach_max = inputs[Aircraft.Engine.Propeller.TIP_MACH_MAX] + tip_speed_max = inputs[Aircraft.Engine.Propeller.TIP_SPEED_MAX] + diam = inputs[Aircraft.Engine.Propeller.DIAMETER] tip_speed_max_nn = np.tile(tip_speed_max, num_nodes) @@ -185,21 +188,19 @@ def compute_partials(self, inputs, J): dspeed_dsm = dKS[:, 0] J['propeller_tip_speed_limit', Dynamic.Mission.VELOCITY] = dspeed_dv - J['propeller_tip_speed_limit', Dynamic.Mission.SPEED_OF_SOUND] = dspeed_ds - J['propeller_tip_speed_limit', Aircraft.Engine.PROPELLER_TIP_MACH_MAX] = ( + J['propeller_tip_speed_limit', Dynamic.Atmosphere.SPEED_OF_SOUND] = dspeed_ds + J['propeller_tip_speed_limit', Aircraft.Engine.Propeller.TIP_MACH_MAX] = ( dspeed_dmm ) - J['propeller_tip_speed_limit', Aircraft.Engine.PROPELLER_TIP_SPEED_MAX] = ( + J['propeller_tip_speed_limit', Aircraft.Engine.Propeller.TIP_SPEED_MAX] = ( dspeed_dsm ) - J[Dynamic.Mission.PROPELLER_TIP_SPEED, Dynamic.Mission.RPM] = ( - diam * math.pi / 60 - ) + J[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.RPM] = (diam * math.pi / 60) - J[Dynamic.Mission.PROPELLER_TIP_SPEED, Aircraft.Engine.PROPELLER_DIAMETER] = ( - rpm * math.pi / 60 - ) + J[Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + Aircraft.Engine.Propeller.DIAMETER] = (rpm * math.pi / 60) class OutMachs(om.ExplicitComponent): @@ -621,8 +622,10 @@ def setup(self): self.add_subsystem( name='sqa_comp', subsys=AreaSquareRatio(num_nodes=nn, smooth_sqa=True), - promotes_inputs=[("DiamNac", Aircraft.Nacelle.AVG_DIAMETER), - ("DiamProp", Aircraft.Engine.PROPELLER_DIAMETER)], + promotes_inputs=[ + ("DiamNac", Aircraft.Nacelle.AVG_DIAMETER), + ("DiamProp", Aircraft.Engine.Propeller.DIAMETER), + ], promotes_outputs=["sqa_array"], ) @@ -630,7 +633,7 @@ def setup(self): name='zje_comp', subsys=AdvanceRatio(num_nodes=nn, smooth_zje=True), promotes_inputs=["sqa_array", ("vtas", Dynamic.Mission.VELOCITY), - ("tipspd", Dynamic.Mission.PROPELLER_TIP_SPEED)], + ("tipspd", Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED)], promotes_outputs=["equiv_adv_ratio"], ) @@ -726,14 +729,17 @@ def setup(self): # TODO options are lists here when using full Aviary problem - need # further investigation compute_installation_loss = aviary_options.get_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS ) if isinstance(compute_installation_loss, (list, np.ndarray)): compute_installation_loss = compute_installation_loss[0] - use_propeller_map = aviary_options.get_val(Aircraft.Engine.USE_PROPELLER_MAP) - if isinstance(use_propeller_map, (list, np.ndarray)): - use_propeller_map = use_propeller_map[0] + try: + prop_file_path = aviary_options.get_val(Aircraft.Engine.Propeller.DATA_FILE) + except KeyError: + prop_file_path = None + if isinstance(prop_file_path, (list, np.ndarray)): + prop_file_path = prop_file_path[0] # compute the propeller tip speed based on the input RPM and diameter of the propeller # NOTE allows for violation of tip speed limits @@ -748,9 +754,9 @@ def setup(self): subsys=InstallLoss(num_nodes=nn), promotes_inputs=[ Aircraft.Nacelle.AVG_DIAMETER, - Aircraft.Engine.PROPELLER_DIAMETER, + Aircraft.Engine.Propeller.DIAMETER, Dynamic.Mission.VELOCITY, - Dynamic.Mission.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, ], promotes_outputs=['install_loss_factor'], ) @@ -763,12 +769,12 @@ def setup(self): name='pre_hamilton_standard', subsys=PreHamiltonStandard(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.DENSITY, - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, Dynamic.Mission.VELOCITY, - Dynamic.Mission.PROPELLER_TIP_SPEED, - Aircraft.Engine.PROPELLER_DIAMETER, - Dynamic.Mission.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + Aircraft.Engine.Propeller.DIAMETER, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, ], promotes_outputs=[ "power_coefficient", @@ -778,9 +784,8 @@ def setup(self): ], ) - if use_propeller_map: + if prop_file_path is not None: prop_model = PropellerMap('prop', aviary_options) - prop_file_path = aviary_options.get_val(Aircraft.Engine.PROPELLER_DATA_FILE) mach_type = prop_model.read_and_set_mach_type(prop_file_path) if mach_type == OutMachType.HELICAL_MACH: self.add_subsystem( @@ -788,7 +793,7 @@ def setup(self): subsys=OutMachs( num_nodes=nn, output_mach_type=OutMachType.HELICAL_MACH ), - promotes_inputs=[("mach", Dynamic.Mission.MACH), "tip_mach"], + promotes_inputs=[("mach", Dynamic.Atmosphere.MACH), "tip_mach"], promotes_outputs=[("helical_mach", "selected_mach")], ) else: @@ -801,7 +806,7 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ("mach", Dynamic.Mission.MACH), + ("mach", Dynamic.Atmosphere.MACH), ], promotes_outputs=["selected_mach"], ) @@ -828,12 +833,12 @@ def setup(self): name='hamilton_standard', subsys=HamiltonStandard(num_nodes=nn, aviary_options=aviary_options), promotes_inputs=[ - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, "power_coefficient", "advance_ratio", "tip_mach", - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, ], promotes_outputs=[ "thrust_coefficient", @@ -847,16 +852,16 @@ def setup(self): promotes_inputs=[ "thrust_coefficient", "comp_tip_loss_factor", - Dynamic.Mission.PROPELLER_TIP_SPEED, - Aircraft.Engine.PROPELLER_DIAMETER, - Dynamic.Mission.DENSITY, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + Aircraft.Engine.Propeller.DIAMETER, + Dynamic.Atmosphere.DENSITY, 'install_loss_factor', "advance_ratio", "power_coefficient", ], promotes_outputs=[ "thrust_coefficient_comp_loss", - Dynamic.Mission.THRUST, + Dynamic.Vehicle.Propulsion.THRUST, "propeller_efficiency", "install_efficiency", ], diff --git a/aviary/subsystems/propulsion/propulsion_builder.py b/aviary/subsystems/propulsion/propulsion_builder.py index 3ba9ea872..24d91112a 100644 --- a/aviary/subsystems/propulsion/propulsion_builder.py +++ b/aviary/subsystems/propulsion/propulsion_builder.py @@ -10,6 +10,8 @@ import numpy as np +from openmdao.utils.units import convert_units as _convert_units + from aviary.interface.utils.markdown_utils import write_markdown_variable_table from aviary.subsystems.subsystem_builder_base import SubsystemBuilderBase @@ -151,11 +153,23 @@ def get_parameters(self, aviary_inputs=None, phase_info=None): # collect all the parameters for engines for engine in self.engine_models: engine_params = engine.get_parameters() + # for param in engine_params: + # # For any parameters that need to be vectorized for multiple engines, + # # apply correct shape + # if param in params: + # try: + # shape_old = params[param]['shape'][0] + # except KeyError: + # # If shape is not defined yet, this is the first time there is + # # a duplicate + # shape_old = 1 + # engine_params[param]['shape'] = (shape_old + 1,) + params.update(engine_params) # for any parameters that need to be vectorized for multiple engines, apply # correct shape - engine_vars = _get_engine_variables() + engine_vars = [var for var in _get_engine_variables()] for var in params: if var in engine_vars: # TODO shape for variables that are supposed to be vectors, like wing diff --git a/aviary/subsystems/propulsion/propulsion_mission.py b/aviary/subsystems/propulsion/propulsion_mission.py index 6237f7dcf..8dc6f7a6f 100644 --- a/aviary/subsystems/propulsion/propulsion_mission.py +++ b/aviary/subsystems/propulsion/propulsion_mission.py @@ -34,21 +34,50 @@ def setup(self): num_engine_type = len(engine_models) if num_engine_type > 1: + # We need a component to add parameters to problem. Dymos can't find it when + # it is already sliced across several components. + # TODO is this problem fixable from dymos end (introspection includes parameters)? + + # create set of params + # TODO get_parameters() should have access to aviary options + phase info + param_dict = {} + # save parameters for use in configure() + parameters = self.parameters = set() + for engine in engine_models: + eng_params = engine.get_parameters() + param_dict.update(eng_params) + + parameters.update(param_dict.keys()) + + # if params exist, create execcomp, fill with placeholder equations + if len(parameters) != 0: + comp = om.ExecComp(has_diag_partials=True) + + for i, param in enumerate(parameters): + # try to find units information + try: + units = param_dict[param]['units'] + except KeyError: + units = 'unitless' + + attrs = { + f'x_{i}': { + 'val': np.ones(num_engine_type), + 'units': units, + }, + f'y_{i}': { + 'val': np.ones(num_engine_type), + 'units': units, + }, + } + comp.add_expr( + f'y_{i}=x_{i}', + **attrs, + ) - # We need a single component with scale_factor. Dymos can't find it when it is - # already sliced across several component. - # TODO this only works for engine decks. Need to fix problem in generic way - comp = om.ExecComp( - "y=x", - y={'val': np.ones(num_engine_type), 'units': 'unitless'}, - x={'val': np.ones(num_engine_type), 'units': 'unitless'}, - has_diag_partials=True, - ) self.add_subsystem( - "scale_passthrough", + "parameter_passthrough", comp, - promotes_inputs=[('x', Aircraft.Engine.SCALE_FACTOR)], - promotes_outputs=[('y', 'passthrough_scale_factor')], ) for i, engine in enumerate(engine_models): @@ -61,22 +90,25 @@ def setup(self): # split vectorized throttles and connect to the correct engine model self.promotes( engine.name, - inputs=[Dynamic.Mission.THROTTLE], + inputs=[Dynamic.Vehicle.Propulsion.THROTTLE], src_indices=om.slicer[:, i], ) - self.promotes( - engine.name, - inputs=[(Aircraft.Engine.SCALE_FACTOR, 'passthrough_scale_factor')], - src_indices=om.slicer[i], - ) + # loop through params and slice as needed + params = engine.get_parameters() + for param in params: + self.promotes( + engine.name, + inputs=[(param, param + '_passthrough')], + src_indices=om.slicer[i], + ) # TODO if only some engine use hybrid throttle, source vector will have an # index for that engine that is unused, will this confuse optimizer? if engine.use_hybrid_throttle: self.promotes( engine.name, - inputs=[Dynamic.Mission.HYBRID_THROTTLE], + inputs=[Dynamic.Vehicle.Propulsion.HYBRID_THROTTLE], src_indices=om.slicer[:, i], ) else: @@ -89,41 +121,67 @@ def setup(self): promotes_inputs=['*'], ) - self.promotes(engine.name, inputs=[Dynamic.Mission.THROTTLE]) + self.promotes(engine.name, inputs=[Dynamic.Vehicle.Propulsion.THROTTLE]) if engine.use_hybrid_throttle: - self.promotes(engine.name, inputs=[Dynamic.Mission.HYBRID_THROTTLE]) + self.promotes( + engine.name, inputs=[Dynamic.Vehicle.Propulsion.HYBRID_THROTTLE] + ) # TODO might be able to avoid hardcoding using propulsion Enums # mux component to vectorize individual engine outputs into 2d arrays perf_mux = om.MuxComp(vec_size=num_engine_type) # add each engine data variable to mux component perf_mux.add_var( - Dynamic.Mission.THRUST, val=0, shape=(nn,), axis=1, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST, val=0, shape=(nn,), axis=1, units='lbf' ) perf_mux.add_var( - Dynamic.Mission.THRUST_MAX, val=0, shape=(nn,), axis=1, units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_MAX, + val=0, + shape=(nn,), + axis=1, + units='lbf', ) perf_mux.add_var( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, val=0, shape=(nn,), axis=1, units='lbm/h', ) perf_mux.add_var( - Dynamic.Mission.ELECTRIC_POWER_IN, val=0, shape=(nn,), axis=1, units='kW' + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, + val=0, + shape=(nn,), + axis=1, + units='kW', ) perf_mux.add_var( - Dynamic.Mission.NOX_RATE, val=0, shape=(nn,), axis=1, units='lb/h' + Dynamic.Vehicle.Propulsion.NOX_RATE, + val=0, + shape=(nn,), + axis=1, + units='lb/h', ) perf_mux.add_var( - Dynamic.Mission.TEMPERATURE_T4, val=0, shape=(nn,), axis=1, units='degR' + Dynamic.Vehicle.Propulsion.TEMPERATURE_T4, + val=0, + shape=(nn,), + axis=1, + units='degR', ) perf_mux.add_var( - Dynamic.Mission.SHAFT_POWER, val=0, shape=(nn,), axis=1, units='hp' + Dynamic.Vehicle.Propulsion.SHAFT_POWER, + val=0, + shape=(nn,), + axis=1, + units='hp', ) perf_mux.add_var( - Dynamic.Mission.SHAFT_POWER_MAX, val=0, shape=(nn,), axis=1, units='hp' + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, + val=0, + shape=(nn,), + axis=1, + units='hp', ) # perf_mux.add_var( # 'exit_area_unscaled', @@ -149,19 +207,19 @@ def configure(self): # TODO this list shouldn't be hardcoded so it can be extended by users supported_outputs = [ - Dynamic.Mission.ELECTRIC_POWER_IN, - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, - Dynamic.Mission.NOX_RATE, - Dynamic.Mission.SHAFT_POWER, - Dynamic.Mission.SHAFT_POWER_MAX, - Dynamic.Mission.TEMPERATURE_T4, - Dynamic.Mission.THRUST, - Dynamic.Mission.THRUST_MAX, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.NOX_RATE, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, + Dynamic.Vehicle.Propulsion.TEMPERATURE_T4, + Dynamic.Vehicle.Propulsion.THRUST, + Dynamic.Vehicle.Propulsion.THRUST_MAX, ] engine_models = self.options['engine_models'] engine_names = [engine.name for engine in engine_models] - # num_engine_type = len(engine_models) + num_engine_type = len(engine_models) # determine if openMDAO messages and warnings should be suppressed verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) @@ -218,6 +276,38 @@ def configure(self): ) # TODO handle setting of other variables from engine outputs (e.g. Aircraft.Engine.****) + if num_engine_type > 1: + # commented out block of code is for experimenting with automatically finding + # inputs that need a passthrough, rather than relying on get_parameters() + # being properly set up + + # custom promote parameters with aliasing to connect to passthrough component + # for engine in engine_models: + # get inputs to engine model + # engine_comp = self._get_subsystem(engine.name) + # input_dict = engine_comp.list_inputs( + # return_format='dict', units=True, out_stream=None, all_procs=True + # ) + # # TODO this catches not fully promoted variables are caught - is this + # # wanted? + # input_list = list( + # set( + # input_dict[key]['prom_name'] + # for key in input_dict + # if '.' not in input_dict[key]['prom_name'] + # ) + # ) + # promotions = [] + for i, param in enumerate(self.parameters): + self.promotes( + 'parameter_passthrough', + inputs=[(f'x_{i}', param)], + outputs=[(f'y_{i}', param + '_passthrough')], + ) + # if param in input_dict: + # promotions.append((param, param + '_passthrough')) + # self.promotes(engine.name, inputs=promotions) + class PropulsionSum(om.ExplicitComponent): ''' @@ -240,36 +330,52 @@ def setup(self): ) self.add_input( - Dynamic.Mission.THRUST, val=np.zeros((nn, num_engine_type)), units='lbf' + Dynamic.Vehicle.Propulsion.THRUST, + val=np.zeros((nn, num_engine_type)), + units='lbf', ) self.add_input( - Dynamic.Mission.THRUST_MAX, val=np.zeros((nn, num_engine_type)), units='lbf' + Dynamic.Vehicle.Propulsion.THRUST_MAX, + val=np.zeros((nn, num_engine_type)), + units='lbf', ) self.add_input( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, val=np.zeros((nn, num_engine_type)), units='lbm/h', ) self.add_input( - Dynamic.Mission.ELECTRIC_POWER_IN, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, val=np.zeros((nn, num_engine_type)), units='kW', ) self.add_input( - Dynamic.Mission.NOX_RATE, val=np.zeros((nn, num_engine_type)), units='lbm/h' + Dynamic.Vehicle.Propulsion.NOX_RATE, + val=np.zeros((nn, num_engine_type)), + units='lbm/h', ) - self.add_output(Dynamic.Mission.THRUST_TOTAL, val=np.zeros(nn), units='lbf') - self.add_output(Dynamic.Mission.THRUST_MAX_TOTAL, val=np.zeros(nn), units='lbf') self.add_output( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, val=np.zeros(nn), units='lbf' + ) + self.add_output( + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + val=np.zeros(nn), + units='lbf', + ) + self.add_output( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, val=np.zeros(nn), units='lbm/h', ) self.add_output( - Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, val=np.zeros(nn), units='kW' + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, + val=np.zeros(nn), + units='kW', + ) + self.add_output( + Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, val=np.zeros(nn), units='lbm/h' ) - self.add_output(Dynamic.Mission.NOX_RATE_TOTAL, val=np.zeros(nn), units='lbm/h') def setup_partials(self): nn = self.options['num_nodes'] @@ -283,36 +389,36 @@ def setup_partials(self): c = np.arange(nn * num_engine_type, dtype=int) self.declare_partials( - Dynamic.Mission.THRUST_TOTAL, - Dynamic.Mission.THRUST, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST, val=deriv, rows=r, cols=c, ) self.declare_partials( - Dynamic.Mission.THRUST_MAX_TOTAL, - Dynamic.Mission.THRUST_MAX, + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_MAX, val=deriv, rows=r, cols=c, ) self.declare_partials( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, val=deriv, rows=r, cols=c, ) self.declare_partials( - Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, - Dynamic.Mission.ELECTRIC_POWER_IN, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, val=deriv, rows=r, cols=c, ) self.declare_partials( - Dynamic.Mission.NOX_RATE_TOTAL, - Dynamic.Mission.NOX_RATE, + Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, + Dynamic.Vehicle.Propulsion.NOX_RATE, val=deriv, rows=r, cols=c, @@ -323,16 +429,20 @@ def compute(self, inputs, outputs): Aircraft.Engine.NUM_ENGINES ) - thrust = inputs[Dynamic.Mission.THRUST] - thrust_max = inputs[Dynamic.Mission.THRUST_MAX] - fuel_flow = inputs[Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE] - electric = inputs[Dynamic.Mission.ELECTRIC_POWER_IN] - nox = inputs[Dynamic.Mission.NOX_RATE] + thrust = inputs[Dynamic.Vehicle.Propulsion.THRUST] + thrust_max = inputs[Dynamic.Vehicle.Propulsion.THRUST_MAX] + fuel_flow = inputs[Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE] + electric = inputs[Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN] + nox = inputs[Dynamic.Vehicle.Propulsion.NOX_RATE] - outputs[Dynamic.Mission.THRUST_TOTAL] = np.dot(thrust, num_engines) - outputs[Dynamic.Mission.THRUST_MAX_TOTAL] = np.dot(thrust_max, num_engines) - outputs[Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL] = np.dot( + outputs[Dynamic.Vehicle.Propulsion.THRUST_TOTAL] = np.dot(thrust, num_engines) + outputs[Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL] = np.dot( + thrust_max, num_engines + ) + outputs[Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL] = np.dot( fuel_flow, num_engines ) - outputs[Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL] = np.dot(electric, num_engines) - outputs[Dynamic.Mission.NOX_RATE_TOTAL] = np.dot(nox, num_engines) + outputs[Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL] = np.dot( + electric, num_engines + ) + outputs[Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL] = np.dot(nox, num_engines) diff --git a/aviary/subsystems/propulsion/propulsion_premission.py b/aviary/subsystems/propulsion/propulsion_premission.py index 7480211bf..8c48bbfef 100644 --- a/aviary/subsystems/propulsion/propulsion_premission.py +++ b/aviary/subsystems/propulsion/propulsion_premission.py @@ -17,11 +17,12 @@ class PropulsionPreMission(om.Group): def initialize(self): self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', + ) self.options.declare( - 'engine_models', types=list, - desc='list of EngineModels on aircraft' + 'engine_models', types=list, desc='list of EngineModels on aircraft' ) def setup(self): @@ -33,7 +34,7 @@ def setup(self): # value relevant to that variable - this group's configure step will handle # promoting/connecting just the relevant index in vectorized inputs/outputs for # each component here - # Promotions are handled in self.configure() + # Promotions are handled in configure() for engine in engine_models: subsys = engine.build_pre_mission(options) if subsys: @@ -41,26 +42,24 @@ def setup(self): proms = None else: proms = ['*'] - self.add_subsystem(engine.name, - subsys=subsys, - promotes_outputs=proms, - ) + self.add_subsystem( + engine.name, + subsys=subsys, + promotes_outputs=proms, + ) if num_engine_type > 1: # Add an empty mux comp, which will be customized to handle all required - # outputs in self.configure() + # outputs in configure() self.add_subsystem( - 'pre_mission_mux', - subsys=om.MuxComp(), - promotes_outputs=['*'] + 'pre_mission_mux', subsys=om.MuxComp(), promotes_outputs=['*'] ) self.add_subsystem( 'propulsion_sum', - subsys=PropulsionSum( - aviary_options=options), + subsys=PropulsionSum(aviary_options=options), promotes_inputs=['*'], - promotes_outputs=['*'] + promotes_outputs=['*'], ) def configure(self): @@ -69,8 +68,8 @@ def configure(self): # so vectorized inputs/outputs are a problem. Slice all needed vector inputs and pass # pre_mission components only the value they need, then mux all the outputs back together - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + engine_models = self.options['engine_models'] + num_engine_type = len(engine_models) # determine if openMDAO messages and warnings should be suppressed verbosity = self.options['aviary_options'].get_val(Settings.VERBOSITY) @@ -80,77 +79,98 @@ def configure(self): if verbosity > Verbosity.VERBOSE: out_stream = sys.stdout - comp_list = [ - self._get_subsystem(group) - for group in dir(self) - if self._get_subsystem(group) - and group not in ['pre_mission_mux', 'propulsion_sum'] - ] + # Patterns to identify which inputs/outputs are vectorized and need to be + # split then re-muxed + pattern = ['engine:', 'nacelle:'] # Dictionary of all unique inputs/outputs from all new components, keys are # units for each var unique_outputs = {} - unique_inputs = {} + # unique_inputs = {} - # dictionaries of inputs/outputs for each added component in prop pre-mission + # dictionaries of inputs/outputs for engine in prop pre-mission input_dict = {} output_dict = {} - for idx, comp in enumerate(comp_list): + for idx, engine_model in enumerate(engine_models): + engine = self._get_subsystem(engine_model.name) # Patterns to identify which inputs/outputs are vectorized and need to be # split then re-muxed pattern = ['engine:', 'nacelle:'] # pull out all inputs (in dict format) in component - comp_inputs = comp.list_inputs( - return_format='dict', units=True, out_stream=out_stream, all_procs=True + eng_inputs = engine.list_inputs( + return_format='dict', + units=True, + out_stream=out_stream, + all_procs=True, + ) + # switch dictionary keys to promoted name rather than full path + # only handle variables that were top-level promoted inside engine model + eng_inputs = dict( + [ + (eng_inputs[key]['prom_name'], eng_inputs[key]) + for key in eng_inputs + if '.' not in eng_inputs[key]['prom_name'] + ] ) # only keep inputs if they contain the pattern - input_dict[comp.name] = dict( - (key, comp_inputs[key]) - for key in comp_inputs + input_dict[engine.name] = dict( + (key, eng_inputs[key]) + for key in eng_inputs if any([x in key for x in pattern]) ) - # Track list of ALL inputs present in prop pre-mission in a "flat" dict. - # Repeating inputs will just override what's already in the dict - we don't - # care if units get overridden, if they differ openMDAO will convert - # (if they aren't compatible, then a component specified the wrong units and - # needs to be fixed there) - unique_inputs.update([(key, input_dict[comp.name][key]['units']) - for key in input_dict[comp.name]]) # do the same thing with outputs - comp_outputs = comp.list_outputs( + eng_outputs = engine.list_outputs( return_format='dict', units=True, out_stream=out_stream, all_procs=True ) - output_dict[comp.name] = dict( - (key, comp_outputs[key]) - for key in comp_outputs + eng_outputs = dict( + [ + (eng_outputs[key]['prom_name'], eng_outputs[key]) + for key in eng_outputs + if '.' not in eng_outputs[key]['prom_name'] + ] + ) + output_dict[engine.name] = dict( + (key, eng_outputs[key]) + for key in eng_outputs if any([x in key for x in pattern]) ) unique_outputs.update( [ - (key, output_dict[comp.name][key]['units']) - for key in output_dict[comp.name] + ( + key, + output_dict[engine.name][key]['units'], + ) + for key in output_dict[engine.name] ] ) - # slice incoming inputs for this component, so it only gets the correct index + # slice incoming inputs for this engine, so it only gets the correct index + if num_engine_type > 1: + src_indices = om.slicer[idx] + else: + src_indices = None + self.promotes( - comp.name, inputs=input_dict[comp.name].keys(), src_indices=om.slicer[idx]) + engine.name, + inputs=[*input_dict[engine.name]], + src_indices=src_indices, + ) - # promote all other inputs/outputs for this component normally (handle vectorized outputs later) + # promote all other inputs/outputs for this engine normally (handle vectorized outputs later) self.promotes( - comp.name, + engine.name, inputs=[ - comp_inputs[input]['prom_name'] - for input in comp_inputs - if input not in input_dict[comp.name] + input + for input in eng_inputs + if input not in input_dict[engine.name] ], outputs=[ - comp_outputs[output]['prom_name'] - for output in comp_outputs - if output not in output_dict[comp.name] + output + for output in eng_outputs + if output not in output_dict[engine.name] ], ) @@ -160,11 +180,11 @@ def configure(self): for output in unique_outputs: self.pre_mission_mux.add_var(output, units=unique_outputs[output]) # promote/alias outputs for each comp that has relevant outputs - for i, comp in enumerate(output_dict): - if output in output_dict[comp]: + for i, engine in enumerate(output_dict): + if output in output_dict[engine]: # if this component provides the output, connect it to the correct mux input self.connect( - comp + '.' + output, + engine + '.' + output, 'pre_mission_mux.' + output + '_' + str(i), ) else: @@ -184,29 +204,40 @@ class PropulsionSum(om.ExplicitComponent): def initialize(self): self.options.declare( - 'aviary_options', types=AviaryValues, - desc='collection of Aircraft/Mission specific options') + 'aviary_options', + types=AviaryValues, + desc='collection of Aircraft/Mission specific options', + ) def setup(self): - num_engine_type = len(self.options['aviary_options'].get_val( - Aircraft.Engine.NUM_ENGINES)) + num_engine_type = len( + self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + ) - add_aviary_input(self, Aircraft.Engine.SCALED_SLS_THRUST, - val=np.zeros(num_engine_type)) + add_aviary_input( + self, Aircraft.Engine.SCALED_SLS_THRUST, val=np.zeros(num_engine_type) + ) - add_aviary_output( - self, Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, val=0.0) + 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['aviary_options'].get_val( + Aircraft.Engine.NUM_ENGINES + ) - self.declare_partials(Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, - Aircraft.Engine.SCALED_SLS_THRUST, val=num_engines) + self.declare_partials( + Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, + Aircraft.Engine.SCALED_SLS_THRUST, + val=num_engines, + ) def compute(self, inputs, outputs): - num_engines = self.options['aviary_options'].get_val(Aircraft.Engine.NUM_ENGINES) + num_engines = self.options['aviary_options'].get_val( + Aircraft.Engine.NUM_ENGINES + ) thrust = inputs[Aircraft.Engine.SCALED_SLS_THRUST] outputs[Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST] = np.dot( - thrust, num_engines) + thrust, num_engines + ) diff --git a/aviary/subsystems/propulsion/test/test_custom_engine_model.py b/aviary/subsystems/propulsion/test/test_custom_engine_model.py index 91db9831e..b62bd6922 100644 --- a/aviary/subsystems/propulsion/test/test_custom_engine_model.py +++ b/aviary/subsystems/propulsion/test/test_custom_engine_model.py @@ -40,7 +40,7 @@ def setup(self): nn = self.options['num_nodes'] # add inputs and outputs to interpolator self.add_input( - Dynamic.Mission.MACH, + Dynamic.Atmosphere.MACH, shape=nn, units='unitless', desc='Current flight Mach number', @@ -52,7 +52,7 @@ def setup(self): desc='Current flight altitude', ) self.add_input( - Dynamic.Mission.THROTTLE, + Dynamic.Vehicle.Propulsion.THROTTLE, shape=nn, units='unitless', desc='Current engine throttle', @@ -66,37 +66,37 @@ def setup(self): self.add_input('y', units='m**2', desc='Dummy variable for bus testing') self.add_output( - Dynamic.Mission.THRUST, + Dynamic.Vehicle.Propulsion.THRUST, shape=nn, units='lbf', desc='Current net thrust produced (scaled)', ) self.add_output( - Dynamic.Mission.THRUST_MAX, + Dynamic.Vehicle.Propulsion.THRUST_MAX, shape=nn, units='lbf', desc='Current net thrust produced (scaled)', ) self.add_output( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, shape=nn, units='lbm/s', desc='Current fuel flow rate (scaled)', ) self.add_output( - Dynamic.Mission.ELECTRIC_POWER_IN, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, shape=nn, units='W', desc='Current electric energy rate (scaled)', ) self.add_output( - Dynamic.Mission.NOX_RATE, + Dynamic.Vehicle.Propulsion.NOX_RATE, shape=nn, units='lbm/s', desc='Current NOx emission rate (scaled)', ) self.add_output( - Dynamic.Mission.TEMPERATURE_T4, + Dynamic.Vehicle.Propulsion.TEMPERATURE_T4, shape=nn, units='degR', desc='Current turbine exit temperature', @@ -106,14 +106,15 @@ def setup(self): def compute(self, inputs, outputs): combined_throttle = ( - inputs[Dynamic.Mission.THROTTLE] + inputs['different_throttle'] + inputs[Dynamic.Vehicle.Propulsion.THROTTLE] + inputs['different_throttle'] ) # calculate outputs - outputs[Dynamic.Mission.THRUST] = 10000.0 * combined_throttle - outputs[Dynamic.Mission.THRUST_MAX] = 10000.0 - outputs[Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE] = -10.0 * combined_throttle - outputs[Dynamic.Mission.TEMPERATURE_T4] = 2800.0 + outputs[Dynamic.Vehicle.Propulsion.THRUST] = 10000.0 * combined_throttle + outputs[Dynamic.Vehicle.Propulsion.THRUST_MAX] = 10000.0 + outputs[Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE] = - \ + 10.0 * combined_throttle + outputs[Dynamic.Vehicle.Propulsion.TEMPERATURE_T4] = 2800.0 class SimpleTestEngine(EngineModel): diff --git a/aviary/subsystems/propulsion/test/test_data_interpolator.py b/aviary/subsystems/propulsion/test/test_data_interpolator.py index bf2486d2e..2cef754ed 100644 --- a/aviary/subsystems/propulsion/test/test_data_interpolator.py +++ b/aviary/subsystems/propulsion/test/test_data_interpolator.py @@ -1,4 +1,3 @@ - import csv import unittest @@ -32,12 +31,14 @@ def test_data_interpolation(self): fuel_flow_rate = model.data[keys.FUEL_FLOW] inputs = NamedValues() - inputs.set_val(Dynamic.Mission.MACH, mach_number) + inputs.set_val(Dynamic.Atmosphere.MACH, mach_number) inputs.set_val(Dynamic.Mission.ALTITUDE, altitude, units='ft') - inputs.set_val(Dynamic.Mission.THROTTLE, throttle) + inputs.set_val(Dynamic.Vehicle.Propulsion.THROTTLE, throttle) - outputs = {Dynamic.Mission.THRUST: 'lbf', - Dynamic.Mission.FUEL_FLOW_RATE: 'lbm/h'} + outputs = { + Dynamic.Vehicle.Propulsion.THRUST: 'lbf', + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE: 'lbm/h', + } test_mach_list = np.linspace(0, 0.85, 5) test_alt_list = np.linspace(0, 40_000, 5) @@ -49,21 +50,31 @@ def test_data_interpolation(self): num_nodes = len(test_mach.flatten()) engine_data = om.IndepVarComp() - engine_data.add_output(Dynamic.Mission.MACH + '_train', - val=np.array(mach_number), - units='unitless') - engine_data.add_output(Dynamic.Mission.ALTITUDE + '_train', - val=np.array(altitude), - units='ft') - engine_data.add_output(Dynamic.Mission.THROTTLE + '_train', - val=np.array(throttle), - units='unitless') - engine_data.add_output(Dynamic.Mission.THRUST + '_train', - val=np.array(thrust), - units='lbf') - engine_data.add_output(Dynamic.Mission.FUEL_FLOW_RATE + '_train', - val=np.array(fuel_flow_rate), - units='lbm/h') + engine_data.add_output( + Dynamic.Atmosphere.MACH + '_train', + val=np.array(mach_number), + units='unitless', + ) + engine_data.add_output( + Dynamic.Mission.ALTITUDE + '_train', + val=np.array(altitude), + units='ft', + ) + engine_data.add_output( + Dynamic.Vehicle.Propulsion.THROTTLE + '_train', + val=np.array(throttle), + units='unitless', + ) + engine_data.add_output( + Dynamic.Vehicle.Propulsion.THRUST + '_train', + val=np.array(thrust), + units='lbf', + ) + engine_data.add_output( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE + '_train', + val=np.array(fuel_flow_rate), + units='lbm/h', + ) engine_interpolator = EngineDataInterpolator(num_nodes=num_nodes, interpolator_inputs=inputs, @@ -76,15 +87,20 @@ def test_data_interpolation(self): prob.setup() - prob.set_val(Dynamic.Mission.MACH, np.array(test_mach.flatten()), 'unitless') + prob.set_val(Dynamic.Atmosphere.MACH, np.array(test_mach.flatten()), 'unitless') prob.set_val(Dynamic.Mission.ALTITUDE, np.array(test_alt.flatten()), 'ft') - prob.set_val(Dynamic.Mission.THROTTLE, np.array( - test_throttle.flatten()), 'unitless') + prob.set_val( + Dynamic.Vehicle.Propulsion.THROTTLE, + np.array(test_throttle.flatten()), + 'unitless', + ) prob.run_model() - interp_thrust = prob.get_val(Dynamic.Mission.THRUST, 'lbf') - interp_fuel_flow = prob.get_val(Dynamic.Mission.FUEL_FLOW_RATE, 'lbm/h') + interp_thrust = prob.get_val(Dynamic.Vehicle.Propulsion.THRUST, 'lbf') + interp_fuel_flow = prob.get_val( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE, 'lbm/h' + ) expected_thrust = [0.00000000e+00, 3.54196788e+02, 6.13575369e+03, 1.44653862e+04, 2.65599096e+04, -3.53133516e+02, 5.80901330e+01, 4.31423671e+03, diff --git a/aviary/subsystems/propulsion/test/test_engine_scaling.py b/aviary/subsystems/propulsion/test/test_engine_scaling.py index 75daf047b..cc30345ea 100644 --- a/aviary/subsystems/propulsion/test/test_engine_scaling.py +++ b/aviary/subsystems/propulsion/test/test_engine_scaling.py @@ -70,7 +70,7 @@ def test_case(self): ) self.prob.set_val('nox_rate_unscaled', np.ones([nn, count]) * 10, units='lbm/h') self.prob.set_val( - Dynamic.Mission.MACH, np.linspace(0, 0.75, nn), units='unitless' + Dynamic.Atmosphere.MACH, np.linspace(0, 0.75, nn), units='unitless' ) self.prob.set_val( Aircraft.Engine.SCALE_FACTOR, options.get_val(Aircraft.Engine.SCALE_FACTOR) @@ -78,9 +78,11 @@ def test_case(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Mission.THRUST) - fuel_flow = self.prob.get_val(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE) - nox_rate = self.prob.get_val(Dynamic.Mission.NOX_RATE) + thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST) + fuel_flow = self.prob.get_val( + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE + ) + nox_rate = self.prob.get_val(Dynamic.Vehicle.Propulsion.NOX_RATE) # exit_area = self.prob.get_val(Dynamic.Mission.EXIT_AREA) thrust_expected = np.array([900.0, 900.0, 900.0, 900]) diff --git a/aviary/subsystems/propulsion/test/test_engine_sizing.py b/aviary/subsystems/propulsion/test/test_engine_sizing.py index b273050a9..a5bbd8e30 100644 --- a/aviary/subsystems/propulsion/test/test_engine_sizing.py +++ b/aviary/subsystems/propulsion/test/test_engine_sizing.py @@ -22,7 +22,6 @@ def test_case_multiengine(self): options = AviaryValues() options.set_val(Aircraft.Engine.DATA_FILE, filename) options.set_val(Aircraft.Engine.SCALE_PERFORMANCE, True) - options.set_val(Aircraft.Engine.SCALE_FACTOR, 1.0) options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, True) options.set_val(Aircraft.Engine.IGNORE_NEGATIVE_THRUST, False) options.set_val(Aircraft.Engine.FLIGHT_IDLE_THRUST_FRACTION, 0.0) @@ -40,18 +39,15 @@ def test_case_multiengine(self): self.prob.model.add_subsystem('engine', SizeEngine( aviary_options=options), promotes=['*']) self.prob.setup(force_alloc_complex=True) - self.prob.set_val( - Aircraft.Engine.SCALED_SLS_THRUST, - np.array([15250]), - units='lbf') + self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, np.array([0.52716908])) self.prob.run_model() - scale_factor = self.prob.get_val(Aircraft.Engine.SCALE_FACTOR) + sls_thrust = self.prob.get_val(Aircraft.Engine.SCALED_SLS_THRUST, units='lbf') - expected_scale_factor = np.array([0.52716908]) + expected_sls_thrust = np.array([15250]) - assert_near_equal(scale_factor, expected_scale_factor, tolerance=1e-8) + assert_near_equal(sls_thrust, expected_sls_thrust, tolerance=1e-8) partial_data = self.prob.check_partials(out_stream=None, method="cs") assert_check_partials(partial_data, atol=1e-12, rtol=1e-10) diff --git a/aviary/subsystems/propulsion/test/test_hamilton_standard.py b/aviary/subsystems/propulsion/test/test_hamilton_standard.py index 515ce449b..14a972e25 100644 --- a/aviary/subsystems/propulsion/test/test_hamilton_standard.py +++ b/aviary/subsystems/propulsion/test/test_hamilton_standard.py @@ -35,15 +35,26 @@ def setUp(self): def test_preHS(self): prob = self.prob - prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10, units="ft") - prob.set_val(Dynamic.Mission.PROPELLER_TIP_SPEED, - [700.0, 750.0, 800.0], units="ft/s") - prob.set_val(Dynamic.Mission.SHAFT_POWER, [1850.0, 1850.0, 900.0], units="hp") - prob.set_val(Dynamic.Mission.DENSITY, - [0.00237717, 0.00237717, 0.00106526], units="slug/ft**3") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10, units="ft") + prob.set_val( + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + [700.0, 750.0, 800.0], + units="ft/s", + ) + prob.set_val( + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [1850.0, 1850.0, 900.0], units="hp" + ) + prob.set_val( + Dynamic.Atmosphere.DENSITY, + [0.00237717, 0.00237717, 0.00106526], + units="slug/ft**3", + ) prob.set_val(Dynamic.Mission.VELOCITY, [100.0, 100, 100], units="ft/s") - prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, - [661.46474547, 661.46474547, 601.93668333], units="knot") + prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, + [661.46474547, 661.46474547, 601.93668333], + units="knot", + ) prob.run_model() @@ -79,7 +90,7 @@ class HamiltonStandardTest(unittest.TestCase): def setUp(self): options = get_option_defaults() - options.set_val(Aircraft.Engine.NUM_PROPELLER_BLADES, val=4, units='unitless') + options.set_val(Aircraft.Engine.Propeller.NUM_BLADES, val=4, units='unitless') prob = om.Problem() @@ -99,10 +110,12 @@ def test_HS(self): prob = self.prob prob.set_val("power_coefficient", [0.2352, 0.2352, 0.2553], units="unitless") prob.set_val("advance_ratio", [0.0066, 0.8295, 1.9908], units="unitless") - prob.set_val(Dynamic.Mission.MACH, [0.001509, 0.1887, 0.4976], units="unitless") + prob.set_val( + Dynamic.Atmosphere.MACH, [0.001509, 0.1887, 0.4976], units="unitless" + ) prob.set_val("tip_mach", [1.2094, 1.2094, 1.3290], units="unitless") - prob.set_val(Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 114.0, units="unitless") - prob.set_val(Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + prob.set_val(Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 114.0, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless") prob.run_model() @@ -150,14 +163,14 @@ def test_postHS(self): prob = self.prob prob.set_val("power_coefficient", [0.3871, 0.3147, 0.2815], units="unitless") prob.set_val("advance_ratio", [0.4494, 0.4194, 0.3932], units="unitless") - prob.set_val(Dynamic.Mission.PROPELLER_TIP_SPEED, + prob.set_val(Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, [700.0, 750.0, 800.0], units="ft/s") prob.set_val( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.DENSITY, np.array([1.0001, 1.0001, 0.4482]) * RHO_SEA_LEVEL_ENGLISH, units="slug/ft**3", ) - prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10.0, units="ft") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.0, units="ft") prob.set_val("thrust_coefficient", [0.2765, 0.2052, 0.1158], units="unitless") prob.set_val("install_loss_factor", [0.0133, 0.0200, 0.0325], units="unitless") prob.set_val("comp_tip_loss_factor", [1.0, 1.0, 0.9819], units="unitless") @@ -167,8 +180,11 @@ def test_postHS(self): tol = 5e-4 assert_near_equal(prob.get_val("thrust_coefficient_comp_loss"), [0.2765, 0.2052, 0.1137], tolerance=tol) - assert_near_equal(prob.get_val(Dynamic.Mission.THRUST), - [3218.9508, 2723.7294, 759.7543], tolerance=tol) + assert_near_equal( + prob.get_val(Dynamic.Vehicle.Propulsion.THRUST), + [3218.9508, 2723.7294, 759.7543], + tolerance=tol, + ) assert_near_equal(prob.get_val("propeller_efficiency"), [0.321, 0.2735, 0.1588], tolerance=tol) assert_near_equal(prob.get_val("install_efficiency"), diff --git a/aviary/subsystems/propulsion/test/test_propeller_map.py b/aviary/subsystems/propulsion/test/test_propeller_map.py index f3b2ce3a4..197410766 100644 --- a/aviary/subsystems/propulsion/test/test_propeller_map.py +++ b/aviary/subsystems/propulsion/test/test_propeller_map.py @@ -23,11 +23,11 @@ def test_general_aviation(self): aviary_options = get_option_defaults() prop_file_path = 'models/propellers/general_aviation.prop' aviary_options.set_val( - Aircraft.Engine.PROPELLER_DATA_FILE, val=prop_file_path, units='unitless') + Aircraft.Engine.Propeller.DATA_FILE, val=prop_file_path, units='unitless' + ) aviary_options.set_val( - Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless') - aviary_options.set_val( - Aircraft.Engine.USE_PROPELLER_MAP, val=True, units='unitless') + Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless' + ) prop_model = PropellerMap('prop', aviary_options) prop_model.build_propeller_interpolator(3, aviary_options) @@ -48,11 +48,11 @@ def test_propfan(self): aviary_options = get_option_defaults() prop_file_path = 'models/propellers/PropFan.prop' aviary_options.set_val( - Aircraft.Engine.PROPELLER_DATA_FILE, val=prop_file_path, units='unitless') - aviary_options.set_val( - Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless') + Aircraft.Engine.Propeller.DATA_FILE, val=prop_file_path, units='unitless' + ) aviary_options.set_val( - Aircraft.Engine.USE_PROPELLER_MAP, val=True, units='unitless') + Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless' + ) prop_model = PropellerMap('prop', aviary_options) prop_model.build_propeller_interpolator(3, aviary_options) @@ -72,11 +72,11 @@ def test_mach_type(self): aviary_options = get_option_defaults() prop_file_path = 'models/propellers/general_aviation.prop' aviary_options.set_val( - Aircraft.Engine.PROPELLER_DATA_FILE, val=prop_file_path, units='unitless') - aviary_options.set_val( - Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless') + Aircraft.Engine.Propeller.DATA_FILE, val=prop_file_path, units='unitless' + ) aviary_options.set_val( - Aircraft.Engine.USE_PROPELLER_MAP, val=True, units='unitless') + Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless' + ) prop_model = PropellerMap('prop', aviary_options) out_mach_type = prop_model.read_and_set_mach_type(prop_file_path) self.assertEqual(out_mach_type, OutMachType.HELICAL_MACH) diff --git a/aviary/subsystems/propulsion/test/test_propeller_performance.py b/aviary/subsystems/propulsion/test/test_propeller_performance.py index ecd6d6c3f..394d1edaf 100644 --- a/aviary/subsystems/propulsion/test/test_propeller_performance.py +++ b/aviary/subsystems/propulsion/test/test_propeller_performance.py @@ -173,13 +173,12 @@ class PropellerPerformanceTest(unittest.TestCase): def setUp(self): options = get_option_defaults() options.set_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=True, units='unitless', ) - options.set_val(Aircraft.Engine.NUM_PROPELLER_BLADES, val=4, units='unitless') + options.set_val(Aircraft.Engine.Propeller.NUM_BLADES, val=4, units='unitless') options.set_val(Aircraft.Engine.GENERATE_FLIGHT_IDLE, False) - options.set_val(Aircraft.Engine.USE_PROPELLER_MAP, False) options.set_val(Settings.VERBOSITY, 0) prob = om.Problem() @@ -199,28 +198,30 @@ def setUp(self): promotes_outputs=["*"], ) - pp.set_input_defaults(Aircraft.Engine.PROPELLER_DIAMETER, 10, units="ft") + pp.set_input_defaults(Aircraft.Engine.Propeller.DIAMETER, 10, units="ft") pp.set_input_defaults( - Dynamic.Mission.PROPELLER_TIP_SPEED, 800 * np.ones(num_nodes), units="ft/s" + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, + 800 * np.ones(num_nodes), + units="ft/s", ) pp.set_input_defaults( Dynamic.Mission.VELOCITY, 100.0 * np.ones(num_nodes), units="knot" ) num_blades = 4 options.set_val( - Aircraft.Engine.NUM_PROPELLER_BLADES, val=num_blades, units='unitless' + Aircraft.Engine.Propeller.NUM_BLADES, val=num_blades, units='unitless' ) options.set_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=True, units='unitless', ) prob.setup() - prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10.5, units="ft") - prob.set_val(Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 114.0, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.5, units="ft") + prob.set_val(Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 114.0, units="unitless") prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) prob.set_val(Aircraft.Nacelle.AVG_DIAMETER, 2.8875, units='ft') @@ -232,7 +233,7 @@ def compare_results(self, case_idx_begin, case_idx_end): cthr = p.get_val('thrust_coefficient') ctlf = p.get_val('comp_tip_loss_factor') tccl = p.get_val('thrust_coefficient_comp_loss') - thrt = p.get_val(Dynamic.Mission.THRUST) + thrt = p.get_val(Dynamic.Vehicle.Propulsion.THRUST) peff = p.get_val('propeller_efficiency') lfac = p.get_val('install_loss_factor') ieff = p.get_val('install_efficiency') @@ -255,13 +256,15 @@ def test_case_0_1_2(self): prob.set_val(Dynamic.Mission.ALTITUDE, [0.0, 0.0, 25000.0], units="ft") prob.set_val(Dynamic.Mission.VELOCITY, [0.10, 125.0, 300.0], units="knot") prob.set_val( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.RPM, [1455.13090827, 1455.13090827, 1455.13090827], units='rpm', ) - prob.set_val(Dynamic.Mission.SHAFT_POWER, [1850.0, 1850.0, 900.0], units="hp") - prob.set_val(Aircraft.Engine.PROPELLER_TIP_MACH_MAX, 1.0, units="unitless") - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 800.0, units="ft/s") + prob.set_val( + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [1850.0, 1850.0, 900.0], units="hp" + ) + prob.set_val(Aircraft.Engine.Propeller.TIP_MACH_MAX, 1.0, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 800.0, units="ft/s") prob.run_model() self.compare_results(case_idx_begin=0, case_idx_end=2) @@ -285,26 +288,28 @@ def test_case_3_4_5(self): options = self.options options.set_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=False, units='unitless', ) 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") - prob.set_val(Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 150.0, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") + prob.set_val(Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 150.0, units="unitless") prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) prob.set_val(Dynamic.Mission.ALTITUDE, [10000.0, 10000.0, 0.0], units="ft") prob.set_val(Dynamic.Mission.VELOCITY, [200.0, 200.0, 50.0], units="knot") - prob.set_val(Dynamic.Mission.SHAFT_POWER, [1000.0, 1000.0, 1250.0], units="hp") prob.set_val( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [1000.0, 1000.0, 1250.0], units="hp" + ) + prob.set_val( + Dynamic.Vehicle.Propulsion.RPM, [1225.02, 1225.02, 1225.02], units='rpm', ) - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 769.70, units="ft/s") + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 769.70, units="ft/s") prob.run_model() @@ -330,29 +335,31 @@ def test_case_6_7_8(self): num_blades = 3 options.set_val( - Aircraft.Engine.NUM_PROPELLER_BLADES, val=num_blades, units='unitless' + Aircraft.Engine.Propeller.NUM_BLADES, val=num_blades, units='unitless' ) options.set_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=False, units='unitless', ) 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") - prob.set_val(Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 150.0, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") + prob.set_val(Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 150.0, units="unitless") prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) prob.set_val(Dynamic.Mission.ALTITUDE, [10000.0, 10000.0, 0.0], units="ft") prob.set_val(Dynamic.Mission.VELOCITY, [200.0, 200.0, 50.0], units="knot") - prob.set_val(Dynamic.Mission.SHAFT_POWER, [1000.0, 1000.0, 1250.0], units="hp") prob.set_val( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [1000.0, 1000.0, 1250.0], units="hp" + ) + prob.set_val( + Dynamic.Vehicle.Propulsion.RPM, [1193.66207319, 1193.66207319, 1193.66207319], units='rpm', ) - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 750.0, units="ft/s") + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 750.0, units="ft/s") prob.run_model() self.compare_results(case_idx_begin=6, case_idx_end=8) @@ -373,24 +380,26 @@ def test_case_6_7_8(self): def test_case_9_10_11(self): # Case 9, 10, 11, to test CLI > 0.5 prob = self.prob - prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 12.0, units="ft") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") prob.set_val(Aircraft.Nacelle.AVG_DIAMETER, 2.4, units='ft') - prob.set_val(Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 150.0, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 150.0, units="unitless") prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.65, units="unitless", ) prob.set_val(Dynamic.Mission.ALTITUDE, [10000.0, 10000.0, 10000.0], units="ft") prob.set_val(Dynamic.Mission.VELOCITY, [200.0, 200.0, 200.0], units="knot") - prob.set_val(Dynamic.Mission.SHAFT_POWER, [900.0, 750.0, 500.0], units="hp") prob.set_val( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [900.0, 750.0, 500.0], units="hp" + ) + prob.set_val( + Dynamic.Vehicle.Propulsion.RPM, [1193.66207319, 1193.66207319, 1193.66207319], units='rpm', ) - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 750.0, units="ft/s") + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 750.0, units="ft/s") prob.run_model() self.compare_results(case_idx_begin=9, case_idx_end=11) @@ -407,11 +416,11 @@ def test_case_9_10_11(self): excludes=["*atmosphere*"], ) # remove partial derivative of 'comp_tip_loss_factor' with respect to - # 'aircraft:engine:propeller_integrated_lift_coefficient' from assert_check_partials + # integrated lift coefficient from assert_check_partials partial_data_hs = partial_data['pp.hamilton_standard'] key_pair = ( 'comp_tip_loss_factor', - 'aircraft:engine:propeller_integrated_lift_coefficient', + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, ) del partial_data_hs[key_pair] assert_check_partials(partial_data, atol=1.5e-3, rtol=1e-4) @@ -421,14 +430,16 @@ def test_case_12_13_14(self): prob = self.prob prob.set_val(Dynamic.Mission.ALTITUDE, [0.0, 0.0, 25000.0], units="ft") prob.set_val(Dynamic.Mission.VELOCITY, [0.10, 125.0, 300.0], units="knot") - prob.set_val(Dynamic.Mission.SHAFT_POWER, [1850.0, 1850.0, 900.0], units="hp") prob.set_val( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [1850.0, 1850.0, 900.0], units="hp" + ) + prob.set_val( + Dynamic.Vehicle.Propulsion.RPM, [1455.1309082687574, 1455.1309082687574, 1156.4081529986502], units='rpm', ) - prob.set_val(Aircraft.Engine.PROPELLER_TIP_MACH_MAX, 0.8, units="unitless") - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 800.0, units="ft/s") + prob.set_val(Aircraft.Engine.Propeller.TIP_MACH_MAX, 0.8, units="unitless") + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 800.0, units="ft/s") prob.run_model() self.compare_results(case_idx_begin=12, case_idx_end=13) @@ -451,28 +462,31 @@ def test_case_15_16_17(self): prob = self.prob options = self.options - options.set_val(Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, - val=False, units='unitless') - options.set_val(Aircraft.Engine.USE_PROPELLER_MAP, - val=True, units='unitless') + options.set_val( + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, + val=False, + units='unitless', + ) prop_file_path = 'models/propellers/PropFan.prop' - options.set_val(Aircraft.Engine.PROPELLER_DATA_FILE, + options.set_val(Aircraft.Engine.Propeller.DATA_FILE, val=prop_file_path, units='unitless') options.set_val(Aircraft.Engine.INTERPOLATION_METHOD, val='slinear', units='unitless') 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") + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 12.0, units="ft") prob.set_val(Dynamic.Mission.ALTITUDE, [10000.0, 10000.0, 0.0], units="ft") prob.set_val(Dynamic.Mission.VELOCITY, [200.0, 200.0, 50.0], units="knot") - prob.set_val(Dynamic.Mission.SHAFT_POWER, [1000.0, 1000.0, 1250.0], units="hp") prob.set_val( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, [1000.0, 1000.0, 1250.0], units="hp" + ) + prob.set_val( + Dynamic.Vehicle.Propulsion.RPM, [1225.0155969783186, 1225.0155969783186, 1225.0155969783186], units='rpm', ) - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 769.70, units="ft/s") + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 769.70, units="ft/s") prob.run_model() self.compare_results(case_idx_begin=15, case_idx_end=17) @@ -598,13 +612,19 @@ def test_tipspeed(self): promotes=["*"], ) prob.setup() - prob.set_val(Dynamic.Mission.VELOCITY, - val=[0.16878, 210.97623, 506.34296], units='ft/s') - prob.set_val(Dynamic.Mission.SPEED_OF_SOUND, - val=[1116.42671, 1116.42671, 1015.95467], units='ft/s') - prob.set_val(Aircraft.Engine.PROPELLER_TIP_MACH_MAX, val=[0.8], units='unitless') - prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, val=[800], units='ft/s') - prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, val=[10.5], units='ft') + prob.set_val( + Dynamic.Mission.VELOCITY, + val=[0.16878, 210.97623, 506.34296], + units='ft/s', + ) + prob.set_val( + Dynamic.Atmosphere.SPEED_OF_SOUND, + val=[1116.42671, 1116.42671, 1015.95467], + units='ft/s', + ) + prob.set_val(Aircraft.Engine.Propeller.TIP_MACH_MAX, val=[0.8], units='unitless') + prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, val=[800], units='ft/s') + prob.set_val(Aircraft.Engine.Propeller.DIAMETER, val=[10.5], units='ft') prob.run_model() diff --git a/aviary/subsystems/propulsion/test/test_propulsion_mission.py b/aviary/subsystems/propulsion/test/test_propulsion_mission.py index 6969de420..cbb6d148e 100644 --- a/aviary/subsystems/propulsion/test/test_propulsion_mission.py +++ b/aviary/subsystems/propulsion/test/test_propulsion_mission.py @@ -57,15 +57,15 @@ def test_case_1(self): self.prob.model = PropulsionMission( num_nodes=nn, aviary_options=options, engine_models=[engine]) - IVC = om.IndepVarComp(Dynamic.Mission.MACH, - np.linspace(0, 0.8, nn), - units='unitless') - IVC.add_output(Dynamic.Mission.ALTITUDE, - np.linspace(0, 40000, nn), - units='ft') - IVC.add_output(Dynamic.Mission.THROTTLE, - np.linspace(1, 0.7, nn), - units='unitless') + IVC = om.IndepVarComp( + Dynamic.Atmosphere.MACH, np.linspace(0, 0.8, nn), units='unitless' + ) + IVC.add_output(Dynamic.Mission.ALTITUDE, np.linspace(0, 40000, nn), units='ft') + IVC.add_output( + Dynamic.Vehicle.Propulsion.THROTTLE, + np.linspace(1, 0.7, nn), + units='unitless', + ) self.prob.model.add_subsystem('IVC', IVC, promotes=['*']) self.prob.setup(force_alloc_complex=True) @@ -74,9 +74,9 @@ def test_case_1(self): self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Mission.THRUST_TOTAL, units='lbf') + thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') fuel_flow = self.prob.get_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h') + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h') expected_thrust = np.array( [ @@ -146,26 +146,34 @@ def test_propulsion_sum(self): self.prob.setup(force_alloc_complex=True) - self.prob.set_val(Dynamic.Mission.THRUST, np.array( - [[500.4, 423.001], [325, 6780]])) - self.prob.set_val(Dynamic.Mission.THRUST_MAX, - np.array([[602.11, 3554], [100, 9000]])) - self.prob.set_val(Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, + self.prob.set_val( + Dynamic.Vehicle.Propulsion.THRUST, np.array([[500.4, 423.001], [325, 6780]]) + ) + self.prob.set_val( + Dynamic.Vehicle.Propulsion.THRUST_MAX, + np.array([[602.11, 3554], [100, 9000]]), + ) + self.prob.set_val(Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, np.array([[123, -221.44], [-765.2, -1]])) - self.prob.set_val(Dynamic.Mission.ELECTRIC_POWER_IN, + self.prob.set_val(Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, np.array([[3.01, -12], [484.2, 8123]])) - self.prob.set_val(Dynamic.Mission.NOX_RATE, - np.array([[322, 4610], [1.54, 2.844]])) + self.prob.set_val( + Dynamic.Vehicle.Propulsion.NOX_RATE, np.array([[322, 4610], [1.54, 2.844]]) + ) self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Mission.THRUST_TOTAL, units='lbf') - thrust_max = self.prob.get_val(Dynamic.Mission.THRUST_MAX_TOTAL, units='lbf') + thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') + thrust_max = self.prob.get_val( + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, units='lbf' + ) fuel_flow = self.prob.get_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lb/h') + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lb/h' + ) electric_power_in = self.prob.get_val( - Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, units='kW') - nox = self.prob.get_val(Dynamic.Mission.NOX_RATE_TOTAL, units='lb/h') + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, units='kW' + ) + nox = self.prob.get_val(Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, units='lb/h') expected_thrust = np.array([2347.202, 14535]) expected_thrust_max = np.array([8914.33, 18300]) @@ -199,32 +207,44 @@ def test_case_multiengine(self): self.prob.model = PropulsionMission( num_nodes=20, aviary_options=options, engine_models=engine_models) - self.prob.model.add_subsystem(Dynamic.Mission.MACH, - om.IndepVarComp(Dynamic.Mission.MACH, - np.linspace(0, 0.85, nn), - units='unitless'), - promotes=['*']) + self.prob.model.add_subsystem( + Dynamic.Atmosphere.MACH, + om.IndepVarComp( + Dynamic.Atmosphere.MACH, np.linspace(0, 0.85, nn), units='unitless' + ), + promotes=['*'], + ) self.prob.model.add_subsystem( Dynamic.Mission.ALTITUDE, om.IndepVarComp( - Dynamic.Mission.ALTITUDE, - np.linspace(0, 40000, nn), - units='ft'), - promotes=['*']) + Dynamic.Mission.ALTITUDE, np.linspace(0, 40000, nn), units='ft' + ), + promotes=['*'], + ) throttle = np.linspace(1.0, 0.6, nn) self.prob.model.add_subsystem( - Dynamic.Mission.THROTTLE, om.IndepVarComp(Dynamic.Mission.THROTTLE, np.vstack((throttle, throttle)).transpose(), units='unitless'), promotes=['*']) + Dynamic.Vehicle.Propulsion.THROTTLE, + om.IndepVarComp( + Dynamic.Vehicle.Propulsion.THROTTLE, + np.vstack((throttle, throttle)).transpose(), + units='unitless', + ), + promotes=['*'], + ) self.prob.setup(force_alloc_complex=True) self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, [0.975, 0.975], units='unitless') self.prob.run_model() - thrust = self.prob.get_val(Dynamic.Mission.THRUST_TOTAL, units='lbf') + thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST_TOTAL, units='lbf') fuel_flow = self.prob.get_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h') - nox_rate = self.prob.get_val(Dynamic.Mission.NOX_RATE_TOTAL, units='lbm/h') + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, units='lbm/h' + ) + nox_rate = self.prob.get_val( + Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, units='lbm/h' + ) expected_thrust = np.array( [ diff --git a/aviary/subsystems/propulsion/test/test_propulsion_premission.py b/aviary/subsystems/propulsion/test/test_propulsion_premission.py index a56a17d3a..cbfabff65 100644 --- a/aviary/subsystems/propulsion/test/test_propulsion_premission.py +++ b/aviary/subsystems/propulsion/test/test_propulsion_premission.py @@ -23,12 +23,15 @@ def test_case(self): options.set_val(Settings.VERBOSITY, 0) options.set_val(Aircraft.Engine.NUM_ENGINES, np.array([2])) - self.prob.model = PropulsionPreMission(aviary_options=options, - engine_models=build_engine_deck(options)) + self.prob.model = PropulsionPreMission( + aviary_options=options, engine_models=build_engine_deck(options) + ) + + self.prob.model.set_input_defaults(Aircraft.Engine.SCALE_FACTOR, np.ones(1)) 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')) + # self.prob.set_val(Aircraft.Engine.SCALED_SLS_THRUST, options.get_val( + # Aircraft.Engine.SCALED_SLS_THRUST, units='lbf')) self.prob.run_model() @@ -54,6 +57,10 @@ def test_multi_engine(self): self.prob.model = PropulsionPreMission(aviary_options=options, engine_models=engine_models) + self.prob.model.set_input_defaults( + Aircraft.Engine.SCALE_FACTOR, np.ones(2) * 0.5 + ) + 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')) diff --git a/aviary/subsystems/propulsion/test/test_turboprop_model.py b/aviary/subsystems/propulsion/test/test_turboprop_model.py index 01ddcbdcd..2ade19493 100644 --- a/aviary/subsystems/propulsion/test/test_turboprop_model.py +++ b/aviary/subsystems/propulsion/test/test_turboprop_model.py @@ -22,7 +22,7 @@ @use_tempdirs -class TurbopropTest(unittest.TestCase): +class TurbopropMissionTest(unittest.TestCase): def setUp(self): self.prob = om.Problem() @@ -60,11 +60,11 @@ def prepare_model( ) options.set_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=True, units='unitless', ) - options.set_val(Aircraft.Engine.NUM_PROPELLER_BLADES, val=4, units='unitless') + options.set_val(Aircraft.Engine.Propeller.NUM_BLADES, val=4, units='unitless') num_nodes = len(test_points) @@ -74,9 +74,12 @@ def prepare_model( preprocess_propulsion(options, [engine]) machs, alts, throttles = zip(*test_points) - IVC = om.IndepVarComp(Dynamic.Mission.MACH, np.array(machs), units='unitless') + IVC = om.IndepVarComp( + Dynamic.Atmosphere.MACH, np.array(machs), units='unitless' + ) IVC.add_output(Dynamic.Mission.ALTITUDE, np.array(alts), units='ft') - IVC.add_output(Dynamic.Mission.THROTTLE, np.array(throttles), units='unitless') + IVC.add_output(Dynamic.Vehicle.Propulsion.THROTTLE, + np.array(throttles), units='unitless') self.prob.model.add_subsystem('IVC', IVC, promotes=['*']) # calculate atmospheric properties @@ -99,15 +102,16 @@ def prepare_model( self.prob.set_val(Aircraft.Engine.SCALE_FACTOR, 1, units='unitless') def get_results(self, point_names=None, display_results=False): - shp = self.prob.get_val(Dynamic.Mission.SHAFT_POWER, units='hp') - total_thrust = self.prob.get_val(Dynamic.Mission.THRUST, units='lbf') + shp = self.prob.get_val(Dynamic.Vehicle.Propulsion.SHAFT_POWER, units='hp') + total_thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST, units='lbf') prop_thrust = self.prob.get_val('turboprop_model.propeller_thrust', units='lbf') tailpipe_thrust = self.prob.get_val( 'turboprop_model.turboshaft_thrust', units='lbf' ) - max_thrust = self.prob.get_val(Dynamic.Mission.THRUST_MAX, units='lbf') + max_thrust = self.prob.get_val( + Dynamic.Vehicle.Propulsion.THRUST_MAX, units='lbf') fuel_flow = self.prob.get_val( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, units='lbm/h' + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, units='lbm/h' ) results = [] @@ -132,55 +136,55 @@ def test_case_1(self): # shp, tailpipe thrust, prop_thrust, total_thrust, max_thrust, fuel flow truth_vals = [ ( - 223.99923788786057, + 111.99923788786062, 37.699999999999996, - 1195.4410222483584, - 1233.1410222483585, - 4983.816420783667, + 610.3580810058977, + 648.0580810058977, + 4184.157517016291, -195.79999999999995, ), ( - 2239.9923788786077, + 1119.992378878607, 136.29999999999967, - 4847.516420783668, - 4983.816420783667, - 4983.816420783667, + 4047.857517016292, + 4184.157517016291, + 4184.157517016291, -643.9999999999998, ), ( - 2466.55094358958, + 778.2106659424866, 21.30000000000001, - 1834.6578916888234, - 1855.9578916888233, - 1855.9578916888233, - -839.7000000000685, + 558.2951237599805, + 579.5951237599804, + 579.5951237599804, + -839.7000000000685 ), ] options = get_option_defaults() options.set_val( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, val=True, units='unitless', ) - options.set_val(Aircraft.Engine.NUM_PROPELLER_BLADES, val=4, units='unitless') + options.set_val(Aircraft.Engine.Propeller.NUM_BLADES, val=4, units='unitless') options.set_val('speed_type', SpeedType.MACH) prop_group = ExamplePropModel('custom_prop_model') self.prepare_model(test_points, filename, prop_group) - self.prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10.5, units="ft") + self.prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.5, units="ft") self.prob.set_val( - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 114.0, units="unitless" + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 114.0, units="unitless" ) # self.prob.set_val(Dynamic.Mission.PERCENT_ROTOR_RPM_CORRECTED, # np.array([1, 1, 0.7]), units="unitless") self.prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) - self.prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 800, units="ft/s") + self.prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 800, units="ft/s") self.prob.run_model() results = self.get_results() @@ -188,7 +192,8 @@ def test_case_1(self): assert_near_equal(results[1], truth_vals[1], tolerance=1.5e-12) assert_near_equal(results[2], truth_vals[2], tolerance=1.5e-12) - # because Hamilton Standard model uses fd method, the following may not be accurate. + # because Hamilton Standard model uses fd method, the following may not be + # accurate. partial_data = self.prob.check_partials(out_stream=None, form="central") assert_check_partials(partial_data, atol=0.2, rtol=0.2) @@ -198,44 +203,44 @@ def test_case_2(self): test_points = [(0.001, 0, 0), (0, 0, 1), (0.6, 25000, 1)] truth_vals = [ ( - 223.99007751511726, - 37.507374999999996, - 1186.7060713100836, - 1224.2134463100836, - 4984.168016782585, - -195.78762499999996, + 111.99470252, + 37.507375, + 610.74316702, + 648.25054202, + 4174.71017, + -195.787625, ), ( - 2239.9923788786077, + 1119.992378878607, 136.29999999999967, - 4847.516420783668, - 4983.816420783667, - 4983.816420783667, + 4047.857517016292, + 4184.157517016291, + 4184.157517016291, -643.9999999999998, ), ( - 2466.55094358958, + 778.2106659424866, 21.30000000000001, - 1834.6578916888234, - 1855.9578916888233, - 1855.9578916888233, - -839.7000000000685, + 558.2951237599805, + 579.5951237599804, + 579.5951237599804, + -839.7000000000685 ), ] self.prepare_model(test_points, filename) - self.prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10.5, units="ft") + self.prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.5, units="ft") self.prob.set_val( - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 114.0, units="unitless" + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 114.0, units="unitless" ) # self.prob.set_val(Dynamic.Mission.PERCENT_ROTOR_RPM_CORRECTED, # np.array([1,1,0.7]), units="unitless") self.prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) - self.prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 800, units="ft/s") + self.prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 800, units="ft/s") self.prob.run_model() @@ -248,46 +253,47 @@ def test_case_2(self): assert_check_partials(partial_data, atol=0.15, rtol=0.15) def test_case_3(self): - # test case using GASP-derived engine deck w/o tailpipe thrust and default HS prop model. + # test case using GASP-derived engine deck w/o tailpipe thrust and default + # HS prop model. filename = get_path('models/engines/turboshaft_1120hp_no_tailpipe.deck') test_points = [(0, 0, 0), (0, 0, 1), (0.6, 25000, 1)] truth_vals = [ ( - 223.99923788786057, + 111.99923788786062, 0.0, - 1195.4410222483584, - 1195.4410222483584, - 4847.516420783668, + 610.3580810058977, + 610.3580810058977, + 4047.857517016292, -195.79999999999995, ), ( - 2239.9923788786077, + 1119.992378878607, 0.0, - 4847.516420783668, - 4847.516420783668, - 4847.516420783668, + 4047.857517016292, + 4047.857517016292, + 4047.857517016292, -643.9999999999998, ), ( - 2466.55094358958, + 778.2106659424866, 0.0, - 1834.6578916888234, - 1834.6578916888234, - 1834.6578916888234, - -839.7000000000685, - ), + 558.2951237599805, + 558.2951237599805, + 558.2951237599805, + -839.7000000000685 + ) ] self.prepare_model(test_points, filename) - self.prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10.5, units="ft") + self.prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.5, units="ft") self.prob.set_val( - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 114.0, units="unitless" + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 114.0, units="unitless" ) self.prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) - self.prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 800, units="ft/s") + self.prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 800, units="ft/s") self.prob.run_model() @@ -296,8 +302,11 @@ def test_case_3(self): assert_near_equal(results[1], truth_vals[1], tolerance=1.5e-12) assert_near_equal(results[2], truth_vals[2], tolerance=1.5e-12) - partial_data = self.prob.check_partials(out_stream=None, form="central") - assert_check_partials(partial_data, atol=0.15, rtol=0.15) + # Note: There isn't much point in checking the partials of a component + # that computes them with FD. + partial_data = self.prob.check_partials(out_stream=None, form="forward", + step=1.01e-6) + assert_check_partials(partial_data, atol=1e10, rtol=1e-3) def test_electroprop(self): # test case using electric motor and default HS prop model. @@ -307,33 +316,34 @@ def test_electroprop(self): motor_model = MotorBuilder() self.prepare_model(test_points, motor_model, input_rpm=True) - self.prob.set_val(Dynamic.Mission.RPM, np.ones(num_nodes) * 2000.0, units='rpm') + self.prob.set_val(Dynamic.Vehicle.Propulsion.RPM, + np.ones(num_nodes) * 2000.0, units='rpm') - self.prob.set_val(Aircraft.Engine.PROPELLER_DIAMETER, 10.5, units="ft") + self.prob.set_val(Aircraft.Engine.Propeller.DIAMETER, 10.5, units="ft") self.prob.set_val( - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, 114.0, units="unitless" + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, 114.0, units="unitless" ) self.prob.set_val( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, 0.5, units="unitless" ) - self.prob.set_val(Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, 800, units="ft/s") + self.prob.set_val(Aircraft.Engine.Propeller.TIP_SPEED_MAX, 800, units="ft/s") self.prob.run_model() - shp_expected = [0.0, 505.55333, 505.55333] + shp_expected = [0.0, 367.82313837, 367.82313837] prop_thrust_expected = total_thrust_expected = [ - 610.35808276, - 2627.2632965, - 312.64111293, + 610.3580827654595, + 2083.253331913252, + 184.38117745374652 ] - electric_power_expected = [0.0, 408.4409047, 408.4409047] + electric_power_expected = [0.0, 303.31014553, 303.31014553] - shp = self.prob.get_val(Dynamic.Mission.SHAFT_POWER, units='hp') - total_thrust = self.prob.get_val(Dynamic.Mission.THRUST, units='lbf') + shp = self.prob.get_val(Dynamic.Vehicle.Propulsion.SHAFT_POWER, units='hp') + total_thrust = self.prob.get_val(Dynamic.Vehicle.Propulsion.THRUST, units='lbf') prop_thrust = self.prob.get_val('turboprop_model.propeller_thrust', units='lbf') electric_power = self.prob.get_val( - Dynamic.Mission.ELECTRIC_POWER_IN, units='kW' + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, units='kW' ) assert_near_equal(shp, shp_expected, tolerance=1e-8) @@ -341,10 +351,11 @@ def test_electroprop(self): assert_near_equal(prop_thrust, prop_thrust_expected, tolerance=1e-8) assert_near_equal(electric_power, electric_power_expected, tolerance=1e-8) - partial_data = self.prob.check_partials( - out_stream=None, method="fd", form="central" - ) - assert_check_partials(partial_data, atol=0.17, rtol=0.15) + # Note: There isn't much point in checking the partials of a component + # that computes them with FD. + partial_data = self.prob.check_partials(out_stream=None, form="forward", + step=1.01e-6) + assert_check_partials(partial_data, atol=1e10, rtol=1e-3) class ExamplePropModel(SubsystemBuilderBase): @@ -355,25 +366,25 @@ def build_mission(self, num_nodes, aviary_inputs, **kwargs): 'propeller_performance', PropellerPerformance(aviary_options=aviary_inputs, num_nodes=num_nodes), promotes_inputs=[ - Dynamic.Mission.MACH, - Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, - Aircraft.Engine.PROPELLER_TIP_MACH_MAX, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.MACH, + Aircraft.Engine.Propeller.TIP_SPEED_MAX, + Aircraft.Engine.Propeller.TIP_MACH_MAX, + Dynamic.Atmosphere.DENSITY, Dynamic.Mission.VELOCITY, - Aircraft.Engine.PROPELLER_DIAMETER, - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + Aircraft.Engine.Propeller.DIAMETER, + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, Aircraft.Nacelle.AVG_DIAMETER, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.RPM, - Dynamic.Mission.SHAFT_POWER, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Vehicle.Propulsion.RPM, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, ], promotes_outputs=['*'], ) - pp.set_input_defaults(Aircraft.Engine.PROPELLER_DIAMETER, 10, units="ft") + pp.set_input_defaults(Aircraft.Engine.Propeller.DIAMETER, 10, units="ft") pp.set_input_defaults( - Dynamic.Mission.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, 800.0 * np.ones(num_nodes), units="ft/s", ) diff --git a/aviary/subsystems/propulsion/throttle_allocation.py b/aviary/subsystems/propulsion/throttle_allocation.py index fd0543fe2..57719cf52 100644 --- a/aviary/subsystems/propulsion/throttle_allocation.py +++ b/aviary/subsystems/propulsion/throttle_allocation.py @@ -56,10 +56,10 @@ def setup(self): ) self.add_output( - Dynamic.Mission.THROTTLE, + Dynamic.Vehicle.Propulsion.THROTTLE, np.ones((nn, num_engine_type)), units="unitless", - desc="Throttle setting for all engines." + desc="Throttle setting for all engines.", ) if alloc_mode == ThrottleAllocation.DYNAMIC: @@ -75,8 +75,12 @@ def setup(self): cols = np.repeat(np.arange(nn), num_engine_type) rows = np.arange(nn * num_engine_type) - self.declare_partials(of=[Dynamic.Mission.THROTTLE], wrt=["aggregate_throttle"], - rows=rows, cols=cols) + self.declare_partials( + of=[Dynamic.Vehicle.Propulsion.THROTTLE], + wrt=["aggregate_throttle"], + rows=rows, + cols=cols, + ) if alloc_mode == ThrottleAllocation.DYNAMIC: a = num_engine_type @@ -87,16 +91,21 @@ def setup(self): cols = np.tile(col, num_engine_type) all_rows = np.tile(rows, nn) + a * np.repeat(np.arange(nn), a * b) all_cols = np.tile(cols, nn) + b * np.repeat(np.arange(nn), a * b) - self.declare_partials(of=[Dynamic.Mission.THROTTLE], wrt=["throttle_allocations"], - rows=all_rows, cols=all_cols) + self.declare_partials( + of=[Dynamic.Vehicle.Propulsion.THROTTLE], + wrt=["throttle_allocations"], + rows=all_rows, + cols=all_cols, + ) rows = np.repeat(np.arange(nn), b) cols = np.arange(nn * b) self.declare_partials(of=["throttle_allocation_sum"], wrt=["throttle_allocations"], rows=rows, cols=cols, val=1.0) else: - self.declare_partials(of=[Dynamic.Mission.THROTTLE], - wrt=["throttle_allocations"]) + self.declare_partials( + of=[Dynamic.Vehicle.Propulsion.THROTTLE], wrt=["throttle_allocations"] + ) self.declare_partials(of=["throttle_allocation_sum"], wrt=["throttle_allocations"], val=1.0) @@ -108,15 +117,19 @@ def compute(self, inputs, outputs, discrete_inputs=None, discrete_outputs=None): allocation = inputs["throttle_allocations"] if alloc_mode == ThrottleAllocation.DYNAMIC: - outputs[Dynamic.Mission.THROTTLE][:, :- - 1] = np.einsum("i,ij->ij", agg_throttle, allocation) + outputs[Dynamic.Vehicle.Propulsion.THROTTLE][:, :-1] = np.einsum( + "i,ij->ij", agg_throttle, allocation + ) sum_alloc = np.sum(allocation, axis=1) else: - outputs[Dynamic.Mission.THROTTLE][:, :- - 1] = np.einsum("i,j->ij", agg_throttle, allocation) + outputs[Dynamic.Vehicle.Propulsion.THROTTLE][:, :-1] = np.einsum( + "i,j->ij", agg_throttle, allocation + ) sum_alloc = np.sum(allocation) - outputs[Dynamic.Mission.THROTTLE][:, -1] = agg_throttle * (1.0 - sum_alloc) + outputs[Dynamic.Vehicle.Propulsion.THROTTLE][:, -1] = agg_throttle * ( + 1.0 - sum_alloc + ) outputs["throttle_allocation_sum"] = sum_alloc @@ -132,7 +145,9 @@ def compute_partials(self, inputs, partials, discrete_inputs=None): if alloc_mode == ThrottleAllocation.DYNAMIC: sum_alloc = np.sum(allocation, axis=1) allocs = np.vstack((allocation.T, 1.0 - sum_alloc)) - partials[Dynamic.Mission.THROTTLE, "aggregate_throttle"] = allocs.T.ravel() + partials[Dynamic.Vehicle.Propulsion.THROTTLE, "aggregate_throttle"] = ( + allocs.T.ravel() + ) ne = num_engine_type - 1 mask1 = np.eye(ne) @@ -140,13 +155,16 @@ def compute_partials(self, inputs, partials, discrete_inputs=None): mask = np.vstack((mask1, mask2)).ravel() deriv = np.outer(agg_throttle, mask).reshape((nn * (ne + 1), ne)) - partials[Dynamic.Mission.THROTTLE, "throttle_allocations"] = deriv.ravel() + partials[Dynamic.Vehicle.Propulsion.THROTTLE, "throttle_allocations"] = ( + deriv.ravel() + ) else: sum_alloc = np.sum(allocation) allocs = np.hstack((allocation, 1.0 - sum_alloc)) - partials[Dynamic.Mission.THROTTLE, - "aggregate_throttle"] = np.tile(allocs, nn) + partials[Dynamic.Vehicle.Propulsion.THROTTLE, "aggregate_throttle"] = ( + np.tile(allocs, nn) + ) ne = num_engine_type - 1 mask1 = np.eye(ne) @@ -154,10 +172,12 @@ def compute_partials(self, inputs, partials, discrete_inputs=None): mask = np.vstack((mask1, mask2)).ravel() deriv = np.outer(agg_throttle, mask).reshape((nn * (ne + 1), ne)) - partials[Dynamic.Mission.THROTTLE, "throttle_allocations"] = deriv + partials[Dynamic.Vehicle.Propulsion.THROTTLE, "throttle_allocations"] = ( + deriv + ) # sum_alloc = np.sum(allocation) - # outputs[Dynamic.Mission.THROTTLE][:, -1] = agg_throttle * (1.0 - sum_alloc) + # outputs[Dynamic.Vehicle.Propulsion.THROTTLE][:, -1] = agg_throttle * (1.0 - sum_alloc) # outputs["throttle_allocation_sum"] = sum_alloc diff --git a/aviary/subsystems/propulsion/turboprop_model.py b/aviary/subsystems/propulsion/turboprop_model.py index 354830a40..fd0446bdf 100644 --- a/aviary/subsystems/propulsion/turboprop_model.py +++ b/aviary/subsystems/propulsion/turboprop_model.py @@ -11,7 +11,7 @@ from aviary.utils.aviary_values import AviaryValues from aviary.variable_info.variables import Aircraft, Dynamic, Settings from aviary.variable_info.enums import Verbosity -from aviary.subsystems.propulsion.propeller.propeller_performance import PropellerPerformance +from aviary.subsystems.propulsion.propeller.propeller_builder import PropellerBuilder from aviary.subsystems.propulsion.gearbox.gearbox_builder import GearboxBuilder @@ -81,7 +81,7 @@ def __init__( # TODO No reason gearbox model needs to be required. All connections can # be handled in configure - need to figure out when user wants gearbox without - # directly passing builder + # having to directly pass builder if gearbox_model is None: # TODO where can we bring in include_constraints? kwargs in init is an option, # but that still requires the L2 interface @@ -89,7 +89,11 @@ def __init__( name=name + '_gearbox', include_constraints=True ) - # BUG if using both custom subsystems that happen to share a kwarg but need different values, this breaks + if propeller_model is None: + self.propeller_model = PropellerBuilder(name=name + '_propeller') + + # BUG if using both custom subsystems that happen to share a kwarg but + # need different values, this breaks def build_pre_mission(self, aviary_inputs, **kwargs) -> om.Group: shp_model = self.shaft_power_model propeller_model = self.propeller_model @@ -98,8 +102,8 @@ def build_pre_mission(self, aviary_inputs, **kwargs) -> om.Group: # TODO engine scaling for turboshafts requires EngineSizing to be refactored to # accept target scaling variable as an option, skipping for now - if type(shp_model) is not EngineDeck: - shp_model_pre_mission = shp_model.build_pre_mission(aviary_inputs, **kwargs) + if not isinstance(shp_model, EngineDeck): + shp_model_pre_mission = shp_model.build_pre_mission(self.options, **kwargs) if shp_model_pre_mission is not None: turboprop_group.add_subsystem( shp_model_pre_mission.name, @@ -108,7 +112,7 @@ def build_pre_mission(self, aviary_inputs, **kwargs) -> om.Group: ) gearbox_model_pre_mission = gearbox_model.build_pre_mission( - aviary_inputs, **kwargs + self.options, **kwargs ) if gearbox_model_pre_mission is not None: turboprop_group.add_subsystem( @@ -117,16 +121,15 @@ def build_pre_mission(self, aviary_inputs, **kwargs) -> om.Group: promotes=['*'], ) - if propeller_model is not None: - propeller_model_pre_mission = propeller_model.build_pre_mission( - aviary_inputs, **kwargs + propeller_model_pre_mission = propeller_model.build_pre_mission( + self.options, **kwargs + ) + if propeller_model_pre_mission is not None: + turboprop_group.add_subsystem( + propeller_model_pre_mission.name, + subsys=propeller_model_pre_mission, + promotes=['*'], ) - if propeller_model_pre_mission is not None: - turboprop_group.add_subsystem( - propeller_model_pre_mission.name, - subsys=propeller_model_pre_mission, - promotes=['*'] - ) return turboprop_group @@ -136,7 +139,7 @@ def build_mission(self, num_nodes, aviary_inputs, **kwargs): shaft_power_model=self.shaft_power_model, propeller_model=self.propeller_model, gearbox_model=self.gearbox_model, - aviary_inputs=aviary_inputs, + aviary_inputs=self.options, kwargs=kwargs, ) @@ -166,19 +169,38 @@ def build_post_mission(self, aviary_inputs, **kwargs): aviary_options=aviary_inputs, ) - if propeller_model is not None: - propeller_model_post_mission = propeller_model.build_post_mission( - aviary_inputs, **kwargs + propeller_model_post_mission = propeller_model.build_post_mission( + aviary_inputs, **kwargs + ) + if propeller_model_post_mission is not None: + turboprop_group.add_subsystem( + propeller_model.name, + subsys=propeller_model_post_mission, + aviary_options=aviary_inputs, ) - if propeller_model_post_mission is not None: - turboprop_group.add_subsystem( - propeller_model.name, - subsys=propeller_model_post_mission, - aviary_options=aviary_inputs, - ) return turboprop_group + def get_parameters(self): + params = super().get_parameters() # calls from EngineModel + if self.shaft_power_model is not None: + params.update(self.shaft_power_model.get_parameters()) + if self.gearbox_model is not None: + params.update(self.gearbox_model.get_parameters()) + if self.propeller_model is not None: + params.update(self.propeller_model.get_parameters()) + return params + + def get_design_vars(self): + desvars = super().get_design_vars() # calls from EngineModel + if self.shaft_power_model is not None: + desvars.update(self.shaft_power_model.get_design_vars()) + if self.gearbox_model is not None: + desvars.update(self.gearbox_model.get_design_vars()) + if self.propeller_model is not None: + desvars.update(self.propeller_model.get_design_vars()) + return desvars + class TurbopropMission(om.Group): def initialize(self): @@ -206,6 +228,10 @@ def setup(self): # save aviary_inputs for use in configure() self.aviary_inputs = aviary_inputs = self.options['aviary_inputs'] + # NOTE: this subsystem is a empty component that has fixed RPM added as an output + # in configure() if provided in aviary_inputs + self.add_subsystem('fixed_rpm_source', subsys=om.IndepVarComp()) + # Shaft Power Model try: shp_kwargs = kwargs[shp_model.name] @@ -216,10 +242,6 @@ def setup(self): if shp_model_mission is not None: self.add_subsystem(shp_model.name, subsys=shp_model_mission) - # NOTE: this subsystem is a empty component that has fixed RPM added as an output - # in configure() if provided in aviary_inputs - self.add_subsystem('fixed_rpm_source', subsys=om.IndepVarComp()) - # Gearbox Model try: gearbox_kwargs = kwargs[gearbox_model.name] @@ -237,85 +259,85 @@ def setup(self): propeller_kwargs = kwargs[propeller_model.name] except (AttributeError, KeyError): propeller_kwargs = {} - if propeller_model is not None: - propeller_group = om.Group() - propeller_model_mission = propeller_model.build_mission( - num_nodes, aviary_inputs, **propeller_kwargs - ) - if propeller_model_mission is not None: - propeller_group.add_subsystem( - propeller_model.name + '_base', - subsys=propeller_model_mission, - promotes_inputs=['*'], - promotes_outputs=[Dynamic.Mission.THRUST], - ) - - propeller_model_mission_max = propeller_model.build_mission( - num_nodes, aviary_inputs, **propeller_kwargs - ) - propeller_group.add_subsystem( - propeller_model.name + '_max', - subsys=propeller_model_mission_max, - promotes_inputs=[ - '*', - (Dynamic.Mission.SHAFT_POWER, Dynamic.Mission.SHAFT_POWER_MAX), - ], - promotes_outputs=[ - (Dynamic.Mission.THRUST, Dynamic.Mission.THRUST_MAX) - ], - ) - self.add_subsystem(propeller_model.name, propeller_group) + propeller_group = om.Group() + propeller_model_mission = propeller_model.build_mission( + num_nodes, aviary_inputs, **propeller_kwargs + ) - else: + if isinstance(propeller_model, PropellerBuilder): # use the Hamilton Standard model # only promote top-level inputs to avoid conflicts with max group prop_inputs = [ - Dynamic.Mission.MACH, - Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, - Aircraft.Engine.PROPELLER_TIP_MACH_MAX, - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.MACH, + Aircraft.Engine.Propeller.TIP_SPEED_MAX, + Aircraft.Engine.Propeller.TIP_MACH_MAX, + Dynamic.Atmosphere.DENSITY, Dynamic.Mission.VELOCITY, - Aircraft.Engine.PROPELLER_DIAMETER, - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + Aircraft.Engine.Propeller.DIAMETER, + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, Aircraft.Nacelle.AVG_DIAMETER, - Dynamic.Mission.SPEED_OF_SOUND, - Dynamic.Mission.RPM, + Dynamic.Atmosphere.SPEED_OF_SOUND, + Dynamic.Vehicle.Propulsion.RPM, ] try: propeller_kwargs = kwargs['hamilton_standard'] except KeyError: propeller_kwargs = {} - propeller_group = om.Group() - propeller_group.add_subsystem( 'propeller_model_base', - PropellerPerformance( - aviary_options=aviary_inputs, - num_nodes=num_nodes, - **propeller_kwargs, - ), + propeller_model_mission, promotes=['*'], ) + propeller_model_mission_max = propeller_model.build_mission( + num_nodes, aviary_inputs, **propeller_kwargs + ) propeller_group.add_subsystem( 'propeller_model_max', - PropellerPerformance( - aviary_options=aviary_inputs, - num_nodes=num_nodes, - **propeller_kwargs, - ), + propeller_model_mission_max, promotes_inputs=[ *prop_inputs, - (Dynamic.Mission.SHAFT_POWER, Dynamic.Mission.SHAFT_POWER_MAX), + (Dynamic.Vehicle.Propulsion.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX), ], - promotes_outputs=[(Dynamic.Mission.THRUST, Dynamic.Mission.THRUST_MAX)], + promotes_outputs=[ + (Dynamic.Vehicle.Propulsion.THRUST, + Dynamic.Vehicle.Propulsion.THRUST_MAX)], ) self.add_subsystem('propeller_model', propeller_group) + else: + if propeller_model_mission is not None: + propeller_group.add_subsystem( + propeller_model.name + '_base', + subsys=propeller_model_mission, + promotes_inputs=['*'], + promotes_outputs=[Dynamic.Vehicle.Propulsion.THRUST], + ) + + propeller_model_mission_max = propeller_model.build_mission( + num_nodes, aviary_inputs, **propeller_kwargs + ) + propeller_group.add_subsystem( + propeller_model.name + '_max', + subsys=propeller_model_mission_max, + promotes_inputs=[ + '*', + (Dynamic.Vehicle.Propulsion.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX), + ], + promotes_outputs=[ + (Dynamic.Vehicle.Propulsion.THRUST, + Dynamic.Vehicle.Propulsion.THRUST_MAX) + ], + ) + + self.add_subsystem(propeller_model.name, propeller_group) + thrust_adder = om.ExecComp( 'turboprop_thrust=turboshaft_thrust+propeller_thrust', turboprop_thrust={'val': np.zeros(num_nodes), 'units': 'lbf'}, @@ -336,14 +358,16 @@ def setup(self): 'thrust_adder', subsys=thrust_adder, promotes_inputs=['*'], - promotes_outputs=[('turboprop_thrust', Dynamic.Mission.THRUST)], + promotes_outputs=[('turboprop_thrust', Dynamic.Vehicle.Propulsion.THRUST)], ) self.add_subsystem( 'max_thrust_adder', subsys=max_thrust_adder, promotes_inputs=['*'], - promotes_outputs=[('turboprop_thrust_max', Dynamic.Mission.THRUST_MAX)], + promotes_outputs=[ + ('turboprop_thrust_max', + Dynamic.Vehicle.Propulsion.THRUST_MAX)], ) def configure(self): @@ -366,14 +390,14 @@ def configure(self): # of this system, also having it as an input causes feedback loop problem at # the propulsion level skipped_inputs = [ - Dynamic.Mission.ELECTRIC_POWER_IN, - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, - Dynamic.Mission.NOX_RATE, - Dynamic.Mission.SHAFT_POWER, - Dynamic.Mission.SHAFT_POWER_MAX, - Dynamic.Mission.TEMPERATURE_T4, - Dynamic.Mission.THRUST, - Dynamic.Mission.THRUST_MAX, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, + Dynamic.Vehicle.Propulsion.NOX_RATE, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, + Dynamic.Vehicle.Propulsion.TEMPERATURE_T4, + Dynamic.Vehicle.Propulsion.THRUST, + Dynamic.Vehicle.Propulsion.THRUST_MAX, ] # Build lists of inputs/outputs for each component as needed: @@ -383,6 +407,16 @@ def configure(self): # given component, which is done at the end as a bulk promote. shp_model = self._get_subsystem(self.options['shaft_power_model'].name) + shp_input_dict = shp_model.list_inputs( + return_format='dict', units=True, out_stream=None, all_procs=True + ) + shp_input_list = list( + set( + shp_input_dict[key]['prom_name'] + for key in shp_input_dict + if '.' not in shp_input_dict[key]['prom_name'] + ) + ) shp_output_dict = shp_model.list_outputs( return_format='dict', units=True, out_stream=None, all_procs=True ) @@ -427,7 +461,7 @@ def configure(self): ) gearbox_outputs = [] - if self.options['propeller_model'] is None: + if isinstance(self.options['propeller_model'], PropellerBuilder): propeller_model_name = 'propeller_model' else: propeller_model_name = self.options['propeller_model'].name @@ -446,8 +480,8 @@ def configure(self): # always promote all propeller model outputs w/o aliasing except thrust propeller_outputs = [ '*', - (Dynamic.Mission.THRUST, 'propeller_thrust'), - (Dynamic.Mission.THRUST_MAX, 'propeller_thrust_max'), + (Dynamic.Vehicle.Propulsion.THRUST, 'propeller_thrust'), + (Dynamic.Vehicle.Propulsion.THRUST_MAX, 'propeller_thrust_max'), ] ######################### @@ -455,13 +489,15 @@ def configure(self): ######################### # Everything not explicitly handled here gets promoted later on # Thrust outputs are directly promoted with alias (this is a special case) - if Dynamic.Mission.THRUST in shp_output_list: - shp_outputs.append((Dynamic.Mission.THRUST, 'turboshaft_thrust')) - shp_output_list.remove(Dynamic.Mission.THRUST) + if Dynamic.Vehicle.Propulsion.THRUST in shp_output_list: + shp_outputs.append((Dynamic.Vehicle.Propulsion.THRUST, 'turboshaft_thrust')) + shp_output_list.remove(Dynamic.Vehicle.Propulsion.THRUST) - if Dynamic.Mission.THRUST_MAX in shp_output_list: - shp_outputs.append((Dynamic.Mission.THRUST_MAX, 'turboshaft_thrust_max')) - shp_output_list.remove(Dynamic.Mission.THRUST_MAX) + if Dynamic.Vehicle.Propulsion.THRUST_MAX in shp_output_list: + shp_outputs.append( + (Dynamic.Vehicle.Propulsion.THRUST_MAX, + 'turboshaft_thrust_max')) + shp_output_list.remove(Dynamic.Vehicle.Propulsion.THRUST_MAX) # Gearbox connections if has_gearbox: @@ -469,8 +505,9 @@ def configure(self): # Check for case: var is output from shp_model, connects to gearbox, then # gets updated by gearbox # RPM has special handling, so skip it here - if var + '_in' in gearbox_input_list and var != Dynamic.Mission.RPM: - # if var is in gearbox input and output, connect on shp -> gearbox side + if var + '_in' in gearbox_input_list and var != Dynamic.Vehicle.Propulsion.RPM: + # if var is in gearbox input and output, connect on shp -> gearbox + # side if ( var in gearbox_output_list or var + '_out' in gearbox_output_list @@ -490,7 +527,7 @@ def configure(self): Aircraft.Engine.FIXED_RPM, units='rpm' ) - if Dynamic.Mission.RPM in shp_output_list: + if Dynamic.Vehicle.Propulsion.RPM in shp_output_list: if self.aviary_inputs.get_val(Settings.VERBOSITY) >= Verbosity.BRIEF: warnings.warn( 'Overriding RPM value outputted by EngineModel' @@ -498,31 +535,42 @@ def configure(self): ) shp_outputs.append( - (Dynamic.Mission.RPM, 'AUTO_OVERRIDE:' + Dynamic.Mission.RPM) - ) - shp_output_list.remove(Dynamic.Mission.RPM) + (Dynamic.Vehicle.Propulsion.RPM, + 'AUTO_OVERRIDE:' + + Dynamic.Vehicle.Propulsion.RPM)) + shp_output_list.remove(Dynamic.Vehicle.Propulsion.RPM) fixed_rpm_nn = np.ones(self.num_nodes) * fixed_rpm - rpm_ivc.add_output(Dynamic.Mission.RPM, fixed_rpm_nn, units='rpm') + rpm_ivc.add_output(Dynamic.Vehicle.Propulsion.RPM, fixed_rpm_nn, units='rpm') if has_gearbox: - self.promotes('fixed_rpm_source', [(Dynamic.Mission.RPM, 'fixed_rpm')]) - gearbox_inputs.append((Dynamic.Mission.RPM + '_in', 'fixed_rpm')) - gearbox_input_list.remove(Dynamic.Mission.RPM + '_in') + self.promotes( + 'fixed_rpm_source', [ + (Dynamic.Vehicle.Propulsion.RPM, 'fixed_rpm')]) + gearbox_inputs.append( + (Dynamic.Vehicle.Propulsion.RPM + '_in', 'fixed_rpm')) + gearbox_input_list.remove(Dynamic.Vehicle.Propulsion.RPM + '_in') else: self.promotes('fixed_rpm_source', ['*']) + # models such as motor take RPM as input + if Dynamic.Vehicle.Propulsion.RPM in shp_input_list: + shp_inputs.append((Dynamic.Vehicle.Propulsion.RPM, 'fixed_rpm')) else: - rpm_ivc.add_output('AUTO_OVERRIDE:' + Dynamic.Mission.RPM, 1.0, units='rpm') + rpm_ivc.add_output( + 'AUTO_OVERRIDE:' + + Dynamic.Vehicle.Propulsion.RPM, + 1.0, + units='rpm') if has_gearbox: - if Dynamic.Mission.RPM in shp_output_list: + if Dynamic.Vehicle.Propulsion.RPM in shp_output_list: shp_outputs.append( - (Dynamic.Mission.RPM, Dynamic.Mission.RPM + '_gearbox') - ) - shp_output_list.remove(Dynamic.Mission.RPM) + (Dynamic.Vehicle.Propulsion.RPM, + Dynamic.Vehicle.Propulsion.RPM + '_gearbox')) + shp_output_list.remove(Dynamic.Vehicle.Propulsion.RPM) gearbox_inputs.append( - (Dynamic.Mission.RPM + '_in', Dynamic.Mission.RPM + '_gearbox') - ) - gearbox_input_list.remove(Dynamic.Mission.RPM + '_in') + (Dynamic.Vehicle.Propulsion.RPM + '_in', + Dynamic.Vehicle.Propulsion.RPM + '_gearbox')) + gearbox_input_list.remove(Dynamic.Vehicle.Propulsion.RPM + '_in') # All other shp model outputs that don't interact with gearbox will be promoted for var in shp_output_list: @@ -581,7 +629,8 @@ def configure(self): ############## # PROMOTIONS # ############## - # bulk promote desired inputs and outputs for each subsystem we have been tracking + # bulk promote desired inputs and outputs for each subsystem we have been + # tracking self.promotes(shp_model.name, inputs=shp_inputs, outputs=shp_outputs) if has_gearbox: diff --git a/aviary/subsystems/propulsion/utils.py b/aviary/subsystems/propulsion/utils.py index 83c3e5f98..5ca421a40 100644 --- a/aviary/subsystems/propulsion/utils.py +++ b/aviary/subsystems/propulsion/utils.py @@ -17,6 +17,7 @@ from aviary.utils.named_values import NamedValues, get_keys, get_items from aviary.variable_info.variables import Aircraft, Dynamic, Mission from aviary.variable_info.variable_meta_data import _MetaData +from aviary.variable_info.enums import GASPEngineType class EngineModelVariables(Enum): @@ -24,21 +25,21 @@ class EngineModelVariables(Enum): Define constants that map to supported variable names in an engine model. """ - MACH = Dynamic.Mission.MACH + MACH = Dynamic.Atmosphere.MACH ALTITUDE = Dynamic.Mission.ALTITUDE - THROTTLE = Dynamic.Mission.THROTTLE - HYBRID_THROTTLE = Dynamic.Mission.HYBRID_THROTTLE - THRUST = Dynamic.Mission.THRUST + THROTTLE = Dynamic.Vehicle.Propulsion.THROTTLE + HYBRID_THROTTLE = Dynamic.Vehicle.Propulsion.HYBRID_THROTTLE + THRUST = Dynamic.Vehicle.Propulsion.THRUST TAILPIPE_THRUST = 'tailpipe_thrust' GROSS_THRUST = 'gross_thrust' - SHAFT_POWER = Dynamic.Mission.SHAFT_POWER + SHAFT_POWER = Dynamic.Vehicle.Propulsion.SHAFT_POWER SHAFT_POWER_CORRECTED = 'shaft_power_corrected' RAM_DRAG = 'ram_drag' - FUEL_FLOW = Dynamic.Mission.FUEL_FLOW_RATE - ELECTRIC_POWER_IN = Dynamic.Mission.ELECTRIC_POWER_IN - NOX_RATE = Dynamic.Mission.NOX_RATE - TEMPERATURE_T4 = Dynamic.Mission.TEMPERATURE_T4 - TORQUE = Dynamic.Mission.TORQUE + FUEL_FLOW = Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE + ELECTRIC_POWER_IN = Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN + NOX_RATE = Dynamic.Vehicle.Propulsion.NOX_RATE + TEMPERATURE_T4 = Dynamic.Vehicle.Propulsion.TEMPERATURE_T4 + TORQUE = Dynamic.Vehicle.Propulsion.TORQUE # EXIT_AREA = auto() @@ -63,8 +64,8 @@ class EngineModelVariables(Enum): # variables that have an accompanying max value max_variables = { - EngineModelVariables.THRUST: Dynamic.Mission.THRUST_MAX, - EngineModelVariables.SHAFT_POWER: Dynamic.Mission.SHAFT_POWER_MAX, + EngineModelVariables.THRUST: Dynamic.Vehicle.Propulsion.THRUST_MAX, + EngineModelVariables.SHAFT_POWER: Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, } @@ -173,7 +174,7 @@ def build_engine_deck(aviary_options: AviaryValues, meta_data=_MetaData): if val_dim > expected_dim + 1: UserWarning( f'Provided vector for {var} has too many dimensions: ' - 'expecting a {expected_dim+1}D array ({expected_dim}D ' + f'expecting a {expected_dim+1}D array ({expected_dim}D ' 'per engine)' ) # if neither metadata nor aviary_val are numpy arrays, cannot check dimensions @@ -202,6 +203,7 @@ def build_engine_deck(aviary_options: AviaryValues, meta_data=_MetaData): except (KeyError, TypeError): continue + # name engine deck after filename # local import to avoid circular import from aviary.subsystems.propulsion.engine_deck import EngineDeck @@ -376,8 +378,8 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('P0', Dynamic.Mission.STATIC_PRESSURE), - ('mach', Dynamic.Mission.MACH), + ('P0', Dynamic.Atmosphere.STATIC_PRESSURE), + ('mach', Dynamic.Atmosphere.MACH), ], promotes_outputs=['delta_T'], ) @@ -396,8 +398,8 @@ def setup(self): has_diag_partials=True, ), promotes_inputs=[ - ('T0', Dynamic.Mission.TEMPERATURE), - ('mach', Dynamic.Mission.MACH), + ('T0', Dynamic.Atmosphere.TEMPERATURE), + ('mach', Dynamic.Atmosphere.MACH), ], promotes_outputs=['theta_T'], ) @@ -405,7 +407,7 @@ def setup(self): self.add_subsystem( 'uncorrection', om.ExecComp( - 'uncorrected_data = corrected_data * (delta_T + theta_T**.5)', + 'uncorrected_data = corrected_data * (delta_T * theta_T**.5)', uncorrected_data={'units': "hp", 'shape': num_nodes}, delta_T={'units': "unitless", 'shape': num_nodes}, theta_T={'units': "unitless", 'shape': num_nodes}, diff --git a/aviary/utils/engine_deck_conversion.py b/aviary/utils/engine_deck_conversion.py index b6476f733..80d296103 100644 --- a/aviary/utils/engine_deck_conversion.py +++ b/aviary/utils/engine_deck_conversion.py @@ -214,34 +214,32 @@ def EngineDeckConverter(input_file, output_file, data_format: EngineDeckType): promotes=['*']) prob.model.add_subsystem( - Dynamic.Mission.MACH, - om.IndepVarComp( - Dynamic.Mission.MACH, - data[MACH], - units='unitless'), - promotes=['*']) + Dynamic.Atmosphere.MACH, + om.IndepVarComp(Dynamic.Atmosphere.MACH, data[MACH], units='unitless'), + promotes=['*'], + ) prob.model.add_subsystem( Dynamic.Mission.ALTITUDE, - om.IndepVarComp( - Dynamic.Mission.ALTITUDE, - data[ALTITUDE], - units='ft'), - promotes=['*']) + om.IndepVarComp(Dynamic.Mission.ALTITUDE, data[ALTITUDE], units='ft'), + promotes=['*'], + ) prob.model.add_subsystem( name='atmosphere', subsys=Atmosphere(num_nodes=len(data[MACH])), promotes_inputs=[Dynamic.Mission.ALTITUDE], - promotes_outputs=[Dynamic.Mission.TEMPERATURE], + promotes_outputs=[Dynamic.Atmosphere.TEMPERATURE], ) prob.model.add_subsystem( name='conversion', subsys=AtmosCalc(num_nodes=len(data[MACH])), - promotes_inputs=[Dynamic.Mission.MACH, - Dynamic.Mission.TEMPERATURE], - promotes_outputs=['t2'] + promotes_inputs=[ + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.TEMPERATURE, + ], + promotes_outputs=['t2'], ) prob.setup() @@ -254,16 +252,20 @@ def EngineDeckConverter(input_file, output_file, data_format: EngineDeckType): # By always keeping minimum T4 zero for normalization, throttle stays # consistent with fraction of T4max # TODO flight condition dependent throttle range? - # NOTE this often leaves max throttles less than 1 in the deck - this caues + # NOTE this often leaves max throttles less than 1 in the deck - this causes # problems when finding reference SLS thrust, as there is often no max # power data at that point in the engine deck. It is recommended GASP # engine decks override Aircraft.Engine.REFERENCE_THRUST in EngineDecks data[THROTTLE] = normalize(data[TEMPERATURE], minimum=0.0, maximum=t4max) else: + # data[THROTTLE] = normalize( + # T4T2, minimum=scalars['t4flight_idle'], maximum=t4max + # ) data[THROTTLE] = normalize(T4T2, minimum=0.0, maximum=t4max) # TODO save these points as commented out? + # remove points above T4max valid_idx = np.where(data[THROTTLE] <= 1.0) data[MACH] = data[MACH][valid_idx] data[ALTITUDE] = data[ALTITUDE][valid_idx] @@ -540,39 +542,37 @@ def _generate_flight_idle(data, T4T2, ref_sls_airflow, ref_sfn_idle): prob = om.Problem() prob.model.add_subsystem( - Dynamic.Mission.MACH, - om.IndepVarComp( - Dynamic.Mission.MACH, - mach_list, - units='unitless'), - promotes=['*']) + Dynamic.Atmosphere.MACH, + om.IndepVarComp(Dynamic.Atmosphere.MACH, mach_list, units='unitless'), + promotes=['*'], + ) prob.model.add_subsystem( Dynamic.Mission.ALTITUDE, - om.IndepVarComp( - Dynamic.Mission.ALTITUDE, - alt_list, - units='ft'), - promotes=['*']) + om.IndepVarComp(Dynamic.Mission.ALTITUDE, alt_list, units='ft'), + promotes=['*'], + ) prob.model.add_subsystem( name='atmosphere', subsys=Atmosphere(num_nodes=nn), promotes_inputs=[Dynamic.Mission.ALTITUDE], - promotes_outputs=[Dynamic.Mission.TEMPERATURE, Dynamic.Mission.STATIC_PRESSURE], + promotes_outputs=[ + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + ], ) prob.model.add_subsystem( name='conversion', - subsys=AtmosCalc( - num_nodes=nn), + subsys=AtmosCalc(num_nodes=nn), promotes_inputs=[ - Dynamic.Mission.MACH, - Dynamic.Mission.TEMPERATURE, - Dynamic.Mission.STATIC_PRESSURE], - promotes_outputs=[ - 't2', - 'p2']) + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.TEMPERATURE, + Dynamic.Atmosphere.STATIC_PRESSURE, + ], + promotes_outputs=['t2', 'p2'], + ) prob.model.add_subsystem( name='flight_idle', @@ -685,12 +685,16 @@ def initialize(self): def setup(self): nn = self.options['num_nodes'] - self.add_input(Dynamic.Mission.MACH, val=np.zeros(nn), - desc='current Mach number', units='unitless') - self.add_input(Dynamic.Mission.TEMPERATURE, val=np.zeros(nn), + self.add_input( + Dynamic.Atmosphere.MACH, + val=np.zeros(nn), + desc='current Mach number', + units='unitless', + ) + self.add_input(Dynamic.Atmosphere.TEMPERATURE, val=np.zeros(nn), desc='current atmospheric temperature', units='degR') self.add_input( - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Atmosphere.STATIC_PRESSURE, _PSLS_PSF, units="psf", shape=nn, diff --git a/aviary/utils/fortran_to_aviary.py b/aviary/utils/fortran_to_aviary.py index d09222793..b783f7224 100644 --- a/aviary/utils/fortran_to_aviary.py +++ b/aviary/utils/fortran_to_aviary.py @@ -30,14 +30,23 @@ from aviary.variable_info.variables import Aircraft, Mission, Settings from aviary.variable_info.enums import LegacyCode, Verbosity, ProblemType from aviary.utils.functions import get_path -from aviary.utils.legacy_code_data.deprecated_vars import flops_deprecated_vars, gasp_deprecated_vars +from aviary.utils.legacy_code_data.deprecated_vars import ( + flops_deprecated_vars, + gasp_deprecated_vars, +) FLOPS = LegacyCode.FLOPS GASP = LegacyCode.GASP -def create_aviary_deck(fortran_deck: str, legacy_code=None, defaults_deck=None, - out_file=None, force=False, verbosity=Verbosity.BRIEF): +def create_aviary_deck( + fortran_deck: str, + legacy_code=None, + defaults_deck=None, + out_file=None, + force=False, + verbosity=Verbosity.BRIEF, +): ''' Create an Aviary CSV file from a Fortran input deck Required input is the filepath to the input deck and legacy code. Optionally, a @@ -51,8 +60,12 @@ def create_aviary_deck(fortran_deck: str, legacy_code=None, defaults_deck=None, # TODO generate both an Aviary input file and a phase_info file - vehicle_data = {'input_values': NamedValues(), 'unused_values': NamedValues(), - 'initialization_guesses': initialization_guesses, 'verbosity': verbosity} + vehicle_data = { + 'input_values': NamedValues(), + 'unused_values': NamedValues(), + 'initialization_guesses': initialization_guesses, + 'verbosity': verbosity, + } fortran_deck: Path = get_path(fortran_deck, verbose=False) @@ -80,32 +93,47 @@ def create_aviary_deck(fortran_deck: str, legacy_code=None, defaults_deck=None, deprecated_vars = flops_deprecated_vars if not defaults_deck: - defaults_filename = legacy_code.value.lower() + '_default_values' + default_extension - defaults_deck = Path(__file__).parent.resolve().joinpath( - 'legacy_code_data', defaults_filename) + defaults_filename = ( + legacy_code.value.lower() + '_default_values' + default_extension + ) + defaults_deck = ( + Path(__file__) + .parent.resolve() + .joinpath('legacy_code_data', defaults_filename) + ) # create dictionary to convert legacy code variables to Aviary variables # key: variable name, value: either None or relevant historical_name aviary_variable_dict = generate_aviary_names([legacy_code.value]) if defaults_deck: # If defaults are specified, initialize the vehicle with them - vehicle_data = input_parser(defaults_deck, vehicle_data, - aviary_variable_dict, deprecated_vars, legacy_code) - - vehicle_data = input_parser(fortran_deck, vehicle_data, - aviary_variable_dict, deprecated_vars, legacy_code) + vehicle_data = input_parser( + defaults_deck, + vehicle_data, + aviary_variable_dict, + deprecated_vars, + legacy_code, + ) + + vehicle_data = input_parser( + fortran_deck, vehicle_data, aviary_variable_dict, deprecated_vars, legacy_code + ) if legacy_code is GASP: vehicle_data = update_gasp_options(vehicle_data) elif legacy_code is FLOPS: vehicle_data = update_flops_options(vehicle_data) + vehicle_data = update_aviary_options(vehicle_data) - if not out_file.is_file(): # default outputted file to be in same directory as input + if ( + not out_file.is_file() + ): # default outputted file to be in same directory as input out_file = fortran_deck.parent / out_file if out_file.is_file(): if not force: - raise RuntimeError(f'{out_file} already exists. Choose a new name or enable ' - '--force') + raise RuntimeError( + f'{out_file} already exists. Choose a new name or enable ' '--force' + ) elif verbosity >= Verbosity.BRIEF: print(f'Overwriting existing file: {out_file.name}') @@ -191,12 +219,22 @@ def input_parser(fortran_deck, vehicle_data, alternate_names, unused_vars, legac data = line.split('=')[1] try: vehicle_data = process_and_store_data( - data, var_name, legacy_code, current_namelist, alternate_names, vehicle_data, unused_vars, comment) + data, + var_name, + legacy_code, + current_namelist, + alternate_names, + vehicle_data, + unused_vars, + comment, + ) except Exception as err: if current_namelist == '': - raise RuntimeError(line + ' could not be parsed successfully.' - '\nIf this was intended as a comment, ' - 'add an "!" at the beginning of the line.') from err + raise RuntimeError( + line + ' could not be parsed successfully.' + '\nIf this was intended as a comment, ' + 'add an "!" at the beginning of the line.' + ) from err else: raise err elif number_of_variables > 1: @@ -205,24 +243,36 @@ def input_parser(fortran_deck, vehicle_data, alternate_names, unused_vars, legac for ii in range(number_of_variables): # Each of the following elements contains all of the data for the current variable # and the last element is the name of the next variable - sub_list = sub_line[ii+1].split(',') - if ii+1 < number_of_variables: + sub_list = sub_line[ii + 1].split(',') + if ii + 1 < number_of_variables: next_var_name = sub_list.pop() if not next_var_name[0].isalpha(): - index = next((i for i, c in enumerate( - next_var_name) if c.isalpha()), len(next_var_name)) + index = next( + (i for i, c in enumerate(next_var_name) if c.isalpha()), + len(next_var_name), + ) sub_list.append(next_var_name[:index]) next_var_name = next_var_name[index:] data = ','.join(sub_list) try: vehicle_data = process_and_store_data( - data, var_name, legacy_code, current_namelist, alternate_names, vehicle_data, unused_vars, comment) + data, + var_name, + legacy_code, + current_namelist, + alternate_names, + vehicle_data, + unused_vars, + comment, + ) except Exception as err: if current_namelist == '': - raise RuntimeError(line + ' could not be parsed successfully.' - '\nIf this was intended as a comment, ' - 'add an "!" at the beginning of the line.') from err + raise RuntimeError( + line + ' could not be parsed successfully.' + '\nIf this was intended as a comment, ' + 'add an "!" at the beginning of the line.' + ) from err else: raise err var_name = next_var_name @@ -233,7 +283,16 @@ def input_parser(fortran_deck, vehicle_data, alternate_names, unused_vars, legac return vehicle_data -def process_and_store_data(data, var_name, legacy_code, current_namelist, alternate_names, vehicle_data, unused_vars, comment=''): +def process_and_store_data( + data, + var_name, + legacy_code, + current_namelist, + alternate_names, + vehicle_data, + unused_vars, + comment='', +): ''' process_and_store_data takes in a string that contains the data, the current variable's name and namelist, the dictionary of alternate names, and the current vehicle data. @@ -252,7 +311,8 @@ def process_and_store_data(data, var_name, legacy_code, current_namelist, altern data_list = [dat for dat in data.split(',') if dat != ''] if len(data_list) > 0: if valid_units(data_list[-1]): - # if the last element is a unit, remove it from the list and update the variable's units + # if the last element is a unit, remove it from the list and update the + # variable's units data_units = data_list.pop() var_values = convert_strings_to_data(data_list) else: @@ -260,7 +320,8 @@ def process_and_store_data(data, var_name, legacy_code, current_namelist, altern var_values = [] list_of_equivalent_aviary_names, var_ind = update_name( - alternate_names, current_namelist+var_name, vehicle_data['verbosity']) + alternate_names, current_namelist + var_name, vehicle_data['verbosity'] + ) # Fortran uses 1 indexing, Python uses 0 indexing fortran_offset = 1 if current_namelist else 0 @@ -268,10 +329,15 @@ def process_and_store_data(data, var_name, legacy_code, current_namelist, altern var_ind -= fortran_offset # Aviary has a reduction gearbox which is 1/gear ratio of GASP gearbox - if current_namelist+var_name == 'INPROP.GR': - var_values = [1/var for var in var_values] - vehicle_data['input_values'] = set_value(Aircraft.Engine.Gearbox.GEAR_RATIO, var_values, - vehicle_data['input_values'], var_id=var_ind, units=data_units) + if current_namelist + var_name == 'INPROP.GR': + var_values = [1 / var for var in var_values] + vehicle_data['input_values'] = set_value( + Aircraft.Engine.Gearbox.GEAR_RATIO, + var_values, + vehicle_data['input_values'], + var_ind=var_ind, + units=data_units, + ) for name in list_of_equivalent_aviary_names: if not skip_variable: @@ -281,12 +347,22 @@ def process_and_store_data(data, var_name, legacy_code, current_namelist, altern continue elif name in _MetaData: - vehicle_data['input_values'] = set_value(name, var_values, vehicle_data['input_values'], - var_ind=var_ind, units=data_units) + vehicle_data['input_values'] = set_value( + name, + var_values, + vehicle_data['input_values'], + var_ind=var_ind, + units=data_units, + ) continue - vehicle_data['unused_values'] = set_value(name, var_values, vehicle_data['unused_values'], - var_ind=var_ind, units=data_units) + vehicle_data['unused_values'] = set_value( + name, + var_values, + vehicle_data['unused_values'], + var_ind=var_ind, + units=data_units, + ) if vehicle_data['verbosity'].value >= Verbosity.VERBOSE: print('Unused:', name, var_values, comment) @@ -294,7 +370,7 @@ def process_and_store_data(data, var_name, legacy_code, current_namelist, altern def set_value(var_name, var_value, value_dict: NamedValues, var_ind=None, units=None): - ''' + ''' set_value will update the current value of a variable in a value dictionary that contains a value and it's associated units. If units are specified for the new value, they will be used, otherwise the current units in the @@ -313,19 +389,20 @@ def set_value(var_name, var_value, value_dict: NamedValues, var_ind=None, units= if not units: units = 'unitless' - if var_ind != None: + if var_ind is not None: # if an index is specified, use it, otherwise store the input as the whole value if isinstance(current_value, list): max_ind = len(current_value) - 1 if var_ind > max_ind: - current_value.extend((var_ind-max_ind)*[0]) + current_value.extend((var_ind - max_ind) * [0]) else: - current_value = [current_value]+[0]*var_ind + current_value = [current_value] + [0] * var_ind current_value[var_ind] = var_value[0] value_dict.set_val(var_name, current_value, units) else: - if current_value != None and isinstance(current_value[0], bool): - # if a variable is defined as boolean but is read in as number, set as boolean + if current_value is not None and isinstance(current_value[0], bool): + # if a variable is defined as boolean but is read in as number, set as + # boolean if var_value[0] == 1: var_value = ['True'] elif var_value[0] == 0: @@ -400,11 +477,19 @@ def update_gasp_options(vehicle_data): for var_name in gasp_scaler_variables: update_gasp_scaler_variables(var_name, input_values) - flap_types = ["plain", "split", "single_slotted", "double_slotted", - "triple_slotted", "fowler", "double_slotted_fowler"] + flap_types = [ + "plain", + "split", + "single_slotted", + "double_slotted", + "triple_slotted", + "fowler", + "double_slotted_fowler", + ] ## PROBLEM TYPE ## - # if multiple values of target_range are specified, use the one that corresponds to the problem_type + # if multiple values of target_range are specified, use the one that + # corresponds to the problem_type design_range, distance_units = input_values.get_item(Mission.Design.RANGE) try: problem_type = input_values.get_val(Settings.PROBLEM_TYPE)[0] @@ -447,58 +532,80 @@ def update_gasp_options(vehicle_data): strut_loc = abs(strut_loc) if strut_loc < 1: - input_values.set_val(Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, - [strut_loc], 'unitless') - input_values.set_val(Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, [ - False], 'unitless') + input_values.set_val( + Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, [strut_loc], 'unitless' + ) + input_values.set_val( + Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, [False], 'unitless' + ) else: input_values.set_val(Aircraft.Strut.ATTACHMENT_LOCATION, [strut_loc], 'ft') input_values.set_val( - Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, [True], 'unitless') + Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, [True], 'unitless' + ) if input_values.get_val(Aircraft.Wing.HAS_FOLD)[0]: if not input_values.get_val(Aircraft.Wing.CHOOSE_FOLD_LOCATION)[0]: - input_values.set_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, - [True], 'unitless') + input_values.set_val( + Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, [True], 'unitless' + ) else: if input_values.get_val(Aircraft.Wing.FOLDED_SPAN, 'ft')[0] > 1: - input_values.set_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, - [True], 'unitless') + input_values.set_val( + Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, + [True], + 'unitless', + ) else: - input_values.set_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, - [False], 'unitless') + input_values.set_val( + Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, + [False], + 'unitless', + ) else: input_values.set_val(Aircraft.Wing.CHOOSE_FOLD_LOCATION, [True], 'unitless') - input_values.set_val(Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, [ - False], 'unitless') + input_values.set_val( + Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, [False], 'unitless' + ) ## FLAPS ## flap_type = input_values.get_val(Aircraft.Wing.FLAP_TYPE)[0] if not isinstance(flap_type, str): - flap_type = flap_types[flap_type-1] + flap_type = flap_types[flap_type - 1] input_values.set_val(Aircraft.Wing.FLAP_TYPE, [flap_type]) flap_ind = flap_types.index(flap_type) if input_values.get_val(Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT)[0] <= 0: - input_values.set_val(Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT, - [[0.62, 1.0, 0.733, 1.2, 1.32, 0.633, 0.678][flap_ind]]) + input_values.set_val( + Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT, + [[0.62, 1.0, 0.733, 1.2, 1.32, 0.633, 0.678][flap_ind]], + ) if input_values.get_val(Aircraft.Wing.OPTIMUM_FLAP_DEFLECTION, 'deg')[0] == 0: - input_values.set_val(Aircraft.Wing.OPTIMUM_FLAP_DEFLECTION, - [[60, 60, 40, 55, 55, 30, 30][flap_ind]], 'deg') + input_values.set_val( + Aircraft.Wing.OPTIMUM_FLAP_DEFLECTION, + [[60, 60, 40, 55, 55, 30, 30][flap_ind]], + 'deg', + ) if input_values.get_val(Aircraft.Wing.FLAP_LIFT_INCREMENT_OPTIMUM)[0] == 0: - input_values.set_val(Aircraft.Wing.FLAP_LIFT_INCREMENT_OPTIMUM, - [[.9, .8, 1.18, 1.4, 1.6, 1.67, 2.25][flap_ind]]) + input_values.set_val( + Aircraft.Wing.FLAP_LIFT_INCREMENT_OPTIMUM, + [[0.9, 0.8, 1.18, 1.4, 1.6, 1.67, 2.25][flap_ind]], + ) if input_values.get_val(Aircraft.Wing.FLAP_DRAG_INCREMENT_OPTIMUM)[0] == 0: - input_values.set_val(Aircraft.Wing.FLAP_DRAG_INCREMENT_OPTIMUM, - [[.12, .23, .13, .23, .23, .1, .15][flap_ind]]) + input_values.set_val( + Aircraft.Wing.FLAP_DRAG_INCREMENT_OPTIMUM, + [[0.12, 0.23, 0.13, 0.23, 0.23, 0.1, 0.15][flap_ind]], + ) res = input_values.get_val(Aircraft.Design.RESERVE_FUEL_ADDITIONAL, units='lbm')[0] if res <= 0: input_values.set_val(Aircraft.Design.RESERVE_FUEL_ADDITIONAL, [0], units='lbm') - input_values.set_val(Aircraft.Design.RESERVE_FUEL_FRACTION, - [-res], units='unitless') + input_values.set_val( + Aircraft.Design.RESERVE_FUEL_FRACTION, [-res], units='unitless' + ) elif res >= 10: - input_values.set_val(Aircraft.Design.RESERVE_FUEL_FRACTION, - [0], units='unitless') + input_values.set_val( + Aircraft.Design.RESERVE_FUEL_FRACTION, [0], units='unitless' + ) else: ValueError('"FRESF" is not valid between 0 and 10.') @@ -547,25 +654,51 @@ def update_flops_options(vehicle_data): # Additional mass fraction scaler set to zero to not add mass twice if Aircraft.Engine.ADDITIONAL_MASS_FRACTION in input_values: if input_values.get_val(Aircraft.Engine.ADDITIONAL_MASS_FRACTION)[0] >= 1: - input_values.set_val(Aircraft.Engine.ADDITIONAL_MASS, - input_values.get_val( - Aircraft.Engine.ADDITIONAL_MASS_FRACTION), - 'lbm') + input_values.set_val( + Aircraft.Engine.ADDITIONAL_MASS, + input_values.get_val(Aircraft.Engine.ADDITIONAL_MASS_FRACTION), + 'lbm', + ) input_values.set_val(Aircraft.Engine.ADDITIONAL_MASS_FRACTION, [0.0]) # Miscellaneous propulsion mass trigger point 1 instead of 5 if Aircraft.Propulsion.MISC_MASS_SCALER in input_values: if input_values.get_val(Aircraft.Propulsion.MISC_MASS_SCALER)[0] >= 1: - input_values.set_val(Aircraft.Propulsion.TOTAL_MISC_MASS, - input_values.get_val( - Aircraft.Propulsion.MISC_MASS_SCALER), - 'lbm') + input_values.set_val( + Aircraft.Propulsion.TOTAL_MISC_MASS, + input_values.get_val(Aircraft.Propulsion.MISC_MASS_SCALER), + 'lbm', + ) input_values.set_val(Aircraft.Propulsion.MISC_MASS_SCALER, [0.0]) vehicle_data['input_values'] = input_values return vehicle_data +def update_aviary_options(vehicle_data): + """ + Special handling for variables that occurs for either legacy code + """ + input_values: NamedValues = vehicle_data['input_values'] + + # if reference + scaled thrust both provided, set scale factor + try: + ref_thrust = input_values.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf')[ + 0 + ] + scaled_thrust = input_values.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf')[ + 0 + ] + except KeyError: + pass + else: + scale_factor = scaled_thrust / ref_thrust + input_values.set_val(Aircraft.Engine.SCALE_FACTOR, [scale_factor]) + + vehicle_data['input_values'] = input_values + return vehicle_data + + def update_flops_scaler_variables(var_name, input_values: NamedValues): """ The following parameters are used to modify or override @@ -665,7 +798,8 @@ def update_gasp_scaler_variables(var_name, input_values: NamedValues): ] initialization_guesses = { - # initialization_guesses is a dictionary that contains values used to initialize the trajectory + # initialization_guesses is a dictionary that contains values used to + # initialize the trajectory 'actual_takeoff_mass': 0, 'rotation_mass': 0, 'fuel_burn_per_passenger_mile': 0, @@ -673,7 +807,7 @@ def update_gasp_scaler_variables(var_name, input_values: NamedValues): 'flight_duration': 0, 'time_to_climb': 0, 'climb_range': 0, - 'reserves': 0 + 'reserves': 0, } @@ -696,7 +830,7 @@ def _setup_F2A_parser(parser): "-o", "--out_file", default=None, - help="Filename for converted input deck, including partial or complete path." + help="Filename for converted input deck, including partial or complete path.", ) parser.add_argument( "-l", @@ -704,13 +838,13 @@ def _setup_F2A_parser(parser): type=LegacyCode, help="Name of the legacy code the deck originated from", choices=set(LegacyCode), - required=True + required=True, ) parser.add_argument( "-d", "--defaults_deck", default=None, - help="Deck of default values for unspecified variables" + help="Deck of default values for unspecified variables", ) parser.add_argument( "--force", @@ -736,5 +870,11 @@ def _exec_F2A(args, user_args): # convert verbosity from int to enum verbosity = Verbosity(args.verbosity) - create_aviary_deck(filepath, args.legacy_code, args.defaults_deck, - args.out_file, args.force, verbosity) + create_aviary_deck( + filepath, + args.legacy_code, + args.defaults_deck, + args.out_file, + args.force, + verbosity, + ) diff --git a/aviary/utils/preprocessors.py b/aviary/utils/preprocessors.py index deec2fb94..6c37a972c 100644 --- a/aviary/utils/preprocessors.py +++ b/aviary/utils/preprocessors.py @@ -316,6 +316,7 @@ def preprocess_propulsion(aviary_options: AviaryValues, engine_models: list = No # if aviary_val is an iterable, just grab val for this engine if isinstance(aviary_val, (list, np.ndarray, tuple)): aviary_val = aviary_val[i] + # add aviary_val to vec using type-appropriate syntax if isinstance(default_value, (list, np.ndarray)): vec = np.append(vec, aviary_val) elif isinstance(default_value, tuple): diff --git a/aviary/utils/process_input_decks.py b/aviary/utils/process_input_decks.py index 634b21140..c413c1b36 100644 --- a/aviary/utils/process_input_decks.py +++ b/aviary/utils/process_input_decks.py @@ -367,16 +367,29 @@ def initialization_guessing(aircraft_values: AviaryValues, initialization_guesse initialization_guesses['flight_duration'] = initialization_guesses['flight_duration'] * \ (60 * 60) + # TODO this does not work at all for mixed-type engines (some propeller and some not) try: - total_thrust = aircraft_values.get_val( - Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') * aircraft_values.get_val(Aircraft.Engine.NUM_ENGINES) + 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) + else: + total_thrust = aircraft_values.get_val( + Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') * aircraft_values.get_val(Aircraft.Engine.NUM_ENGINES) + except KeyError: - # heterogeneous engine-model case. Get thrust from the engine decks instead. - total_thrust = 0 - for model in engine_builders: - thrust = model.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') - num_engines = model.get_val(Aircraft.Engine.NUM_ENGINES) - total_thrust += thrust * num_engines + if engine_builders is not None and len(engine_builders) > 1: + + # heterogeneous engine-model case. Get thrust from the engine models instead. + total_thrust = 0 + for model in engine_builders: + thrust = model.get_val(Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') + num_engines = model.get_val(Aircraft.Engine.NUM_ENGINES) + total_thrust += thrust * num_engines + + else: + total_thrust = aircraft_values.get_val( + Aircraft.Engine.SCALED_SLS_THRUST, 'lbf') * aircraft_values.get_val(Aircraft.Engine.NUM_ENGINES) gamma_guess = np.arcsin(.5*total_thrust / mission_mass) avg_speed_guess = (.5 * 667 * cruise_mach) # kts @@ -433,7 +446,7 @@ def initialization_guessing(aircraft_values: AviaryValues, initialization_guesse [Aircraft.Design.PART25_STRUCTURAL_CATEGORY, { 'val': 0, 'relation': '<', 'target': Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER, 'result': True, 'alternate': False}], [Aircraft.Engine.TYPE, { - 'val': [1, 2, 3, 4, 11, 12, 13, 14], 'relation': 'in', 'target': Aircraft.Engine.HAS_PROPELLERS, 'result': True, 'alternate': False}], + 'val': [1, 2, 3, 4, 6, 11, 12, 13, 14], 'relation': 'in', 'target': Aircraft.Engine.HAS_PROPELLERS, 'result': True, 'alternate': False}], ['JENGSZ', { 'val': 4, 'relation': '!=', 'target': Aircraft.Engine.SCALE_PERFORMANCE, 'result': True, 'alternate': False}], [Aircraft.HorizontalTail.VOLUME_COEFFICIENT, { 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 f7007f33e..84753ddb9 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 @@ -29,7 +29,7 @@ from aviary.utils.aviary_values import AviaryValues from aviary.utils.functions import set_aviary_input_defaults from aviary.utils.functions import set_aviary_initial_values -from aviary.utils.preprocessors import preprocess_crewpayload +from aviary.utils.preprocessors import preprocess_crewpayload, preprocess_propulsion from aviary.utils.test_utils.assert_utils import warn_timeseries_near_equal from aviary.utils.test_utils.default_subsystems import get_default_mission_subsystems from aviary.validation_cases.validation_tests import get_flops_inputs @@ -188,6 +188,7 @@ def run_trajectory(sim=True): # default subsystems engine = build_engine_deck(aviary_inputs) + preprocess_propulsion(aviary_inputs, engine) default_mission_subsystems = get_default_mission_subsystems('FLOPS', engine) climb_options = EnergyPhase( @@ -308,8 +309,11 @@ def run_trajectory(sim=True): 'landing', landing, promotes_inputs=['aircraft:*', 'mission:*'], promotes_outputs=['mission:*']) - traj.link_phases(["climb", "cruise", "descent"], [ - "time", Dynamic.Mission.MASS, Dynamic.Mission.DISTANCE], connected=strong_couple) + traj.link_phases( + ["climb", "cruise", "descent"], + ["time", Dynamic.Vehicle.MASS, Dynamic.Mission.DISTANCE], + connected=strong_couple, + ) # Need to declare dymos parameters for every input that is promoted out of the missions. externs = {'climb': {}, 'cruise': {}, 'descent': {}} @@ -444,13 +448,21 @@ def run_trajectory(sim=True): prob.set_val('traj.climb.t_initial', t_i_climb, units='s') prob.set_val('traj.climb.t_duration', t_duration_climb, units='s') - prob.set_val('traj.climb.controls:altitude', climb.interp( - Dynamic.Mission.ALTITUDE, ys=[alt_i_climb, alt_f_climb]), units='m') prob.set_val( - 'traj.climb.controls:mach', climb.interp( - Dynamic.Mission.MACH, ys=[mach_i_climb, mach_f_climb]), units='unitless') - prob.set_val('traj.climb.states:mass', climb.interp( - Dynamic.Mission.MASS, ys=[mass_i_climb, mass_f_climb]), units='kg') + 'traj.climb.controls:altitude', + climb.interp(Dynamic.Mission.ALTITUDE, ys=[alt_i_climb, alt_f_climb]), + units='m', + ) + prob.set_val( + 'traj.climb.controls:mach', + climb.interp(Dynamic.Atmosphere.MACH, ys=[mach_i_climb, mach_f_climb]), + units='unitless', + ) + prob.set_val( + 'traj.climb.states:mass', + climb.interp(Dynamic.Vehicle.MASS, ys=[mass_i_climb, mass_f_climb]), + units='kg', + ) prob.set_val('traj.climb.states:distance', climb.interp( Dynamic.Mission.DISTANCE, ys=[distance_i_climb, distance_f_climb]), units='m') @@ -462,26 +474,42 @@ def run_trajectory(sim=True): else: controls_str = 'polynomial_controls' - prob.set_val(f'traj.cruise.{controls_str}:altitude', cruise.interp( - Dynamic.Mission.ALTITUDE, ys=[alt_i_cruise, alt_f_cruise]), units='m') prob.set_val( - f'traj.cruise.{controls_str}:mach', cruise.interp( - Dynamic.Mission.MACH, ys=[cruise_mach, cruise_mach]), units='unitless') - prob.set_val('traj.cruise.states:mass', cruise.interp( - Dynamic.Mission.MASS, ys=[mass_i_cruise, mass_f_cruise]), units='kg') + f'traj.cruise.{controls_str}:altitude', + cruise.interp(Dynamic.Mission.ALTITUDE, ys=[alt_i_cruise, alt_f_cruise]), + units='m', + ) + prob.set_val( + f'traj.cruise.{controls_str}:mach', + cruise.interp(Dynamic.Atmosphere.MACH, ys=[cruise_mach, cruise_mach]), + units='unitless', + ) + prob.set_val( + 'traj.cruise.states:mass', + cruise.interp(Dynamic.Vehicle.MASS, ys=[mass_i_cruise, mass_f_cruise]), + units='kg', + ) prob.set_val('traj.cruise.states:distance', cruise.interp( Dynamic.Mission.DISTANCE, ys=[distance_i_cruise, distance_f_cruise]), units='m') prob.set_val('traj.descent.t_initial', t_i_descent, units='s') prob.set_val('traj.descent.t_duration', t_duration_descent, units='s') - prob.set_val('traj.descent.controls:altitude', descent.interp( - Dynamic.Mission.ALTITUDE, ys=[alt_i_descent, alt_f_descent]), units='m') prob.set_val( - 'traj.descent.controls:mach', descent.interp( - Dynamic.Mission.MACH, ys=[mach_i_descent, mach_f_descent]), units='unitless') - prob.set_val('traj.descent.states:mass', descent.interp( - Dynamic.Mission.MASS, ys=[mass_i_descent, mass_f_descent]), units='kg') + 'traj.descent.controls:altitude', + descent.interp(Dynamic.Mission.ALTITUDE, ys=[alt_i_descent, alt_f_descent]), + units='m', + ) + prob.set_val( + 'traj.descent.controls:mach', + descent.interp(Dynamic.Atmosphere.MACH, ys=[mach_i_descent, mach_f_descent]), + units='unitless', + ) + prob.set_val( + 'traj.descent.states:mass', + descent.interp(Dynamic.Vehicle.MASS, ys=[mass_i_descent, mass_f_descent]), + units='kg', + ) prob.set_val('traj.descent.states:distance', descent.interp( Dynamic.Mission.DISTANCE, ys=[distance_i_descent, distance_f_descent]), units='m') diff --git a/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py b/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py index 913fb3ee4..7fe7e744e 100644 --- a/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py +++ b/aviary/validation_cases/benchmark_tests/test_battery_in_a_mission.py @@ -88,15 +88,49 @@ def test_subsystems_in_a_mission(self): electric_energy_used = prob.get_val( 'traj.cruise.timeseries.' - f'{av.Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED}', + f'{av.Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED}', units='kW*h', ) + soc = prob.get_val( + 'traj.cruise.timeseries.' + f'{av.Dynamic.Vehicle.BATTERY_STATE_OF_CHARGE}', + ) fuel_burned = prob.get_val(av.Mission.Summary.FUEL_BURNED, units='lbm') # Check outputs - assert_near_equal(electric_energy_used[-1], 38.60538132, 1.e-7) - assert_near_equal(fuel_burned, 676.87235486, 1.e-7) + # indirectly check mission trajectory by checking total fuel/electric split + assert_near_equal(electric_energy_used[-1], 38.60747069, 1.e-7) + assert_near_equal(fuel_burned, 676.93670291, 1.e-7) + # check battery state-of-charge over mission + + assert_near_equal( + soc.ravel(), + [0.9999957806265609, + 0.975511918724275, + 0.9417326925421843, + 0.931042529806735, + 0.931042529806735, + 0.8810540781831623, + 0.8120948314123136, + 0.7902729948636958, + 0.7902729948636958, + 0.7308724676601358, + 0.6489324990486358, + 0.6230037623262401, + 0.6230037623262401, + 0.5730701397031007, + 0.5041865153698425, + 0.4823886057245942, + 0.4823886057245942, + 0.4579498542268948, + 0.4242328589510152, + 0.4135623891269744], + 1e-7, + ) if __name__ == "__main__": - unittest.main() + # unittest.main() + test = TestSubsystemsMission() + test.setUp() + test.test_subsystems_in_a_mission() diff --git a/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py b/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py index 1c10dc162..82304cd17 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_GwGm.py @@ -231,7 +231,7 @@ def test_bench_GwGm_shooting(self): if __name__ == '__main__': - # unittest.main() - test = ProblemPhaseTestCase() - test.setUp() - test.test_bench_GwGm_shooting() + unittest.main() + # test = ProblemPhaseTestCase() + # test.setUp() + # test.test_bench_GwGm_SNOPT() diff --git a/aviary/validation_cases/benchmark_tests/test_bench_electrified_large_turboprop_freighter.py b/aviary/validation_cases/benchmark_tests/test_bench_electrified_large_turboprop_freighter.py new file mode 100644 index 000000000..054170193 --- /dev/null +++ b/aviary/validation_cases/benchmark_tests/test_bench_electrified_large_turboprop_freighter.py @@ -0,0 +1,101 @@ +import numpy as np +import unittest +import openmdao.api as om + + +from numpy.testing import assert_almost_equal +from openmdao.utils.testing_utils import use_tempdirs + +from aviary.interface.methods_for_level2 import AviaryProblem +from aviary.subsystems.propulsion.turboprop_model import TurbopropModel +from aviary.subsystems.propulsion.motor.motor_builder import MotorBuilder +from aviary.utils.process_input_decks import create_vehicle +from aviary.variable_info.variables import Aircraft, Mission, Settings + +from aviary.models.large_turboprop_freighter.phase_info import ( + two_dof_phase_info, + energy_phase_info, +) + + +@use_tempdirs +# TODO need to add asserts with "truth" values +class LargeElectrifiedTurbopropFreighterBenchmark(unittest.TestCase): + + def build_and_run_problem(self): + + # Build problem + prob = AviaryProblem() + + # load inputs from .csv to build engine + options, guesses = create_vehicle( + "models/large_turboprop_freighter/large_turboprop_freighter.csv" + ) + + options.set_val(Settings.EQUATIONS_OF_MOTION, 'height_energy') + # options.set_val(Aircraft.Engine.NUM_ENGINES, 2) + # options.set_val(Aircraft.Engine.WING_LOCATIONS, 0.385) + scale_factor = 3 + options.set_val(Aircraft.Engine.RPM_DESIGN, 6000, 'rpm') + options.set_val(Aircraft.Engine.FIXED_RPM, 6000, 'rpm') + options.set_val(Aircraft.Engine.Gearbox.GEAR_RATIO, 5.88) + options.set_val(Aircraft.Engine.Gearbox.EFFICIENCY, 1.0) + options.set_val(Aircraft.Engine.SCALE_FACTOR, scale_factor) # 11.87) + options.set_val( + Aircraft.Engine.SCALED_SLS_THRUST, + options.get_val(Aircraft.Engine.REFERENCE_SLS_THRUST, 'lbf') * scale_factor, + 'lbf', + ) + + # turboprop = TurbopropModel('turboprop', options=options) + # turboprop2 = TurbopropModel('turboprop2', options=options) + + motor = MotorBuilder( + 'motor', + ) + + electroprop = TurbopropModel( + 'electroprop', options=options, shaft_power_model=motor + ) + + # load_inputs needs to be updated to accept an already existing aviary options + prob.load_inputs( + options, # "models/large_turboprop_freighter/large_turboprop_freighter.csv", + energy_phase_info, + engine_builders=[electroprop], + ) + prob.aviary_inputs.set_val(Settings.VERBOSITY, 2) + + # FLOPS aero specific stuff? Best guesses for values here + prob.aviary_inputs.set_val(Mission.Constraints.MAX_MACH, 0.5) + prob.aviary_inputs.set_val(Aircraft.Wing.AREA, 1744.59, 'ft**2') + # prob.aviary_inputs.set_val(Aircraft.Wing.ASPECT_RATIO, 10.078) + prob.aviary_inputs.set_val( + Aircraft.Wing.THICKNESS_TO_CHORD, + 0.1500) # average between root and chord T/C + prob.aviary_inputs.set_val(Aircraft.Fuselage.MAX_WIDTH, 4.3, 'm') + prob.aviary_inputs.set_val(Aircraft.Fuselage.MAX_HEIGHT, 3.95, 'm') + prob.aviary_inputs.set_val(Aircraft.Fuselage.AVG_DIAMETER, 4.125, 'm') + + prob.check_and_preprocess_inputs() + prob.add_pre_mission_systems() + prob.add_phases() + prob.add_post_mission_systems() + prob.link_phases() + prob.add_driver("IPOPT", max_iter=0, verbosity=0) + prob.add_design_variables() + prob.add_objective() + + prob.setup() + # prob.model.list_vars(units=True, print_arrays=True) + om.n2(prob) + + prob.set_initial_guesses() + prob.run_aviary_problem("dymos_solution.db") + + om.n2(prob) + + +if __name__ == '__main__': + test = LargeElectrifiedTurbopropFreighterBenchmark() + test.build_and_run_problem() diff --git a/aviary/models/large_turboprop_freighter/test_bench_large_turboprop_freighter.py b/aviary/validation_cases/benchmark_tests/test_bench_large_turboprop_freighter.py similarity index 73% rename from aviary/models/large_turboprop_freighter/test_bench_large_turboprop_freighter.py rename to aviary/validation_cases/benchmark_tests/test_bench_large_turboprop_freighter.py index cfd330d1d..1454af94d 100644 --- a/aviary/models/large_turboprop_freighter/test_bench_large_turboprop_freighter.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_large_turboprop_freighter.py @@ -1,15 +1,21 @@ import numpy as np import unittest +import openmdao.api as om + from numpy.testing import assert_almost_equal from openmdao.utils.testing_utils import use_tempdirs from aviary.interface.methods_for_level2 import AviaryProblem from aviary.subsystems.propulsion.turboprop_model import TurbopropModel +from aviary.subsystems.propulsion.motor.motor_builder import MotorBuilder from aviary.utils.process_input_decks import create_vehicle from aviary.variable_info.variables import Aircraft, Mission, Settings -from aviary.models.large_turboprop_freighter.phase_info import phase_info +from aviary.models.large_turboprop_freighter.phase_info import ( + two_dof_phase_info, + energy_phase_info, +) @use_tempdirs @@ -32,26 +38,30 @@ def build_and_run_problem(self): # load_inputs needs to be updated to accept an already existing aviary options prob.load_inputs( "models/large_turboprop_freighter/large_turboprop_freighter.csv", - phase_info, + two_dof_phase_info, engine_builders=[turboprop], ) + prob.aviary_inputs.set_val(Settings.VERBOSITY, 2) # FLOPS aero specific stuff? Best guesses for values here - # prob.aviary_inputs.set_val(Mission.Constraints.MAX_MACH, 0.5) - # prob.aviary_inputs.set_val(Aircraft.Fuselage.AVG_DIAMETER, 4.125, 'm') + prob.aviary_inputs.set_val(Mission.Constraints.MAX_MACH, 0.5) + prob.aviary_inputs.set_val(Aircraft.Fuselage.AVG_DIAMETER, 4.125, 'm') prob.check_and_preprocess_inputs() prob.add_pre_mission_systems() prob.add_phases() prob.add_post_mission_systems() prob.link_phases() - prob.add_driver("SLSQP", max_iter=0, verbosity=0) + prob.add_driver("IPOPT", max_iter=0, verbosity=0) prob.add_design_variables() prob.add_objective() prob.setup() + # om.n2(prob) + prob.set_initial_guesses() + prob.run_aviary_problem("dymos_solution.db") - prob.run_aviary_problem("dymos_solution.db", make_plots=False) + om.n2(prob) if __name__ == '__main__': diff --git a/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py b/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py index 1302e1b2b..146a1f1be 100644 --- a/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py +++ b/aviary/validation_cases/benchmark_tests/test_bench_multiengine.py @@ -129,9 +129,9 @@ def test_multiengine_static(self): alloc_cruise = prob.get_val('traj.cruise.parameter_vals:throttle_allocations') alloc_descent = prob.get_val('traj.descent.parameter_vals:throttle_allocations') - assert_near_equal(alloc_climb[0], 0.512, tolerance=1e-2) - assert_near_equal(alloc_cruise[0], 0.747, tolerance=1e-2) - assert_near_equal(alloc_descent[0], 0.999, tolerance=1e-2) + 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) @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.751, tolerance=1e-2) + assert_near_equal(alloc_cruise[0], 0.576, tolerance=1e-2) # Check general trend: favors engine 1. self.assertGreater(alloc_climb[2], 0.55) diff --git a/aviary/validation_cases/validation_data/flops_data/full_mission_test_data.py b/aviary/validation_cases/validation_data/flops_data/full_mission_test_data.py index 02aca9e40..92086d0f6 100644 --- a/aviary/validation_cases/validation_data/flops_data/full_mission_test_data.py +++ b/aviary/validation_cases/validation_data/flops_data/full_mission_test_data.py @@ -62,55 +62,87 @@ data.set_val( # states:altitude Dynamic.Mission.ALTITUDE, - val=[29.3112920637369, 10668, 26.3564405194251, ], + val=[ + 29.3112920637369, + 10668, + 26.3564405194251, + ], units='m', ) data.set_val( # outputs Dynamic.Mission.ALTITUDE_RATE, - val=[29.8463233754212, -5.69941245767868E-09, -4.32644785970493, ], + val=[ + 29.8463233754212, + -5.69941245767868e-09, + -4.32644785970493, + ], units='ft/s', ) data.set_val( # outputs Dynamic.Mission.ALTITUDE_RATE_MAX, - val=[3679.0525544843, 3.86361517135375, 6557.07891846677, ], + val=[ + 3679.0525544843, + 3.86361517135375, + 6557.07891846677, + ], units='ft/min', ) data.set_val( # outputs - Dynamic.Mission.DRAG, - val=[9978.32211087097, 8769.90342254821, 7235.03338269778, ], + Dynamic.Vehicle.DRAG, + val=[ + 9978.32211087097, + 8769.90342254821, + 7235.03338269778, + ], units='lbf', ) data.set_val( # outputs - Dynamic.Mission.FUEL_FLOW_RATE, - val=[16602.302762413, 5551.61304633633, 1286, ], + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE, + val=[ + 16602.302762413, + 5551.61304633633, + 1286, + ], units='lbm/h', ) data.set_val( - Dynamic.Mission.MACH, - val=[0.482191004489294, 0.785, 0.345807620281699, ], + Dynamic.Atmosphere.MACH, + val=[ + 0.482191004489294, + 0.785, + 0.345807620281699, + ], units='unitless', ) data.set_val( # states:mass - Dynamic.Mission.MASS, - val=[81796.1389890711, 74616.9849763798, 65193.7423491884, ], + Dynamic.Vehicle.MASS, + val=[ + 81796.1389890711, + 74616.9849763798, + 65193.7423491884, + ], units='kg', ) # TODO: double check values data.set_val( - Dynamic.Mission.THROTTLE, - val=[0.5, 0.5, 0., ], + Dynamic.Vehicle.Propulsion.THROTTLE, + val=[ + 0.5, + 0.5, + 0.0, + ], units='unitless', ) @@ -131,28 +163,44 @@ data.set_val( # outputs Dynamic.Mission.SPECIFIC_ENERGY_RATE, - val=[18.4428113202544191, -1.7371801250963E-9, -5.9217623736010768, ], + val=[ + 18.4428113202544191, + -1.7371801250963e-9, + -5.9217623736010768, + ], units='m/s', ) data.set_val( # outputs Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, - val=[28.03523893220630, 3.8636151713537548, 28.706899839848, ], + val=[ + 28.03523893220630, + 3.8636151713537548, + 28.706899839848, + ], units='m/s', ) data.set_val( # outputs - Dynamic.Mission.THRUST_TOTAL, - val=[30253.9128379374, 8769.90342132054, 0, ], + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, + val=[ + 30253.9128379374, + 8769.90342132054, + 0, + ], units='lbf', ) data.set_val( # outputs - Dynamic.Mission.THRUST_MAX_TOTAL, - val=[40799.6009633346, 11500.32, 42308.2709683461, ], + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, + val=[ + 40799.6009633346, + 11500.32, + 42308.2709683461, + ], units='lbf', ) @@ -166,13 +214,21 @@ data.set_val( # states:velocity Dynamic.Mission.VELOCITY, - val=[164.029012458452, 232.775306059091, 117.638805929526, ], + val=[ + 164.029012458452, + 232.775306059091, + 117.638805929526, + ], units='m/s', ) data.set_val( # state_rates:velocity Dynamic.Mission.VELOCITY_RATE, - val=[0.558739800813549, 3.33665416459715E-17, -0.38372209277242, ], + val=[ + 0.558739800813549, + 3.33665416459715e-17, + -0.38372209277242, + ], units='m/s**2', ) diff --git a/aviary/variable_info/enums.py b/aviary/variable_info/enums.py index 75d7392b7..e2d2edaff 100644 --- a/aviary/variable_info/enums.py +++ b/aviary/variable_info/enums.py @@ -68,7 +68,7 @@ class GASPEngineType(Enum): """ Defines the type of engine to use in GASP-based mass calculations. Note that only the value for the first engine model will be used. - Currenly only the TURBOJET option is implemented, but other types of engines will be added in the future. + Currenly only the TURBOJET and TURBOPROP options are implemented, but other types of engines will be added in the future. """ # Reciprocating engine with carburator RECIP_CARB = 1 diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 776303688..6ef0e83de 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -1,13 +1,21 @@ ''' Define meta data associated with variables in the Aviary data hierarchy. ''' + import numpy as np from copy import deepcopy from pathlib import Path from aviary.utils.develop_metadata import add_meta_data -from aviary.variable_info.enums import EquationsOfMotion, FlapType, GASPEngineType, LegacyCode, Verbosity, ProblemType +from aviary.variable_info.enums import ( + EquationsOfMotion, + FlapType, + GASPEngineType, + LegacyCode, + Verbosity, + ProblemType, +) from aviary.variable_info.variables import Aircraft, Dynamic, Mission, Settings # --------------------------- @@ -51,13 +59,15 @@ # - see also: Aircraft.AirConditioning.MASS_SCALER Aircraft.AirConditioning.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(23, 2)', '~WEIGHT.WAC', '~WTSTAT.WSP(23, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._air_conditioning_group_weight', - 'aircraft.outputs.L0_weights_summary.air_conditioning_group_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(23, 2)', '~WEIGHT.WAC', '~WTSTAT.WSP(23, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._air_conditioning_group_weight', + 'aircraft.outputs.L0_weights_summary.air_conditioning_group_weight', + ], + }, units='lbm', desc='air conditioning system mass', default_value=None, @@ -66,10 +76,7 @@ add_meta_data( Aircraft.AirConditioning.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(6)', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CW(6)', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='mass trend coefficient of air conditioning', default_value=1.0, @@ -78,11 +85,12 @@ add_meta_data( Aircraft.AirConditioning.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WAC', 'MISWT.WAC', 'MISWT.OAC'], - "FLOPS": 'WTIN.WAC', - "LEAPS1": 'aircraft.inputs.L0_overrides.air_conditioning_group_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WAC', 'MISWT.WAC', 'MISWT.OAC'], + "FLOPS": 'WTIN.WAC', + "LEAPS1": 'aircraft.inputs.L0_overrides.air_conditioning_group_weight', + }, units='unitless', desc='air conditioning system mass scaler', default_value=1.0, @@ -103,13 +111,15 @@ # - see also: Aircraft.AntiIcing.MASS_SCALER Aircraft.AntiIcing.MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(7)', - # ['WTS.WSP(24, 2)', '~WEIGHT.WAI', '~WTSTAT.WSP(24, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._aux_gear_weight', - 'aircraft.outputs.L0_weights_summary.aux_gear_weight', - ] - }, + historical_name={ + "GASP": 'INGASP.CW(7)', + # ['WTS.WSP(24, 2)', '~WEIGHT.WAI', '~WTSTAT.WSP(24, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._aux_gear_weight', + 'aircraft.outputs.L0_weights_summary.aux_gear_weight', + ], + }, units='lbm', desc='mass of anti-icing system (auxiliary gear)', default_value=None, @@ -118,11 +128,12 @@ add_meta_data( Aircraft.AntiIcing.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WAI', 'MISWT.WAI', 'MISWT.OAI'], - "FLOPS": 'WTIN.WAI', - "LEAPS1": 'aircraft.inputs.L0_overrides.aux_gear_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WAI', 'MISWT.WAI', 'MISWT.OAI'], + "FLOPS": 'WTIN.WAI', + "LEAPS1": 'aircraft.inputs.L0_overrides.aux_gear_weight', + }, units='unitless', desc='anti-icing system mass scaler', default_value=1.0, @@ -141,13 +152,15 @@ # - see also: Aircraft.APU.MASS_SCALER Aircraft.APU.MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(1)', - # ['WTS.WSP(17, 2)', '~WEIGHT.WAPU', '~WTSTAT.WSP(17, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._aux_power_weight', - 'aircraft.outputs.L0_weights_summary.aux_power_weight', - ] - }, + historical_name={ + "GASP": 'INGASP.CW(1)', + # ['WTS.WSP(17, 2)', '~WEIGHT.WAPU', '~WTSTAT.WSP(17, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._aux_power_weight', + 'aircraft.outputs.L0_weights_summary.aux_power_weight', + ], + }, units='lbm', desc='mass of auxiliary power unit', default_value=None, @@ -156,11 +169,12 @@ add_meta_data( Aircraft.APU.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WAPU', 'MISWT.WAPU', 'MISWT.OAPU'], - "FLOPS": 'WTIN.WAPU', - "LEAPS1": 'aircraft.inputs.L0_overrides.aux_power_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WAPU', 'MISWT.WAPU', 'MISWT.OAPU'], + "FLOPS": 'WTIN.WAPU', + "LEAPS1": 'aircraft.inputs.L0_overrides.aux_power_weight', + }, units='unitless', desc='mass scaler for auxiliary power unit', default_value=1.0, @@ -179,13 +193,15 @@ # - see also: Aircraft.Avionics.MASS_SCALER Aircraft.Avionics.MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(5)', - # ['WTS.WSP(21, 2)', '~WEIGHT.WAVONC', '~WTSTAT.WSP(21, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._avionics_group_weight', - 'aircraft.outputs.L0_weights_summary.avionics_group_weight', - ] - }, + historical_name={ + "GASP": 'INGASP.CW(5)', + # ['WTS.WSP(21, 2)', '~WEIGHT.WAVONC', '~WTSTAT.WSP(21, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._avionics_group_weight', + 'aircraft.outputs.L0_weights_summary.avionics_group_weight', + ], + }, units='lbm', desc='avionics mass', default_value=None, @@ -194,11 +210,12 @@ add_meta_data( Aircraft.Avionics.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WAVONC', 'MISWT.WAVONC', 'MISWT.OAVONC'], - "FLOPS": 'WTIN.WAVONC', - "LEAPS1": 'aircraft.inputs.L0_overrides.avionics_group_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WAVONC', 'MISWT.WAVONC', 'MISWT.OAVONC'], + "FLOPS": 'WTIN.WAVONC', + "LEAPS1": 'aircraft.inputs.L0_overrides.avionics_group_weight', + }, units='unitless', desc='avionics mass scaler', default_value=1.0, @@ -216,10 +233,11 @@ add_meta_data( Aircraft.Battery.ADDITIONAL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": 'aircraft.inputs.L0_battery.weight_offset' - }, + historical_name={ + "GASP": None, + "FLOPS": None, + "LEAPS1": 'aircraft.inputs.L0_battery.weight_offset', + }, units='lbm', desc='mass of non energy-storing parts of the battery', default_value=0.0, @@ -228,13 +246,14 @@ add_meta_data( Aircraft.Battery.DISCHARGE_LIMIT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SOCMIN', - "FLOPS": None, - "LEAPS1": 'aircraft.inputs.L0_battery.depth_of_discharge' - }, + historical_name={ + "GASP": 'INGASP.SOCMIN', + "FLOPS": None, + "LEAPS1": 'aircraft.inputs.L0_battery.depth_of_discharge', + }, units='unitless', desc='default constraint on how far the battery can discharge, as a proportion of ' - 'total energy capacity', + 'total energy capacity', default_value=0.2, ) @@ -250,21 +269,19 @@ add_meta_data( Aircraft.Battery.ENERGY_CAPACITY, meta_data=_MetaData, - historical_name={"GASP": 'EBATTAVL', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'EBATTAVL', "FLOPS": None, "LEAPS1": None}, units='kJ', - desc="total energy the battery can store" + desc="total energy the battery can store", ) add_meta_data( Aircraft.Battery.MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WBATTIN', - "FLOPS": None, - "LEAPS1": 'aircraft.inputs.L0_battery.weight' - }, + historical_name={ + "GASP": 'INGASP.WBATTIN', + "FLOPS": None, + "LEAPS1": 'aircraft.inputs.L0_battery.weight', + }, units='lbm', desc='total mass of the battery', default_value=0.0, @@ -273,10 +290,11 @@ add_meta_data( Aircraft.Battery.PACK_ENERGY_DENSITY, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ENGYDEN', - "FLOPS": None, - "LEAPS1": 'aircraft.inputs.L0_battery.energy_density' - }, + historical_name={ + "GASP": 'INGASP.ENGYDEN', + "FLOPS": None, + "LEAPS1": 'aircraft.inputs.L0_battery.energy_density', + }, units='kW*h/kg', desc='specific energy density of the battery pack', default_value=1.0, @@ -286,10 +304,7 @@ add_meta_data( Aircraft.Battery.PACK_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of the energy-storing components of the battery', default_value=0.0, @@ -298,10 +313,7 @@ add_meta_data( Aircraft.Battery.PACK_VOLUMETRIC_DENSITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='kW*h/L', desc='volumetric density of the battery pack', default_value=0, @@ -310,10 +322,7 @@ add_meta_data( Aircraft.Battery.VOLUME, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='ft*3', desc='total volume of the battery pack', default_value=0.0, @@ -333,13 +342,15 @@ add_meta_data( Aircraft.BWB.CABIN_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.FUSEIN.ACABIN', 'WDEF.ACABIN'], - "FLOPS": 'FUSEIN.ACABIN', - "LEAPS1": ['aircraft.inputs.L0_blended_wing_body_design.cabin_area', - 'aircraft.cached.L0_blended_wing_body_design.cabin_area', - ] - }, + historical_name={ + "GASP": None, + # ['&DEFINE.FUSEIN.ACABIN', 'WDEF.ACABIN'], + "FLOPS": 'FUSEIN.ACABIN', + "LEAPS1": [ + 'aircraft.inputs.L0_blended_wing_body_design.cabin_area', + 'aircraft.cached.L0_blended_wing_body_design.cabin_area', + ], + }, units='ft**2', desc='fixed area of passenger cabin for blended wing body transports', default_value=0.0, @@ -348,12 +359,14 @@ add_meta_data( Aircraft.BWB.NUM_BAYS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'FUSEIN.NBAY', # ['&DEFINE.FUSEIN.NBAY', 'FUSDTA.NBAY'], - "LEAPS1": ['aircraft.inputs.L0_blended_wing_body_design.bay_count', - 'aircraft.cached.L0_blended_wing_body_design.bay_count', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'FUSEIN.NBAY', # ['&DEFINE.FUSEIN.NBAY', 'FUSDTA.NBAY'], + "LEAPS1": [ + 'aircraft.inputs.L0_blended_wing_body_design.bay_count', + 'aircraft.cached.L0_blended_wing_body_design.bay_count', + ], + }, units='unitless', desc='fixed number of bays', types=int, @@ -364,11 +377,12 @@ add_meta_data( Aircraft.BWB.PASSENGER_LEADING_EDGE_SWEEP, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.FUSEIN.SWPLE', 'FUSDTA.SWPLE'], - "FLOPS": 'FUSEIN.SWPLE', - "LEAPS1": 'aircraft.inputs.L0_blended_wing_body_design.passenger_leading_edge_sweep' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.FUSEIN.SWPLE', 'FUSDTA.SWPLE'], + "FLOPS": 'FUSEIN.SWPLE', + "LEAPS1": 'aircraft.inputs.L0_blended_wing_body_design.passenger_leading_edge_sweep', + }, units='deg', desc='sweep angle of the leading edge of the passenger cabin', default_value=45.0, @@ -384,10 +398,11 @@ add_meta_data( Aircraft.Canard.AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.SCAN', # ['&DEFINE.WTIN.SCAN', 'EDETIN.SCAN'], - "LEAPS1": 'aircraft.inputs.L0_canard.area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.SCAN', # ['&DEFINE.WTIN.SCAN', 'EDETIN.SCAN'], + "LEAPS1": 'aircraft.inputs.L0_canard.area', + }, units='ft**2', desc='canard theoretical area', default_value=0.0, @@ -396,10 +411,11 @@ add_meta_data( Aircraft.Canard.ASPECT_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.ARCAN', # ['&DEFINE.WTIN.ARCAN', 'EDETIN.ARCAN'], - "LEAPS1": 'aircraft.inputs.L0_canard.aspect_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.ARCAN', # ['&DEFINE.WTIN.ARCAN', 'EDETIN.ARCAN'], + "LEAPS1": 'aircraft.inputs.L0_canard.aspect_ratio', + }, units='unitless', desc='canard theoretical aspect ratio', default_value=None, @@ -408,36 +424,41 @@ add_meta_data( Aircraft.Canard.CHARACTERISTIC_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL[-1]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[-1]', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[-1]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL[-1]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[-1]', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[-1]', + ], + }, units='ft', - desc='Reynolds characteristic length for the canard' + desc='Reynolds characteristic length for the canard', ) add_meta_data( Aircraft.Canard.FINENESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.FR[-1]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[-1]', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[-1]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.FR[-1]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[-1]', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[-1]', + ], + }, units='unitless', - desc='canard fineness ratio' + desc='canard fineness ratio', ) add_meta_data( Aircraft.Canard.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRLC', # ['&DEFINE.AERIN.TRLC', 'XLAM.TRLC', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.canard_percent_laminar_flow_lower_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRLC', # ['&DEFINE.AERIN.TRLC', 'XLAM.TRLC', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.canard_percent_laminar_flow_lower_surface', + }, units='unitless', desc='define percent laminar flow for canard lower surface', default_value=0.0, @@ -446,10 +467,11 @@ add_meta_data( Aircraft.Canard.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRUC', # ['&DEFINE.AERIN.TRUC', 'XLAM.TRUC', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.canard_percent_laminar_flow_upper_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRUC', # ['&DEFINE.AERIN.TRUC', 'XLAM.TRUC', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.canard_percent_laminar_flow_upper_surface', + }, units='unitless', desc='define percent laminar flow for canard upper surface', default_value=0.0, @@ -460,13 +482,15 @@ # - see also: Aircraft.Canard.MASS_SCALER Aircraft.Canard.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(5, 2)', '~WEIGHT.WCAN', '~WTSTAT.WSP(5, 2)', '~INERT.WCAN'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._canard_weight', - 'aircraft.outputs.L0_weights_summary.canard_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(5, 2)', '~WEIGHT.WCAN', '~WTSTAT.WSP(5, 2)', '~INERT.WCAN'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._canard_weight', + 'aircraft.outputs.L0_weights_summary.canard_weight', + ], + }, units='lbm', desc='mass of canards', default_value=None, @@ -475,10 +499,11 @@ add_meta_data( Aircraft.Canard.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRCAN', # ['&DEFINE.WTIN.FRCAN', 'WTS.FRCAN', ], - "LEAPS1": 'aircraft.inputs.L0_overrides.canard_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRCAN', # ['&DEFINE.WTIN.FRCAN', 'WTS.FRCAN', ], + "LEAPS1": 'aircraft.inputs.L0_overrides.canard_weight', + }, units='unitless', desc='mass scaler for canard structure', default_value=1.0, @@ -487,10 +512,11 @@ add_meta_data( Aircraft.Canard.TAPER_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.TRCAN', # ['&DEFINE.WTIN.TRCAN', 'WTS.TRCAN'], - "LEAPS1": 'aircraft.inputs.L0_canard.taper_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.TRCAN', # ['&DEFINE.WTIN.TRCAN', 'WTS.TRCAN'], + "LEAPS1": 'aircraft.inputs.L0_canard.taper_ratio', + }, units='unitless', desc='canard theoretical taper ratio', default_value=None, @@ -499,10 +525,11 @@ add_meta_data( Aircraft.Canard.THICKNESS_TO_CHORD, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.TCCAN', # ['&DEFINE.WTIN.TCCAN', 'EDETIN.TCCAN'], - "LEAPS1": 'aircraft.inputs.L0_canard.thickness_to_chord_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.TCCAN', # ['&DEFINE.WTIN.TCCAN', 'EDETIN.TCCAN'], + "LEAPS1": 'aircraft.inputs.L0_canard.thickness_to_chord_ratio', + }, units='unitless', desc='canard thickness-chord ratio', default_value=0.0, @@ -513,15 +540,17 @@ # - see also: Aircraft.Canard.WETTED_AREA_SCALER Aircraft.Canard.WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['ACTWET.SWTCN', 'MISSA.SWET[-1]'], - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.canard_wetted_area', - 'aircraft.outputs.L0_aerodynamics' - '.mission_component_wetted_area_table[-1]', - 'aircraft.cached.L0_aerodynamics' - '.mission_component_wetted_area_table[-1]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['ACTWET.SWTCN', 'MISSA.SWET[-1]'], + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.canard_wetted_area', + 'aircraft.outputs.L0_aerodynamics' + '.mission_component_wetted_area_table[-1]', + 'aircraft.cached.L0_aerodynamics' + '.mission_component_wetted_area_table[-1]', + ], + }, units='ft**2', desc='canard wetted area', default_value=None, @@ -530,10 +559,11 @@ add_meta_data( Aircraft.Canard.WETTED_AREA_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.SWETC', # ['&DEFINE.AERIN.SWETC', 'AWETO.SWETC', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.canard_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.SWETC', # ['&DEFINE.AERIN.SWETC', 'AWETO.SWETC', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.canard_wetted_area', + }, units='unitless', desc='canard wetted area scaler', default_value=1.0, @@ -550,10 +580,7 @@ add_meta_data( Aircraft.Controls.COCKPIT_CONTROL_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CK15', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CK15', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='technology factor on cockpit controls mass', default_value=1.0, @@ -562,10 +589,7 @@ add_meta_data( Aircraft.Controls.CONTROL_MASS_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELWFC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELWFC', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='incremental flight controls mass', default_value=0, @@ -574,10 +598,7 @@ add_meta_data( Aircraft.Controls.STABILITY_AUGMENTATION_SYSTEM_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKSAS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKSAS', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of stability augmentation system', default_value=0, @@ -586,10 +607,7 @@ add_meta_data( Aircraft.Controls.STABILITY_AUGMENTATION_SYSTEM_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CK19', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CK19', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='technology factor on stability augmentation system mass', default_value=1, @@ -598,10 +616,7 @@ add_meta_data( Aircraft.Controls.TOTAL_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WFC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WFC', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of cockpit controls, fixed wing controls, and SAS', ) @@ -619,24 +634,27 @@ add_meta_data( Aircraft.CrewPayload.BAGGAGE_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(35,2)', '~WEIGHT.WPBAG', '~WTSTAT.WSP(35,2)', '~INERT.WPBAG'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._passenger_bag_weight', - 'aircraft.outputs.L0_weights_summary.passenger_bag_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(35,2)', '~WEIGHT.WPBAG', '~WTSTAT.WSP(35,2)', '~INERT.WPBAG'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._passenger_bag_weight', + 'aircraft.outputs.L0_weights_summary.passenger_bag_weight', + ], + }, units='lbm', - desc='mass of passenger baggage' + desc='mass of passenger baggage', ) add_meta_data( Aircraft.CrewPayload.BAGGAGE_MASS_PER_PASSENGER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.BPP', # ['&DEFINE.WTIN.BPP', 'WPAB.BPP'], - "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.baggage_weight_per_passenger' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.BPP', # ['&DEFINE.WTIN.BPP', 'WPAB.BPP'], + "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.baggage_weight_per_passenger', + }, units='lbm', desc='baggage mass per passenger', option=True, @@ -648,13 +666,15 @@ # - see also: Aircraft.CrewPayload.CARGO_CONTAINER_MASS_SCALER Aircraft.CrewPayload.CARGO_CONTAINER_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(32,2)', '~WEIGHT.WCON', '~WTSTAT.WSP(32,2)', '~INERT.WCON',], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._cargo_containers_weight', - 'aircraft.outputs.L0_weights_summary.cargo_containers_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(32,2)', '~WEIGHT.WCON', '~WTSTAT.WSP(32,2)', '~INERT.WCON',], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._cargo_containers_weight', + 'aircraft.outputs.L0_weights_summary.cargo_containers_weight', + ], + }, units='lbm', desc='mass of cargo containers', default_value=None, @@ -663,11 +683,12 @@ add_meta_data( Aircraft.CrewPayload.CARGO_CONTAINER_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WCON', 'MISWT.WCON', 'MISWT.OCON'], - "FLOPS": 'WTIN.WCON', - "LEAPS1": 'aircraft.inputs.L0_overrides.cargo_containers_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WCON', 'MISWT.WCON', 'MISWT.OCON'], + "FLOPS": 'WTIN.WCON', + "LEAPS1": 'aircraft.inputs.L0_overrides.cargo_containers_weight', + }, units='unitless', desc='Scaler for mass of cargo containers', default_value=1.0, @@ -676,24 +697,23 @@ add_meta_data( Aircraft.CrewPayload.CARGO_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WCARGO', - # ['WTS.WSP(36,2)', '~WEIGHT.WCARGO', '~WTSTAT.WSP(36,2)', '~INERT.WCARGO',], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._cargo_weight', - 'aircraft.outputs.L0_weights_summary.cargo_weight', - ] - }, + historical_name={ + "GASP": 'INGASP.WCARGO', + # ['WTS.WSP(36,2)', '~WEIGHT.WCARGO', '~WTSTAT.WSP(36,2)', '~INERT.WCARGO',], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._cargo_weight', + 'aircraft.outputs.L0_weights_summary.cargo_weight', + ], + }, units='lbm', - desc='total mass of cargo' + desc='total mass of cargo', ) add_meta_data( Aircraft.CrewPayload.CATERING_ITEMS_MASS_PER_PASSENGER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(12)', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CW(12)', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of catering items per passenger', default_value=0.7, @@ -768,13 +788,15 @@ # - see also: Aircraft.CrewPayload.FLIGHT_CREW_MASS_SCALER Aircraft.CrewPayload.FLIGHT_CREW_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(27, 2)', '~WEIGHT.WFLCRB', '~WTSTAT.WSP(27, 2)', '~INERT.WFLCRB'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._flight_crew_and_bag_weight', - 'aircraft.outputs.L0_weights_summary.flight_crew_and_bag_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(27, 2)', '~WEIGHT.WFLCRB', '~WTSTAT.WSP(27, 2)', '~INERT.WFLCRB'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._flight_crew_and_bag_weight', + 'aircraft.outputs.L0_weights_summary.flight_crew_and_bag_weight', + ], + }, units='lbm', desc='total mass of the flight crew and their baggage', default_value=None, @@ -783,11 +805,12 @@ add_meta_data( Aircraft.CrewPayload.FLIGHT_CREW_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WFLCRB', 'MISWT.WFLCRB', 'MISWT.OFLCRB'], - "FLOPS": 'WTIN.WFLCRB', - "LEAPS1": 'aircraft.inputs.L0_overrides.flight_crew_and_bag_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WFLCRB', 'MISWT.WFLCRB', 'MISWT.OFLCRB'], + "FLOPS": 'WTIN.WFLCRB', + "LEAPS1": 'aircraft.inputs.L0_overrides.flight_crew_and_bag_weight', + }, units='unitless', desc='scaler for total mass of the flight crew and their baggage', default_value=1.0, @@ -796,10 +819,11 @@ add_meta_data( Aircraft.CrewPayload.MASS_PER_PASSENGER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.WPPASS', # ['&DEFINE.WTIN.WPPASS', 'WPAB.WPPASS'], - "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.weight_per_passenger' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.WPPASS', # ['&DEFINE.WTIN.WPPASS', 'WPAB.WPPASS'], + "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.weight_per_passenger', + }, units='lbm', desc='mass per passenger', option=True, @@ -809,10 +833,11 @@ add_meta_data( Aircraft.CrewPayload.MISC_CARGO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.CARGOF', # ['&DEFINE.WTIN.CARGOF', 'WTS.CARGOF'], - "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.misc_cargo' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.CARGOF', # ['&DEFINE.WTIN.CARGOF', 'WTS.CARGOF'], + "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.misc_cargo', + }, units='lbm', desc='cargo (other than passenger baggage) carried in fuselage', default_value=0.0, @@ -823,13 +848,15 @@ # - see also: Aircraft.CrewPayload.NON_FLIGHT_CREW_MASS_SCALER Aircraft.CrewPayload.NON_FLIGHT_CREW_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(28,2)', '~WEIGHT.WSTUAB', '~WTSTAT.WSP(28, 2)', '~INERT.WSTUAB'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._cabin_crew_and_bag_weight', - 'aircraft.outputs.L0_weights_summary.cabin_crew_and_bag_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(28,2)', '~WEIGHT.WSTUAB', '~WTSTAT.WSP(28, 2)', '~INERT.WSTUAB'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._cabin_crew_and_bag_weight', + 'aircraft.outputs.L0_weights_summary.cabin_crew_and_bag_weight', + ], + }, units='lbm', desc='total mass of the non-flight crew and their baggage', default_value=None, @@ -838,11 +865,12 @@ add_meta_data( Aircraft.CrewPayload.NON_FLIGHT_CREW_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WSTUAB', 'MISWT.WSTUAB', 'MISWT.OSTUAB'], - "FLOPS": 'WTIN.WSTUAB', - "LEAPS1": 'aircraft.inputs.L0_overrides.cabin_crew_and_bag_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WSTUAB', 'MISWT.WSTUAB', 'MISWT.OSTUAB'], + "FLOPS": 'WTIN.WSTUAB', + "LEAPS1": 'aircraft.inputs.L0_overrides.cabin_crew_and_bag_weight', + }, units='unitless', desc='scaler for total mass of the non-flight crew and their baggage', default_value=1.0, @@ -851,10 +879,11 @@ add_meta_data( Aircraft.CrewPayload.NUM_BUSINESS_CLASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['&DEFINE.WTIN.NPB', 'WTS.NPB'], - "LEAPS1": None, # 'aircraft.inputs.L0_crew_and_payload.business_class_count' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['&DEFINE.WTIN.NPB', 'WTS.NPB'], + "LEAPS1": None, # 'aircraft.inputs.L0_crew_and_payload.business_class_count', + }, units='unitless', desc='number of business class passengers', types=int, @@ -865,10 +894,11 @@ add_meta_data( Aircraft.CrewPayload.NUM_FIRST_CLASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['&DEFINE.WTIN.NPF', 'WTS.NPF'], - "LEAPS1": None, # 'aircraft.inputs.L0_crew_and_payload.first_class_count' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['&DEFINE.WTIN.NPF', 'WTS.NPF'], + "LEAPS1": None, # 'aircraft.inputs.L0_crew_and_payload.first_class_count', + }, units='unitless', desc='number of first class passengers', types=int, @@ -879,12 +909,14 @@ add_meta_data( Aircraft.CrewPayload.NUM_FLIGHT_ATTENDANTS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.NSTU', # ['&DEFINE.WTIN.NSTU', 'WTS.NSTU'], - "LEAPS1": ['aircraft.inputs.L0_crew_and_payload.flight_attendants_count', - 'aircraft.cached.L0_crew_and_payload.flight_attendants_count', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.NSTU', # ['&DEFINE.WTIN.NSTU', 'WTS.NSTU'], + "LEAPS1": [ + 'aircraft.inputs.L0_crew_and_payload.flight_attendants_count', + 'aircraft.cached.L0_crew_and_payload.flight_attendants_count', + ], + }, units='unitless', desc='number of flight attendants', types=int, @@ -895,13 +927,15 @@ add_meta_data( Aircraft.CrewPayload.NUM_FLIGHT_CREW, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.NFLCR', 'WTS.NFLCR', '~WTSTAT.NFLCR'], - "FLOPS": 'WTIN.NFLCR', - "LEAPS1": ['aircraft.inputs.L0_crew_and_payload.flight_crew_count', - 'aircraft.cached.L0_crew_and_payload.flight_crew_count', - ] - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.NFLCR', 'WTS.NFLCR', '~WTSTAT.NFLCR'], + "FLOPS": 'WTIN.NFLCR', + "LEAPS1": [ + 'aircraft.inputs.L0_crew_and_payload.flight_crew_count', + 'aircraft.cached.L0_crew_and_payload.flight_crew_count', + ], + }, units='unitless', desc='number of flight crew', types=int, @@ -912,12 +946,14 @@ add_meta_data( Aircraft.CrewPayload.NUM_GALLEY_CREW, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.NGALC', # ['&DEFINE.WTIN.NGALC', 'WTS.NGALC'], - "LEAPS1": ['aircraft.inputs.L0_crew_and_payload.galley_crew_count', - 'aircraft.cached.L0_crew_and_payload.galley_crew_count', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.NGALC', # ['&DEFINE.WTIN.NGALC', 'WTS.NGALC'], + "LEAPS1": [ + 'aircraft.inputs.L0_crew_and_payload.galley_crew_count', + 'aircraft.cached.L0_crew_and_payload.galley_crew_count', + ], + }, units='unitless', desc='number of galley crew', types=int, @@ -928,10 +964,11 @@ add_meta_data( Aircraft.CrewPayload.NUM_PASSENGERS, meta_data=_MetaData, - historical_name={"GASP": None, # 'INGASP.PAX' here we assume previous studies were changing Design.num_pax not as-flown - "FLOPS": None, # ['CSTDAT.NSV', '~WEIGHT.NPASS', '~WTSTAT.NPASS'], - "LEAPS1": None, # 'aircraft.outputs.L0_crew_and_payload.passenger_count' - }, + historical_name={ + "GASP": None, # 'INGASP.PAX' here we assume previous studies were changing Design.num_pax not as-flown + "FLOPS": None, # ['CSTDAT.NSV', '~WEIGHT.NPASS', '~WTSTAT.NPASS'], + "LEAPS1": None, # 'aircraft.outputs.L0_crew_and_payload.passenger_count', + }, units='unitless', desc='total number of passengers', option=True, @@ -943,10 +980,11 @@ add_meta_data( Aircraft.CrewPayload.NUM_TOURIST_CLASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['&DEFINE.WTIN.NPT', 'WTS.NPT'], - "LEAPS1": None, # 'aircraft.inputs.L0_crew_and_payload.tourist_class_count' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['&DEFINE.WTIN.NPT', 'WTS.NPT'], + "LEAPS1": None, # 'aircraft.inputs.L0_crew_and_payload.tourist_class_count', + }, units='unitless', desc='number of tourist class passengers', types=int, @@ -957,13 +995,15 @@ add_meta_data( Aircraft.CrewPayload.PASSENGER_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(34, 2)', '~WEIGHT.WPASS', '~WTSTAT.WSP(34, 2)', '~INERT.WPASS'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._passenger_weight', - 'aircraft.outputs.L0_weights_summary.passenger_weight' - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(34, 2)', '~WEIGHT.WPASS', '~WTSTAT.WSP(34, 2)', '~INERT.WPASS'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._passenger_weight', + 'aircraft.outputs.L0_weights_summary.passenger_weight', + ], + }, units='lbm', desc='TBD: total mass of all passengers without their baggage', ) @@ -971,10 +1011,7 @@ add_meta_data( Aircraft.CrewPayload.PASSENGER_MASS_WITH_BAGS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.UWPAX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.UWPAX', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of one passenger and their bags', option=True, @@ -991,7 +1028,7 @@ "LEAPS1": None }, units='lbm', - desc='mass of passenger payload, including passengers, passenger baggage' + desc='mass of passenger payload, including passengers, passenger baggage', ) add_meta_data( @@ -999,13 +1036,15 @@ # - see also: Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_SCALER Aircraft.CrewPayload.PASSENGER_SERVICE_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(31, 2)', '~WEIGHT.WSRV', '~WTSTAT.WSP(31, 2)', '~INERT.WSRV'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._passenger_service_weight', - 'aircraft.outputs.L0_weights_summary.passenger_service_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(31, 2)', '~WEIGHT.WSRV', '~WTSTAT.WSP(31, 2)', '~INERT.WSRV'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._passenger_service_weight', + 'aircraft.outputs.L0_weights_summary.passenger_service_weight', + ], + }, units='lbm', desc='mass of passenger service equipment', default_value=None, @@ -1014,10 +1053,7 @@ add_meta_data( Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_PER_PASSENGER, meta_data=_MetaData, - historical_name={"GASP": "INGASP.CW(9)", - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": "INGASP.CW(9)", "FLOPS": None, "LEAPS1": None}, default_value=2.0, units="lbm", desc='mass of passenger service items mass per passenger', @@ -1026,11 +1062,12 @@ add_meta_data( Aircraft.CrewPayload.PASSENGER_SERVICE_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WSRV', 'MISWT.WSRV', 'MISWT.OSRV'], - "FLOPS": 'WTIN.WSRV', - "LEAPS1": 'aircraft.inputs.L0_overrides.passenger_service_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WSRV', 'MISWT.WSRV', 'MISWT.OSRV'], + "FLOPS": 'WTIN.WSRV', + "LEAPS1": 'aircraft.inputs.L0_overrides.passenger_service_weight', + }, units='unitless', desc='scaler for mass of passenger service equipment', default_value=1.0, @@ -1039,21 +1076,15 @@ add_meta_data( Aircraft.CrewPayload.TOTAL_PAYLOAD_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='total mass of payload, including passengers, passenger baggage, and cargo' + desc='total mass of payload, including passengers, passenger baggage, and cargo', ) add_meta_data( Aircraft.CrewPayload.WATER_MASS_PER_OCCUPANT, meta_data=_MetaData, - historical_name={"GASP": "INGASP.CW(10)", - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": "INGASP.CW(10)", "FLOPS": None, "LEAPS1": None}, default_value=1.0, units="lbm", desc='mass of water per occupant (passengers, pilots, and flight attendants)', @@ -1062,10 +1093,11 @@ add_meta_data( Aircraft.CrewPayload.WING_CARGO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.CARGOW', # ['&DEFINE.WTIN.CARGOW', 'WTS.CARGOW'], - "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.wing_cargo' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.CARGOW', # ['&DEFINE.WTIN.CARGOW', 'WTS.CARGOW'], + "LEAPS1": 'aircraft.inputs.L0_crew_and_payload.wing_cargo', + }, units='lbm', desc='cargo carried in wing', default_value=0.0, @@ -1083,55 +1115,53 @@ add_meta_data( Aircraft.Design.BASE_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.SBASE', - # [ # inputs - # '&DEFINE.AERIN.SBASE', 'EDETIN.SBASE', - # # outputs - # 'MISSA.SBASE', 'MISSA.SBASEX', - # ], - "LEAPS1": ['aircraft.inputs.L0_aerodynamics.base_area', - 'aircraft.outputs.L0_aerodynamics.mission_base_area', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.SBASE', + # [ # inputs + # '&DEFINE.AERIN.SBASE', 'EDETIN.SBASE', + # # outputs + # 'MISSA.SBASE', 'MISSA.SBASEX', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_aerodynamics.base_area', + 'aircraft.outputs.L0_aerodynamics.mission_base_area', + ], + }, units='ft**2', desc='Aircraft base area (total exit cross-section area minus inlet ' - 'capture areas for internally mounted engines)', + 'capture areas for internally mounted engines)', default_value=0.0, ) add_meta_data( Aircraft.Design.CG_DELTA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELCG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELCG', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='allowable center-of-gravity (cg) travel as a fraction of ' - 'the mean aerodynamic chord', + 'the mean aerodynamic chord', ) add_meta_data( Aircraft.Design.CHARACTERISTIC_LENGTHS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table', + ], + }, units='ft', - desc='Reynolds characteristic length for each component' + desc='Reynolds characteristic length for each component', ) add_meta_data( Aircraft.Design.COCKPIT_CONTROL_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKCC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKCC', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of cockpit controls', ) @@ -1139,40 +1169,31 @@ add_meta_data( Aircraft.Design.COMPUTE_HTAIL_VOLUME_COEFF, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", option=True, default_value=False, types=bool, desc='if true, use empirical tail volume coefficient equation. This is ' - 'true if VBARHX is 0 in GASP.' + 'true if VBARHX is 0 in GASP.', ) add_meta_data( Aircraft.Design.COMPUTE_VTAIL_VOLUME_COEFF, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", option=True, default_value=False, types=bool, desc='if true, use empirical tail volume coefficient equation. This is ' - 'true if VBARVX is 0 in GASP.' + 'true if VBARVX is 0 in GASP.', ) add_meta_data( Aircraft.Design.DRAG_COEFFICIENT_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELCD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELCD', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='increment to the profile drag coefficient', ) @@ -1180,10 +1201,7 @@ add_meta_data( Aircraft.Design.DRAG_POLAR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='Drag polar computed during Aviary pre-mission.', ) @@ -1191,10 +1209,7 @@ add_meta_data( Aircraft.Design.EMERGENCY_EQUIPMENT_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(11)', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CW(11)', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of emergency equipment', default_value=0.0, @@ -1203,11 +1218,12 @@ add_meta_data( Aircraft.Design.EMPTY_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFMSS.MISSIN.DOWE', '&FLOPS.RERUN.DOWE', 'ESB.DOWE'], - "FLOPS": 'MISSIN.DOWE', - "LEAPS1": 'aircraft.inputs.L0_mission.fixed_operating_weight_empty' - }, + historical_name={ + "GASP": None, + # ['&DEFMSS.MISSIN.DOWE', '&FLOPS.RERUN.DOWE', 'ESB.DOWE'], + "FLOPS": 'MISSIN.DOWE', + "LEAPS1": 'aircraft.inputs.L0_mission.fixed_operating_weight_empty', + }, units='lbm', desc='fixed operating empty mass', default_value=0.0, @@ -1218,10 +1234,11 @@ # - see also: Aircraft.Design.EMPTY_MASS_MARGIN_SCALER Aircraft.Design.EMPTY_MASS_MARGIN, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'DARM.WMARG', - "LEAPS1": '(WeightABC)self._weight_empty_margin' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'DARM.WMARG', + "LEAPS1": '(WeightABC)self._weight_empty_margin', + }, units='lbm', desc='empty mass margin', default_value=None, @@ -1232,10 +1249,11 @@ # discarded Aircraft.Design.EMPTY_MASS_MARGIN_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.EWMARG', # ['&DEFINE.WTIN.EWMARG', 'DARM.EWMARG'], - "LEAPS1": 'aircraft.inputs.L0_overrides.weight_empty_margin' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.EWMARG', # ['&DEFINE.WTIN.EWMARG', 'DARM.EWMARG'], + "LEAPS1": 'aircraft.inputs.L0_overrides.weight_empty_margin', + }, units='unitless', desc='empty mass margin scaler', default_value=0.0, @@ -1243,10 +1261,11 @@ add_meta_data( Aircraft.Design.EXTERNAL_SUBSYSTEMS_MASS, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None, - }, + historical_name={ + "GASP": None, + "FLOPS": None, + "LEAPS1": None, + }, meta_data=_MetaData, units='lbm', desc='total mass of all user-defined external subsystems', @@ -1255,35 +1274,31 @@ add_meta_data( Aircraft.Design.FINENESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.FR', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.FR', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table', + ], + }, units='unitless', - desc='table of component fineness ratios' + desc='table of component fineness ratios', ) add_meta_data( Aircraft.Design.FIXED_EQUIPMENT_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WFE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WFE', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of fixed equipment: APU, Instruments, Hydraulics, Electrical, ' - 'Avionics, AC, Anti-Icing, Auxilary Equipment, and Furnishings', + 'Avionics, AC, Anti-Icing, Auxilary Equipment, and Furnishings', ) add_meta_data( Aircraft.Design.FIXED_USEFUL_LOAD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WFUL', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WFUL', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of fixed useful load: crew, service items, trapped oil, etc', ) @@ -1298,10 +1313,11 @@ add_meta_data( Aircraft.Design.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.TRL', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.mission_component_percent_laminar_flow_lower_surface_table' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.TRL', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.mission_component_percent_laminar_flow_lower_surface_table', + }, units='unitless', desc='table of percent laminar flow over lower component surfaces', default_value=None, @@ -1310,10 +1326,11 @@ add_meta_data( Aircraft.Design.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.TRU', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.mission_component_percent_laminar_flow_upper_surface_table' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.TRU', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.mission_component_percent_laminar_flow_upper_surface_table', + }, units='unitless', desc='table of percent laminar flow over upper component surfaces', default_value=None, @@ -1323,10 +1340,11 @@ # Note user override (no scaling) Aircraft.Design.LANDING_TO_TAKEOFF_MASS_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.WRATIO', # ['&DEFINE.AERIN.WRATIO', 'ESB.WRATIO'], - "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.landing_to_takeoff_weight_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.WRATIO', # ['&DEFINE.AERIN.WRATIO', 'ESB.WRATIO'], + "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.landing_to_takeoff_weight_ratio', + }, units='unitless', desc='ratio of maximum landing mass to maximum takeoff mass', default_value=0.9, @@ -1335,10 +1353,7 @@ add_meta_data( Aircraft.Design.LIFT_CURVE_SLOPE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CLALPH', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CLALPH', "FLOPS": None, "LEAPS1": None}, units="1/rad", desc='lift curve slope at cruise mach number', ) @@ -1346,22 +1361,20 @@ add_meta_data( Aircraft.Design.LIFT_DEPENDENT_DRAG_COEFF_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'MISSIN.FCDI', # '~DRGFCT.FCDI', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.induced_drag_coeff_fact' - }, + historical_name={ + "GASP": None, + "FLOPS": 'MISSIN.FCDI', # '~DRGFCT.FCDI', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.induced_drag_coeff_fact', + }, units='unitless', default_value=1.0, - desc='Scaling factor for lift-dependent drag coefficient' + desc='Scaling factor for lift-dependent drag coefficient', ) add_meta_data( Aircraft.Design.LIFT_POLAR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='Lift polar computed during Aviary pre-mission.', ) @@ -1369,10 +1382,7 @@ add_meta_data( Aircraft.Design.MAX_FUSELAGE_PITCH_ANGLE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.THEMAX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.THEMAX', "FLOPS": None, "LEAPS1": None}, units='deg', desc='maximum fuselage pitch allowed', default_value=15, @@ -1381,10 +1391,7 @@ add_meta_data( Aircraft.Design.MAX_STRUCTURAL_SPEED, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.VMLFSL', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.VMLFSL', "FLOPS": None, "LEAPS1": None}, units='mi/h', desc='maximum structural design flight speed in miles per hour', default_value=0, @@ -1395,24 +1402,23 @@ meta_data=_MetaData, # TODO: check with Aviary and GASPy engineers to ensure these are indeed # defined the same way - historical_name={"GASP": 'INGASP.OWE', - # ['WTS.WSP(33, 2)', '~WEIGHT.WOWE', '~WTSTAT.WSP(33, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._operating_weight_empty', - 'aircraft.outputs.L0_weights_summary.operating_weight_empty', - ] - }, + historical_name={ + "GASP": 'INGASP.OWE', + # ['WTS.WSP(33, 2)', '~WEIGHT.WOWE', '~WTSTAT.WSP(33, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._operating_weight_empty', + 'aircraft.outputs.L0_weights_summary.operating_weight_empty', + ], + }, units='lbm', - desc='operating mass empty of the aircraft' + desc='operating mass empty of the aircraft', ) add_meta_data( Aircraft.Design.PART25_STRUCTURAL_CATEGORY, meta_data=_MetaData, - historical_name={"GASP": "INGASP.CATD", - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": "INGASP.CATD", "FLOPS": None, "LEAPS1": None}, option=True, default_value=3, types=int, @@ -1423,10 +1429,7 @@ add_meta_data( Aircraft.Design.RESERVE_FUEL_ADDITIONAL, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FRESF', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FRESF', "FLOPS": None, "LEAPS1": None}, option=True, units="lbm", desc='required fuel reserves: directly in lbm', @@ -1447,10 +1450,7 @@ add_meta_data( Aircraft.Design.SMOOTH_MASS_DISCONTINUITIES, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, option=True, default_value=False, types=bool, @@ -1461,10 +1461,7 @@ add_meta_data( Aircraft.Design.STATIC_MARGIN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.STATIC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.STATIC', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='aircraft static margin as a fraction of mean aerodynamic chord', ) @@ -1472,10 +1469,7 @@ add_meta_data( Aircraft.Design.STRUCTURAL_MASS_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELWST', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELWST', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='structural mass increment that is added (or removed) after the structural mass is calculated', default_value=0, @@ -1484,65 +1478,67 @@ add_meta_data( Aircraft.Design.STRUCTURE_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(9, 2)', '~WEIGHT.WSTRCT', '~WTSTAT.WSP(9, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._total_structural_weight', - 'aircraft.outputs.L0_weights_summary.total_structural_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(9, 2)', '~WEIGHT.WSTRCT', '~WTSTAT.WSP(9, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._total_structural_weight', + 'aircraft.outputs.L0_weights_summary.total_structural_weight', + ], + }, units='lbm', - desc='Total structural group mass' + desc='Total structural group mass', ) add_meta_data( Aircraft.Design.SUBSONIC_DRAG_COEFF_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'MISSIN.FCDSUB', # '~DRGFCT.FCDSUB', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.sub_drag_coeff_fact' - }, + historical_name={ + "GASP": None, + "FLOPS": 'MISSIN.FCDSUB', # '~DRGFCT.FCDSUB', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.sub_drag_coeff_fact', + }, units='unitless', default_value=1.0, - desc='Scaling factor for subsonic drag' + desc='Scaling factor for subsonic drag', ) add_meta_data( Aircraft.Design.SUPERCRITICAL_DIVERGENCE_SHIFT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SCFAC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SCFAC', "FLOPS": None, "LEAPS1": None}, units='unitless', - desc='shift in drag divergence Mach number due to ' - 'supercritical design', + desc='shift in drag divergence Mach number due to ' 'supercritical design', ) add_meta_data( Aircraft.Design.SUPERSONIC_DRAG_COEFF_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'MISSIN.FCDSUP', # '~DRGFCT.FCDSUP', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.sup_drag_coeff_fact' - }, + historical_name={ + "GASP": None, + "FLOPS": 'MISSIN.FCDSUP', # '~DRGFCT.FCDSUP', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.sup_drag_coeff_fact', + }, units='unitless', default_value=1.0, - desc='Scaling factor for supersonic drag' + desc='Scaling factor for supersonic drag', ) add_meta_data( Aircraft.Design.SYSTEMS_EQUIP_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(25, 2)', '~WEIGHT.WSYS', '~WTSTAT.WSP(25, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._equipment_group_weight', - 'aircraft.outputs.L0_weights_summary.equipment_group_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(25, 2)', '~WEIGHT.WSYS', '~WTSTAT.WSP(25, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._equipment_group_weight', + 'aircraft.outputs.L0_weights_summary.equipment_group_weight', + ], + }, units='lbm', - desc='Total systems & equipment group mass' + desc='Total systems & equipment group mass', ) add_meta_data( @@ -1551,52 +1547,52 @@ # value during calculations; in Aviary, these must be separate variables Aircraft.Design.SYSTEMS_EQUIP_MASS_BASE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='Total systems & equipment group mass without additional 1% of ' - 'empty mass' + desc='Total systems & equipment group mass without additional 1% of ' 'empty mass', ) add_meta_data( Aircraft.Design.THRUST_TO_WEIGHT_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'CONFIN.TWR', - "LEAPS1": 'ipropulsion.req_thrust_weight_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'CONFIN.TWR', + "LEAPS1": 'ipropulsion.req_thrust_weight_ratio', + }, units='unitless', - desc='required thrust-to-weight ratio of aircraft' + desc='required thrust-to-weight ratio of aircraft', ) add_meta_data( Aircraft.Design.TOTAL_WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.TWET', - "LEAPS1": '~WeightABC._update_cycle.total_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.TWET', + "LEAPS1": '~WeightABC._update_cycle.total_wetted_area', + }, units='ft**2', - desc='total aircraft wetted area' + desc='total aircraft wetted area', ) add_meta_data( # NOTE: user override (no scaling) Aircraft.Design.TOUCHDOWN_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.WLDG', - # [ # inputs - # '&DEFINE.WTIN.WLDG', 'WTS.WLDG', - # # outputs - # 'CMODLW.WLDGO', - # ], - "LEAPS1": ['aircraft.inputs.L0_landing_gear.design_landing_weight', - 'aircraft.outputs.L0_landing_gear.design_landing_weight', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.WLDG', + # [ # inputs + # '&DEFINE.WTIN.WLDG', 'WTS.WLDG', + # # outputs + # 'CMODLW.WLDGO', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_landing_gear.design_landing_weight', + 'aircraft.outputs.L0_landing_gear.design_landing_weight', + ], + }, units='lbm', desc='design landing mass', default_value=None, @@ -1605,26 +1601,24 @@ add_meta_data( Aircraft.Design.ULF_CALCULATED_FROM_MANEUVER, meta_data=_MetaData, - historical_name={"GASP": 'CATD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'CATD', "FLOPS": None, "LEAPS1": None}, option=True, default_value=False, types=bool, units="unitless", desc='if true, ULF (ultimate load factor) is forced to be calculated from ' - 'the maneuver load factor, even if the gust load factor is larger. ' - 'This was set to true with a negative CATD in GASP.' + 'the maneuver load factor, even if the gust load factor is larger. ' + 'This was set to true with a negative CATD in GASP.', ) add_meta_data( Aircraft.Design.USE_ALT_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.IALTWT', - "LEAPS1": 'aircraft.inputs.L0_weights.use_alt_weights' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.IALTWT', + "LEAPS1": 'aircraft.inputs.L0_weights.use_alt_weights', + }, units='unitless', desc='control whether the alternate mass equations are to be used or not', option=True, @@ -1635,41 +1629,46 @@ add_meta_data( Aircraft.Design.WETTED_AREAS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.SWET', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table', - 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.SWET', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table', + 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table', + ], + }, units='ft**2', - desc='table of component wetted areas' + desc='table of component wetted areas', ) add_meta_data( Aircraft.Design.ZERO_FUEL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(37,2)', '~WEIGHT.WZF', '~WTSTAT.WSP(37,2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._zero_fuel_weight', - 'aircraft.outputs.L0_weights.zero_fuel_weight', - 'aircraft.outputs.L0_weights_summary.zero_fuel_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(37,2)', '~WEIGHT.WZF', '~WTSTAT.WSP(37,2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._zero_fuel_weight', + 'aircraft.outputs.L0_weights.zero_fuel_weight', + 'aircraft.outputs.L0_weights_summary.zero_fuel_weight', + ], + }, units='lbm', - desc='zero fuel mass' + desc='zero fuel mass', ) add_meta_data( Aircraft.Design.ZERO_LIFT_DRAG_COEFF_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'MISSIN.FCDO', # '~DRGFCT.FCDO', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.geom_drag_coeff_fact' - }, + historical_name={ + "GASP": None, + "FLOPS": 'MISSIN.FCDO', # '~DRGFCT.FCDO', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.geom_drag_coeff_fact', + }, units='unitless', default_value=1.0, - desc='Scaling factor for zero-lift drag coefficient' + desc='Scaling factor for zero-lift drag coefficient', ) # @@ -1684,10 +1683,7 @@ add_meta_data( Aircraft.Electrical.HAS_HYBRID_SYSTEM, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", option=True, default_value=True, @@ -1698,10 +1694,7 @@ add_meta_data( Aircraft.Electrical.HYBRID_CABLE_LENGTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.LCABLE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.LCABLE', "FLOPS": None, "LEAPS1": None}, units='ft', desc='length of cable for hybrid electric augmented system', ) @@ -1711,13 +1704,15 @@ # - see also: Aircraft.Electrical.MASS_SCALER Aircraft.Electrical.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(20, 2)', '~WEIGHT.WELEC', '~WTSTAT.WSP(20, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._electrical_group_weight', - 'aircraft.outputs.L0_weights_summary.electrical_group_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(20, 2)', '~WEIGHT.WELEC', '~WTSTAT.WSP(20, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._electrical_group_weight', + 'aircraft.outputs.L0_weights_summary.electrical_group_weight', + ], + }, units='lbm', desc='mass of the electrical system', default_value=None, @@ -1726,11 +1721,12 @@ add_meta_data( Aircraft.Electrical.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WELEC', 'MISWT.WELEC', 'MISWT.OELEC'], - "FLOPS": 'WTIN.WELEC', - "LEAPS1": 'aircraft.inputs.L0_overrides.electrical_group_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WELEC', 'MISWT.WELEC', 'MISWT.OELEC'], + "FLOPS": 'WTIN.WELEC', + "LEAPS1": 'aircraft.inputs.L0_overrides.electrical_group_weight', + }, units='unitless', desc='mass scaler for the electrical system', default_value=1.0, @@ -1751,85 +1747,65 @@ add_meta_data( Aircraft.Engine.ADDITIONAL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='additional propulsion system mass added to engine control and starter mass, or ' - 'engine installation mass', - default_value=0.0 + 'engine installation mass', + default_value=0.0, ) add_meta_data( Aircraft.Engine.ADDITIONAL_MASS_FRACTION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKPEI', - "FLOPS": 'WTIN.WPMISC', # ['&DEFINE.WTIN.WPMISC', 'FAWT.WPMISC'], - "LEAPS1": 'aircraft.inputs.L0_propulsion.misc_weight' - }, + historical_name={ + "GASP": 'INGASP.SKPEI', + "FLOPS": 'WTIN.WPMISC', # ['&DEFINE.WTIN.WPMISC', 'FAWT.WPMISC'], + "LEAPS1": 'aircraft.inputs.L0_propulsion.misc_weight', + }, units='unitless', 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', default_value=0.0, ) -# NOTE if FT < 0, this bool is true, if >= 0, this is false and the value of FT is used -# as the installation loss factor -add_meta_data( - Aircraft.Engine.COMPUTE_PROPELLER_INSTALLATION_LOSS, - meta_data=_MetaData, - historical_name={"GASP": 'INPROP.FT', - "FLOPS": None, - "LEAPS1": None - }, - units="unitless", - option=True, - default_value=True, - types=bool, - desc='if true, compute installation loss factor based on blockage factor', -) - add_meta_data( Aircraft.Engine.CONSTANT_FUEL_CONSUMPTION, meta_data=_MetaData, historical_name={ "GASP": None, "FLOPS": 'MISSIN.FLEAK', - "LEAPS1": [ - 'iengine.fuel_leak', - 'aircraft.inputs.L0_engine.fuel_leak']}, + "LEAPS1": ['iengine.fuel_leak', 'aircraft.inputs.L0_engine.fuel_leak'], + }, option=True, units='lbm/h', desc='Additional constant fuel flow. This value is not scaled with the engine', - default_value=0.0) + default_value=0.0, +) add_meta_data( Aircraft.Engine.CONTROLS_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.WEC', - "LEAPS1": '(WeightABC)self._engine_ctrl_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.WEC', + "LEAPS1": '(WeightABC)self._engine_ctrl_weight', + }, units='lbm', desc='estimated mass of the engine controls', - default_value=0.0 + default_value=0.0, ) # TODO there should be a GASP name that pairs here add_meta_data( Aircraft.Engine.DATA_FILE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": "ENGDIN.EIFILE", - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": "ENGDIN.EIFILE", "LEAPS1": None}, units='unitless', types=(str, Path), default_value=None, option=True, - desc='filepath to data file containing engine performance tables' + desc='filepath to data file containing engine performance tables', ) add_meta_data( @@ -1846,107 +1822,110 @@ add_meta_data( Aircraft.Engine.FLIGHT_IDLE_MAX_FRACTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.FIDMAX', - "LEAPS1": 'aircraft.L0_fuel_flow.idle_max_fract' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.FIDMAX', + "LEAPS1": 'aircraft.L0_fuel_flow.idle_max_fract', + }, units="unitless", option=True, default_value=1.0, desc='If Aircraft.Engine.GENERATE_FLIGHT_IDLE is True, bounds engine ' - 'performance outputs (other than thrust) at flight idle to be below a ' - 'decimal fraction of the max value of that output produced by the engine ' - 'at each flight condition.' + 'performance outputs (other than thrust) at flight idle to be below a ' + 'decimal fraction of the max value of that output produced by the engine ' + 'at each flight condition.', ) add_meta_data( Aircraft.Engine.FLIGHT_IDLE_MIN_FRACTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.FIDMIN', - "LEAPS1": 'aircraft.L0_fuel_flow.idle_min_fract' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.FIDMIN', + "LEAPS1": 'aircraft.L0_fuel_flow.idle_min_fract', + }, units="unitless", option=True, default_value=0.08, desc='If Aircraft.Engine.GENERATE_FLIGHT_IDLE is True, bounds engine ' - 'performance outputs (other than thrust) at flight idle to be above a ' - 'decimal fraction of the max value of that output produced by the engine ' - 'at each flight condition.' + 'performance outputs (other than thrust) at flight idle to be above a ' + 'decimal fraction of the max value of that output produced by the engine ' + 'at each flight condition.', ) add_meta_data( Aircraft.Engine.FLIGHT_IDLE_THRUST_FRACTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", option=True, default_value=0.0, desc='If Aircraft.Engine.GENERATE_FLIGHT_IDLE is True, defines idle thrust ' - 'condition as a decimal fraction of max thrust produced by the engine at each ' - 'flight condition.' + 'condition as a decimal fraction of max thrust produced by the engine at each ' + 'flight condition.', ) add_meta_data( Aircraft.Engine.FUEL_FLOW_SCALER_CONSTANT_TERM, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.DFFAC', - "LEAPS1": 'ifuel_flow.scaling_const_term' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.DFFAC', + "LEAPS1": 'ifuel_flow.scaling_const_term', + }, units='unitless', option=True, desc='Constant term in fuel flow scaling equation', - default_value=0.0 + default_value=0.0, ) add_meta_data( Aircraft.Engine.FUEL_FLOW_SCALER_LINEAR_TERM, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.FFFAC', - "LEAPS1": 'ifuel_flow.scaling_linear_term' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.FFFAC', + "LEAPS1": 'ifuel_flow.scaling_linear_term', + }, units='unitless', desc='Linear term in fuel flow scaling equation', default_value=0.0, - option=True + option=True, ) add_meta_data( Aircraft.Engine.GENERATE_FLIGHT_IDLE, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.IDLE', - "LEAPS1": 'engine_model.imodel_info.flight_idle_index' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.IDLE', + "LEAPS1": 'engine_model.imodel_info.flight_idle_index', + }, meta_data=_MetaData, units="unitless", option=True, default_value=False, types=bool, desc='If True, generate flight idle data by extrapolating from engine deck. Flight ' - 'idle is defined as engine performance when thrust is reduced to the level ' - 'defined by Aircraft.Engine.FLIGHT_IDLE_THRUST_FRACTION. Engine outputs are ' - 'extrapolated to this thrust level, bounded by ' - 'Aircraft.Engine.FLIGHT_IDLE_MIN_FRACT and Aircraft.Engine.FLIGHT_IDLE_MIN_FRACT' + 'idle is defined as engine performance when thrust is reduced to the level ' + 'defined by Aircraft.Engine.FLIGHT_IDLE_THRUST_FRACTION. Engine outputs are ' + 'extrapolated to this thrust level, bounded by ' + 'Aircraft.Engine.FLIGHT_IDLE_MIN_FRACT and Aircraft.Engine.FLIGHT_IDLE_MIN_FRACT', ) add_meta_data( Aircraft.Engine.GEOPOTENTIAL_ALT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.IGEO', - "LEAPS1": 'imodel_info.geopotential_alt' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.IGEO', + "LEAPS1": 'imodel_info.geopotential_alt', + }, units='unitless', option=True, desc='If True, engine deck altitudes are geopotential and will be converted to ' - 'geometric altitudes. If False, engine deck altitudes are geometric.', + 'geometric altitudes. If False, engine deck altitudes are geometric.', types=bool, - default_value=False + default_value=False, ) # Global hybrid throttle is also False by default to account for parallel-hybrid engines @@ -1999,16 +1978,17 @@ add_meta_data( Aircraft.Engine.IGNORE_NEGATIVE_THRUST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.NONEG', - "LEAPS1": 'imodel_info.ignore_negative_thrust' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.NONEG', + "LEAPS1": 'imodel_info.ignore_negative_thrust', + }, option=True, units="unitless", default_value=False, types=bool, desc='If False, all input or generated points are used, otherwise points in the ' - 'engine deck with negative net thrust are ignored.' + 'engine deck with negative net thrust are ignored.', ) add_meta_data( @@ -2021,23 +2001,25 @@ add_meta_data( Aircraft.Engine.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['WTS.WSP(10, 2)', '~WTSTAT.WSP(10, 2)'], - "LEAPS1": 'aircraft.outputs.L0_weights_summary.Engine.WEIGHT' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['WTS.WSP(10, 2)', '~WTSTAT.WSP(10, 2)'], + "LEAPS1": 'aircraft.outputs.L0_weights_summary.Engine.WEIGHT', + }, units='lbm', desc='scaled mass of a single engine or bare engine if inlet and nozzle mass are ' - 'supplied', - default_value=0.0 + 'supplied', + default_value=0.0, ) add_meta_data( Aircraft.Engine.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CK5', - "FLOPS": 'WTIN.EEXP', # '~WEIGHT.EEXP', - "LEAPS1": 'aircraft.inputs.L0_propulsion.engine_weight_scale' - }, + historical_name={ + "GASP": 'INGASP.CK5', + "FLOPS": 'WTIN.EEXP', # '~WEIGHT.EEXP', + "LEAPS1": 'aircraft.inputs.L0_propulsion.engine_weight_scale', + }, units='unitless', desc='scaler for engine mass', default_value=0.0, @@ -2046,10 +2028,7 @@ add_meta_data( Aircraft.Engine.MASS_SPECIFIC, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SWSLS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SWSLS', "FLOPS": None, "LEAPS1": None}, units="lbm/lbf", desc='specific mass of one engine (engine weight/SLS thrust)', default_value=0.0, @@ -2058,80 +2037,67 @@ add_meta_data( Aircraft.Engine.NUM_ENGINES, meta_data=_MetaData, - historical_name={"GASP": "INGASP.ENP", - "FLOPS": None, # ['~ANALYS.NENG', 'LANDG.XENG', ], - "LEAPS1": 'aircraft.outputs.L0_propulsion.total_engine_count' - }, + historical_name={ + "GASP": "INGASP.ENP", + "FLOPS": None, # ['~ANALYS.NENG', 'LANDG.XENG', ], + "LEAPS1": 'aircraft.outputs.L0_propulsion.total_engine_count', + }, units='unitless', desc='total number of engines per model on the aircraft ' - '(fuselage, wing, or otherwise)', + '(fuselage, wing, or otherwise)', types=int, option=True, - default_value=2 + default_value=2, ) add_meta_data( Aircraft.Engine.NUM_FUSELAGE_ENGINES, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.NEF', # ['&DEFINE.WTIN.NEF', 'EDETIN.NEF'], - "LEAPS1": 'aircraft.inputs.L0_fuselage.engines_count' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.NEF', # ['&DEFINE.WTIN.NEF', 'EDETIN.NEF'], + "LEAPS1": 'aircraft.inputs.L0_fuselage.engines_count', + }, units='unitless', desc='number of fuselage mounted engines per model', option=True, types=int, - default_value=0 -) - -add_meta_data( - Aircraft.Engine.NUM_PROPELLER_BLADES, - meta_data=_MetaData, - historical_name={"GASP": 'INPROP.BL', - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - desc='number of blades per propeller', - option=True, - types=int, - default_value=0 + default_value=0, ) add_meta_data( Aircraft.Engine.NUM_WING_ENGINES, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.NEW', 'EDETIN.NEW', '~WWGHT.NEW'], - "FLOPS": 'WTIN.NEW', - "LEAPS1": 'aircraft.inputs.L0_wing.engines_count' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.NEW', 'EDETIN.NEW', '~WWGHT.NEW'], + "FLOPS": 'WTIN.NEW', + "LEAPS1": 'aircraft.inputs.L0_wing.engines_count', + }, units='unitless', desc='number of wing mounted engines per model', option=True, types=int, - default_value=0 + default_value=0, ) add_meta_data( Aircraft.Engine.POD_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['~WEIGHT.WPOD', '~WWGHT.WPOD'], - "LEAPS1": '(WeightABC)self._engine_pod_weight_list' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['~WEIGHT.WPOD', '~WWGHT.WPOD'], + "LEAPS1": '(WeightABC)self._engine_pod_weight_list', + }, units='lbm', desc='engine pod mass including nacelles', - default_value=0.0 + default_value=0.0, ) add_meta_data( Aircraft.Engine.POD_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CK14', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CK14', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='technology factor on mass of engine pods', default_value=1.0, @@ -2140,177 +2106,93 @@ add_meta_data( Aircraft.Engine.POSITION_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKEPOS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKEPOS', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='engine position factor', default_value=0, ) add_meta_data( - Aircraft.Engine.PROPELLER_ACTIVITY_FACTOR, + Aircraft.Engine.PYLON_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INPROP.AF', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FPYL', "FLOPS": None, "LEAPS1": None}, units="unitless", - desc='propeller actitivty factor per Blade (Range: 80 to 200)', - default_value=0.0, + desc='factor for turbofan engine pylon mass', + default_value=0.7, ) add_meta_data( - Aircraft.Engine.PROPELLER_DATA_FILE, + Aircraft.Engine.REFERENCE_DIAMETER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - types=(str, Path), - default_value=None, - option=True, - desc='filepath to data file containing propeller data map', + historical_name={"GASP": 'INGASP.DIAM_REF', "FLOPS": None, "LEAPS1": None}, + units='ft', + desc='engine reference diameter', + default_value=0.0, ) +# NOTE This unscaled turbine (engine) weight is an input provided by the user, and is not +# an override. It is scaled by Aircraft.Engine.SCALE_FACTOR (a calculated value) to +# produce Aircraft.Engine.MASS add_meta_data( - Aircraft.Engine.PROPELLER_DIAMETER, + Aircraft.Engine.REFERENCE_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INPROP.DPROP', - "FLOPS": None, - "LEAPS1": None - }, - units='ft', - desc='propeller diameter', - default_value=0.0, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.WENG', # '~WEIGHT.WENG', + "LEAPS1": '(WeightABC)self._Engine.WEIGHT', + }, + units='lbm', + desc='unscaled mass of a single engine or bare engine if inlet and nozzle mass ' + 'are supplied', + default_value=None, + option=True, ) add_meta_data( - Aircraft.Engine.PROPELLER_INTEGRATED_LIFT_COEFFICIENT, + Aircraft.Engine.REFERENCE_SLS_THRUST, meta_data=_MetaData, - historical_name={"GASP": 'INPROP.CLI', - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - desc='propeller blade integrated design lift coefficient (Range: 0.3 to 0.8)', - default_value=0.5, + historical_name={ + "GASP": 'INGASP.FN_REF', + "FLOPS": 'WTIN.THRSO', + "LEAPS1": 'aircraft.inputs.L0_engine*.thrust', + }, + units='lbf', + desc='maximum thrust of an engine provided in engine model files', + default_value=None, + option=True, ) add_meta_data( - Aircraft.Engine.PROPELLER_TIP_MACH_MAX, + Aircraft.Engine.RPM_DESIGN, meta_data=_MetaData, historical_name={ - "GASP": None, # TODO this needs verification + "GASP": 'INPROP.XNMAX', # maximum engine speed, rpm "FLOPS": None, "LEAPS1": None, }, + units='rpm', + desc='the designed output RPM from the engine for fixed-RPM shafts', + default_value=None, +) + +add_meta_data( + Aircraft.Engine.SCALE_FACTOR, + meta_data=_MetaData, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', - desc='maximum allowable Mach number at propeller tip (based on helical speed)', + desc='Thrust-based scaling factor used to scale engine performance data during ' + 'mission analysis', default_value=1.0, ) add_meta_data( - Aircraft.Engine.PROPELLER_TIP_SPEED_MAX, + Aircraft.Engine.SCALE_MASS, meta_data=_MetaData, historical_name={ - "GASP": ['INPROP.TSPDMX', 'INPROP.TPSPDMXe'], + "GASP": None, "FLOPS": None, - "LEAPS1": None, + "LEAPS1": '(types)EngineScaleModes.WEIGHT', }, - units='ft/s', - desc='maximum allowable linear propeller tip speed due to rotation', - default_value=800.0, -) - -add_meta_data( - Aircraft.Engine.PYLON_FACTOR, - meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FPYL', - "FLOPS": None, - "LEAPS1": None - }, - units="unitless", - desc='factor for turbofan engine pylon mass', - default_value=.7 -) - -add_meta_data( - Aircraft.Engine.REFERENCE_DIAMETER, - meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DIAM_REF', - "FLOPS": None, - "LEAPS1": None - }, - units='ft', - desc='engine reference diameter', - default_value=0.0 -) - -# NOTE This unscaled turbine (engine) weight is an input provided by the user, and is not -# an override. It is scaled by Aircraft.Engine.SCALE_FACTOR (a calculated value) to -# produce Aircraft.Engine.MASS -add_meta_data( - Aircraft.Engine.REFERENCE_MASS, - meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.WENG', # '~WEIGHT.WENG', - "LEAPS1": '(WeightABC)self._Engine.WEIGHT' - }, - units='lbm', - desc='unscaled mass of a single engine or bare engine if inlet and nozzle mass ' - 'are supplied', - default_value=None, - option=True, -) - -add_meta_data( - Aircraft.Engine.REFERENCE_SLS_THRUST, - meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FN_REF', - "FLOPS": 'WTIN.THRSO', - "LEAPS1": 'aircraft.inputs.L0_engine*.thrust' - }, - units='lbf', - desc='maximum thrust of an engine provided in engine model files', - default_value=None, - option=True -) - -add_meta_data( - Aircraft.Engine.RPM_DESIGN, - meta_data=_MetaData, - historical_name={"GASP": 'INPROP.XNMAX', # maximum engine speed, rpm - "FLOPS": None, - "LEAPS1": None - }, - units='rpm', - desc='the designed output RPM from the engine for fixed-RPM shafts', - default_value=None, -) - -add_meta_data( - Aircraft.Engine.SCALE_FACTOR, - meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - desc='Thrust-based scaling factor used to scale engine performance data during ' - 'mission analysis', - default_value=1.0 -) - -add_meta_data( - Aircraft.Engine.SCALE_MASS, - meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": '(types)EngineScaleModes.WEIGHT' - }, desc='Toggle for enabling scaling of engine mass', option=True, types=bool, @@ -2320,14 +2202,16 @@ add_meta_data( Aircraft.Engine.SCALE_PERFORMANCE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": ['iengine.scale_mode', - '(types)EngineScaleModes.DEFAULT', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, + "LEAPS1": [ + 'iengine.scale_mode', + '(types)EngineScaleModes.DEFAULT', + ], + }, desc='Toggle for enabling scaling of engine performance including thrust, fuel flow, ' - 'and electric power', + 'and electric power', option=True, types=bool, default_value=True, @@ -2336,12 +2220,14 @@ add_meta_data( Aircraft.Engine.SCALED_SLS_THRUST, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.THIN', - "FLOPS": 'CONFIN.THRUST', - "LEAPS1": ['aircraft.outputs.L0_propulsion.max_rated_thrust', - 'aircraft.cached.L0_propulsion.max_rated_thrust', - ] - }, + historical_name={ + "GASP": 'INGASP.THIN', + "FLOPS": 'CONFIN.THRUST', + "LEAPS1": [ + 'aircraft.outputs.L0_propulsion.max_rated_thrust', + 'aircraft.cached.L0_propulsion.max_rated_thrust', + ], + }, units='lbf', desc='maximum thrust of an engine after scaling', default_value=0.0, @@ -2350,39 +2236,42 @@ add_meta_data( Aircraft.Engine.STARTER_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.WSTART', - "LEAPS1": '(WeightABC)self._starter_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.WSTART', + "LEAPS1": '(WeightABC)self._starter_weight', + }, units='lbm', desc='starter mass', - default_value=0.0 + default_value=0.0, ) add_meta_data( Aircraft.Engine.SUBSONIC_FUEL_FLOW_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.FFFSUB', - "LEAPS1": 'aircraft.L0_fuel_flow.subsonic_factor' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.FFFSUB', + "LEAPS1": 'aircraft.L0_fuel_flow.subsonic_factor', + }, units='unitless', desc='scaling factor on fuel flow when Mach number is subsonic', default_value=1.0, - option=True + option=True, ) add_meta_data( Aircraft.Engine.SUPERSONIC_FUEL_FLOW_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'ENGDIN.FFFSUP', - "LEAPS1": 'aircraft.L0_fuel_flow.supersonic_factor' - }, + historical_name={ + "GASP": None, + "FLOPS": 'ENGDIN.FFFSUP', + "LEAPS1": 'aircraft.L0_fuel_flow.supersonic_factor', + }, units='unitless', desc='scaling factor on fuel flow when Mach number is supersonic', default_value=1.0, - option=True + option=True, ) add_meta_data( @@ -2390,13 +2279,15 @@ # - see also: Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER Aircraft.Engine.THRUST_REVERSERS_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(11, 2)', '~WEIGHT.WTHR', '~WTSTAT.WSP(11, 2)', '~INERT.WTHR'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._thrust_reversers_weight', - 'aircraft.outputs.L0_weights_summary.thrust_reversers_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(11, 2)', '~WEIGHT.WTHR', '~WTSTAT.WSP(11, 2)', '~INERT.WTHR'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._thrust_reversers_weight', + 'aircraft.outputs.L0_weights_summary.thrust_reversers_weight', + ], + }, units='lbm', desc='mass of thrust reversers on engines', default_value=0.0, @@ -2407,11 +2298,12 @@ # discarded Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WTHR', 'MISWT.WTHR', 'MISWT.OTHR'], - "FLOPS": 'WTIN.WTHR', - "LEAPS1": 'aircraft.inputs.L0_overrides.thrust_reversers_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WTHR', 'MISWT.WTHR', 'MISWT.OTHR'], + "FLOPS": 'WTIN.WTHR', + "LEAPS1": 'aircraft.inputs.L0_overrides.thrust_reversers_weight', + }, units='unitless', desc='scaler for mass of thrust reversers on engines', default_value=0.0, # FLOPS/LEAPS1 default value @@ -2420,42 +2312,26 @@ add_meta_data( Aircraft.Engine.TYPE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.NTYE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.NTYE', "FLOPS": None, "LEAPS1": None}, option=True, default_value=GASPEngineType.TURBOJET, types=GASPEngineType, units="unitless", - desc='specifies engine type used for engine mass calculation', -) - -add_meta_data( - Aircraft.Engine.USE_PROPELLER_MAP, - meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - option=True, - default_value=False, - types=bool, - units="unitless", - desc='flag whether to use propeller map or Hamilton-Standard model.' + desc='specifies engine type used for GASP-based engine mass calculation', ) add_meta_data( Aircraft.Engine.WING_LOCATIONS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.YP', - "FLOPS": 'WTIN.ETAE', # ['&DEFINE.WTIN.ETAE', 'WDEF.ETAE'], - "LEAPS1": 'aircraft.inputs.L0_propulsion.wing_engine_locations' - }, + historical_name={ + "GASP": 'INGASP.YP', + "FLOPS": 'WTIN.ETAE', # ['&DEFINE.WTIN.ETAE', 'WDEF.ETAE'], + "LEAPS1": 'aircraft.inputs.L0_propulsion.wing_engine_locations', + }, units='unitless', desc='Engine wing mount locations as fractions of semispan; (NUM_WING_ENGINES)/2 values ' - 'are input', - default_value=np.array([0.0]) + 'are input', + default_value=np.array([0.0]), ) # ___ _ @@ -2467,20 +2343,15 @@ add_meta_data( Aircraft.Engine.Gearbox.EFFICIENCY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='The efficiency of the gearbox.', - default_value=0.98, + default_value=1.0, ) add_meta_data( Aircraft.Engine.Gearbox.GEAR_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, # 1 / INPROP.GR - "FLOPS": None, - "LEAPS1": None}, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, # 1 / INPROP.GR units='unitless', desc='Reduction gear ratio, or the ratio of the RPM_in divided by the RPM_out for the gearbox.', default_value=1.0, @@ -2506,7 +2377,6 @@ units='hp', desc='A guess for the maximum power that will be transmitted through the gearbox during the mission (max shp input).', default_value=1.0, - option=True, ) add_meta_data( @@ -2542,6 +2412,115 @@ 'motor mass in pre-mission', ) +# ___ _ _ +# | _ \ _ _ ___ _ __ ___ | | | | ___ _ _ +# | _/ | '_| / _ \ | '_ \ / -_) | | | | / -_) | '_| +# |_| |_| \___/ | .__/ \___| |_| |_| \___| |_| +# |_| +# =================================================== + +add_meta_data( + Aircraft.Engine.Propeller.ACTIVITY_FACTOR, + meta_data=_MetaData, + historical_name={"GASP": 'INPROP.AF', "FLOPS": None, "LEAPS1": None}, + units="unitless", + desc='propeller actitivty factor per Blade (Range: 80 to 200)', + default_value=0.0, +) + +# NOTE if FT < 0, this bool is true, if >= 0, this is false and the value of FT is used +# as the installation loss factor +add_meta_data( + Aircraft.Engine.Propeller.COMPUTE_INSTALLATION_LOSS, + meta_data=_MetaData, + historical_name={"GASP": 'INPROP.FT', "FLOPS": None, "LEAPS1": None}, + units="unitless", + option=True, + default_value=True, + types=bool, + desc='if true, compute installation loss factor based on blockage factor', +) + +add_meta_data( + Aircraft.Engine.Propeller.DATA_FILE, + meta_data=_MetaData, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='unitless', + types=(str, Path), + default_value=None, + option=True, + desc='filepath to data file containing propeller data map', +) + +add_meta_data( + Aircraft.Engine.Propeller.DIAMETER, + meta_data=_MetaData, + historical_name={"GASP": 'INPROP.DPROP', "FLOPS": None, "LEAPS1": None}, + units='ft', + desc='propeller diameter', + default_value=0.0, +) + +add_meta_data( + Aircraft.Engine.Propeller.INTEGRATED_LIFT_COEFFICIENT, + meta_data=_MetaData, + historical_name={"GASP": 'INPROP.CLI', "FLOPS": None, "LEAPS1": None}, + units='unitless', + desc='propeller blade integrated design lift coefficient (Range: 0.3 to 0.8)', + default_value=0.5, +) + +add_meta_data( + Aircraft.Engine.Propeller.NUM_BLADES, + meta_data=_MetaData, + historical_name={"GASP": 'INPROP.BL', "FLOPS": None, "LEAPS1": None}, + units='unitless', + desc='number of blades per propeller', + option=True, + types=int, + default_value=0, +) + +add_meta_data( + Aircraft.Engine.Propeller.TIP_MACH_MAX, + meta_data=_MetaData, + historical_name={ + "GASP": None, # TODO this needs verification + "FLOPS": None, + "LEAPS1": None, + }, + units='unitless', + desc='maximum allowable Mach number at propeller tip (based on helical speed)', + default_value=1.0, +) + +add_meta_data( + Aircraft.Engine.Propeller.TIP_SPEED_MAX, + meta_data=_MetaData, + historical_name={ + "GASP": ['INPROP.TSPDMX', 'INPROP.TPSPDMXe'], + "FLOPS": None, + "LEAPS1": None, + }, + units='ft/s', + desc='maximum allowable propeller linear tip speed', + default_value=800.0, +) + +# add_meta_data( +# Aircraft.Engine.USE_PROPELLER_MAP, +# meta_data=_MetaData, +# historical_name={"GASP": None, +# "FLOPS": None, +# "LEAPS1": None +# }, +# option=True, +# default_value=False, +# types=bool, +# units="unitless", +# desc='flag whether to use propeller map or Hamilton-Standard model.' +# ) + # ______ _ # | ____| (_) # | |__ _ _ __ ___ @@ -2553,10 +2532,11 @@ add_meta_data( Aircraft.Fins.AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.SFIN', # ['&DEFINE.WTIN.SFIN', 'WTS.SFIN'], - "LEAPS1": 'aircraft.inputs.L0_fins.area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.SFIN', # ['&DEFINE.WTIN.SFIN', 'WTS.SFIN'], + "LEAPS1": 'aircraft.inputs.L0_fins.area', + }, units='ft**2', desc='vertical fin theoretical area', default_value=0.0, @@ -2567,13 +2547,15 @@ # - see also: Aircraft.Fins.MASS_SCALER Aircraft.Fins.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(4, 2)', '~WEIGHT.WFIN', '~WTSTAT.WSP(4, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._wing_vertical_fin_weight', - 'aircraft.outputs.L0_weights_summary.wing_vertical_fin_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(4, 2)', '~WEIGHT.WFIN', '~WTSTAT.WSP(4, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._wing_vertical_fin_weight', + 'aircraft.outputs.L0_weights_summary.wing_vertical_fin_weight', + ], + }, units='lbm', desc='mass of vertical fins', default_value=None, @@ -2582,10 +2564,11 @@ add_meta_data( Aircraft.Fins.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRFIN', # ['&DEFINE.WTIN.FRFIN', 'WTS.FRFIN'], - "LEAPS1": 'aircraft.inputs.L0_overrides.wing_vertical_fin_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRFIN', # ['&DEFINE.WTIN.FRFIN', 'WTS.FRFIN'], + "LEAPS1": 'aircraft.inputs.L0_overrides.wing_vertical_fin_weight', + }, units='unitless', desc='mass scaler for fin structure', default_value=1.0, @@ -2594,10 +2577,11 @@ add_meta_data( Aircraft.Fins.NUM_FINS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.NFIN', # ['&DEFINE.WTIN.NFIN', 'WTS.NFIN'], - "LEAPS1": 'aircraft.inputs.L0_fins.fin_count' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.NFIN', # ['&DEFINE.WTIN.NFIN', 'WTS.NFIN'], + "LEAPS1": 'aircraft.inputs.L0_fins.fin_count', + }, units='unitless', desc='number of fins', types=int, @@ -2608,10 +2592,11 @@ add_meta_data( Aircraft.Fins.TAPER_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.TRFIN', # ['&DEFINE.WTIN.TRFIN', 'WTS.TRFIN'], - "LEAPS1": 'aircraft.inputs.L0_fins.taper_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.TRFIN', # ['&DEFINE.WTIN.TRFIN', 'WTS.TRFIN'], + "LEAPS1": 'aircraft.inputs.L0_fins.taper_ratio', + }, units='unitless', desc='vertical fin theoretical taper ratio', default_value=None, @@ -2628,10 +2613,11 @@ add_meta_data( Aircraft.Fuel.AUXILIARY_FUEL_CAPACITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FULAUX', # ['&DEFINE.WTIN.FULAUX', 'FAWT.FULAUX'], - "LEAPS1": 'aircraft.inputs.L0_fuel.aux_capacity' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FULAUX', # ['&DEFINE.WTIN.FULAUX', 'FAWT.FULAUX'], + "LEAPS1": 'aircraft.inputs.L0_fuel.aux_capacity', + }, units='lbm', desc='fuel capacity of the auxiliary tank', default_value=None, @@ -2640,10 +2626,7 @@ add_meta_data( Aircraft.Fuel.BURN_PER_PASSENGER_MILE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm/NM', desc='average fuel burn per passenger per mile flown', ) @@ -2651,10 +2634,11 @@ add_meta_data( Aircraft.Fuel.CAPACITY_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISWT.FWMAX', - "LEAPS1": '(WeightABC)self._wing_fuel_capacity_factor' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISWT.FWMAX', + "LEAPS1": '(WeightABC)self._wing_fuel_capacity_factor', + }, units='unitless', desc='fuel capacity factor', default_value=23.0, @@ -2663,10 +2647,7 @@ add_meta_data( Aircraft.Fuel.DENSITY, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FUELD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FUELD', "FLOPS": None, "LEAPS1": None}, units='lbm/galUS', desc='fuel density', default_value=6.687, @@ -2676,28 +2657,26 @@ add_meta_data( Aircraft.Fuel.DENSITY_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FULDEN', # ['&DEFINE.WTIN.FULDEN', 'UPFUEL.FULDEN'], - "LEAPS1": 'aircraft.inputs.L0_fuel.density_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FULDEN', # ['&DEFINE.WTIN.FULDEN', 'UPFUEL.FULDEN'], + "LEAPS1": 'aircraft.inputs.L0_fuel.density_ratio', + }, units='unitless', desc='Fuel density ratio for alternate fuels compared to jet fuel (typical ' - 'density of 6.7 lbm/gal), used in the calculation of wing_capacity (if ' - 'wing_capacity is not input) and in the calculation of fuel system ' - 'weight.', + 'density of 6.7 lbm/gal), used in the calculation of wing_capacity (if ' + 'wing_capacity is not input) and in the calculation of fuel system ' + 'weight.', default_value=1.0, ) add_meta_data( Aircraft.Fuel.FUEL_MARGIN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FVOL_MRG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FVOL_MRG', "FLOPS": None, "LEAPS1": None}, units='unitless', # percent desc='excess fuel volume required, essentially the amount of fuel above ' - 'the design point that there has to be volume to carry', + 'the design point that there has to be volume to carry', ) add_meta_data( @@ -2705,13 +2684,15 @@ # - see also: Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER Aircraft.Fuel.FUEL_SYSTEM_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(13, 2)', '~WEIGHT.WFSYS', '~WTSTAT.WSP(13, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._fuel_sys_weight', - 'aircraft.outputs.L0_weights_summary.fuel_sys_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(13, 2)', '~WEIGHT.WFSYS', '~WTSTAT.WSP(13, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._fuel_sys_weight', + 'aircraft.outputs.L0_weights_summary.fuel_sys_weight', + ], + }, units='lbm', desc='fuel system mass', default_value=None, @@ -2720,10 +2701,7 @@ add_meta_data( Aircraft.Fuel.FUEL_SYSTEM_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKFS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKFS', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of fuel system', ) @@ -2731,11 +2709,12 @@ add_meta_data( Aircraft.Fuel.FUEL_SYSTEM_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CK21', - # ['&DEFINE.WTIN.WFSYS', 'MISWT.WFSYS', 'MISWT.OFSYS'], - "FLOPS": 'WTIN.WFSYS', - "LEAPS1": 'aircraft.inputs.L0_overrides.fuel_sys_weight' - }, + historical_name={ + "GASP": 'INGASP.CK21', + # ['&DEFINE.WTIN.WFSYS', 'MISWT.WFSYS', 'MISWT.OFSYS'], + "FLOPS": 'WTIN.WFSYS', + "LEAPS1": 'aircraft.inputs.L0_overrides.fuel_sys_weight', + }, units='unitless', desc='scaler for fuel system mass', default_value=1.0, @@ -2744,13 +2723,15 @@ add_meta_data( Aircraft.Fuel.FUSELAGE_FUEL_CAPACITY, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.FULFMX', 'WTS.FULFMX', '~WEIGHT.FUFU'], - "FLOPS": 'WTIN.FULFMX', - "LEAPS1": ['aircraft.inputs.L0_fuel.fuselage_capacity', - '(WeightABC)self._fuselage_fuel_capacity' - ] - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.FULFMX', 'WTS.FULFMX', '~WEIGHT.FUFU'], + "FLOPS": 'WTIN.FULFMX', + "LEAPS1": [ + 'aircraft.inputs.L0_fuel.fuselage_capacity', + '(WeightABC)self._fuselage_fuel_capacity', + ], + }, units='lbm', desc='fuel capacity of the fuselage', default_value=None, @@ -2759,10 +2740,11 @@ add_meta_data( Aircraft.Fuel.NUM_TANKS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.NTANK', # ['&DEFINE.WTIN.NTANK', 'WTS.NTANK'], - "LEAPS1": 'aircraft.inputs.L0_fuel.tank_count' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.NTANK', # ['&DEFINE.WTIN.NTANK', 'WTS.NTANK'], + "LEAPS1": 'aircraft.inputs.L0_fuel.tank_count', + }, units='unitless', desc='number of fuel tanks', types=int, @@ -2773,32 +2755,36 @@ add_meta_data( Aircraft.Fuel.TOTAL_CAPACITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FMXTOT', # ['&DEFINE.WTIN.FMXTOT', 'PLRNG.FMXTOT'], - "LEAPS1": ['aircraft.inputs.L0_fuel.total_capacity', - 'aircraft.cached.L0_fuel.total_capacity', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FMXTOT', # ['&DEFINE.WTIN.FMXTOT', 'PLRNG.FMXTOT'], + "LEAPS1": [ + 'aircraft.inputs.L0_fuel.total_capacity', + 'aircraft.cached.L0_fuel.total_capacity', + ], + }, units='lbm', desc='Total fuel capacity of the aircraft including wing, fuselage and ' - 'auxiliary tanks. Used in generating payload-range diagram (Default = ' - 'wing_capacity + fuselage_capacity + aux_capacity)', + 'auxiliary tanks. Used in generating payload-range diagram (Default = ' + 'wing_capacity + fuselage_capacity + aux_capacity)', default_value=None, ) add_meta_data( Aircraft.Fuel.TOTAL_VOLUME, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.ZFEQ', - "LEAPS1": ['(WeightABC)self._total_fuel_vol', - '~WeightABC.calc_unusable_fuel.total_fuel_vol', - '~WeightABC._pre_unusable_fuel.total_fuel_vol', - '~BasicTransportWeight._pre_unusable_fuel.total_fuel_vol', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.ZFEQ', + "LEAPS1": [ + '(WeightABC)self._total_fuel_vol', + '~WeightABC.calc_unusable_fuel.total_fuel_vol', + '~WeightABC._pre_unusable_fuel.total_fuel_vol', + '~BasicTransportWeight._pre_unusable_fuel.total_fuel_vol', + ], + }, units='galUS', # need to check this - desc='Total fuel volume' + desc='Total fuel volume', ) add_meta_data( @@ -2806,13 +2792,15 @@ # - see also: Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER Aircraft.Fuel.UNUSABLE_FUEL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(29, 2)', '~WEIGHT.WUF', '~WTSTAT.WSP(29, 2)', '~INERT.WUF'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._unusable_fuel_weight', - 'aircraft.outputs.L0_weights_summary.unusable_fuel_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(29, 2)', '~WEIGHT.WUF', '~WTSTAT.WSP(29, 2)', '~INERT.WUF'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._unusable_fuel_weight', + 'aircraft.outputs.L0_weights_summary.unusable_fuel_weight', + ], + }, units='lbm', desc='unusable fuel mass', default_value=None, @@ -2821,10 +2809,7 @@ add_meta_data( Aircraft.Fuel.UNUSABLE_FUEL_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": "INGASP.CW(13)", - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": "INGASP.CW(13)", "FLOPS": None, "LEAPS1": None}, default_value=6.0, units="unitless", desc='mass trend coefficient of trapped fuel factor', @@ -2833,11 +2818,12 @@ add_meta_data( Aircraft.Fuel.UNUSABLE_FUEL_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WUF', 'MISWT.WUF', 'MISWT.OUF'], - "FLOPS": 'WTIN.WUF', - "LEAPS1": 'aircraft.inputs.L0_overrides.unusable_fuel_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WUF', 'MISWT.WUF', 'MISWT.OUF'], + "FLOPS": 'WTIN.WUF', + "LEAPS1": 'aircraft.inputs.L0_overrides.unusable_fuel_weight', + }, units='unitless', desc='scaler for Unusable fuel mass', default_value=1.0, @@ -2846,10 +2832,11 @@ add_meta_data( Aircraft.Fuel.WING_FUEL_CAPACITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FULWMX', # ['&DEFINE.WTIN.FULWMX', 'WTS.FULWMX'], - "LEAPS1": 'aircraft.inputs.L0_fuel.wing_capacity' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FULWMX', # ['&DEFINE.WTIN.FULWMX', 'WTS.FULWMX'], + "LEAPS1": 'aircraft.inputs.L0_fuel.wing_capacity', + }, units='lbm', desc='fuel capacity of the auxiliary tank', default_value=None, @@ -2858,10 +2845,7 @@ add_meta_data( Aircraft.Fuel.WING_FUEL_FRACTION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKWF', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKWF', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='fraction of total theoretical wing volume used for wing fuel', ) @@ -2869,10 +2853,11 @@ add_meta_data( Aircraft.Fuel.WING_REF_CAPACITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FUELRF', # ['&DEFINE.WTIN.FUELRF', 'WPAB.FUELRF'], - "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FUELRF', # ['&DEFINE.WTIN.FUELRF', 'WPAB.FUELRF'], + "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity', + }, units='lbm', # TODO FLOPS says lbm, sfwate.f line 827 desc='reference fuel volume', default_value=0.0, @@ -2881,10 +2866,11 @@ add_meta_data( Aircraft.Fuel.WING_REF_CAPACITY_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FSWREF', # ['&DEFINE.WTIN.FSWREF', 'WPAB.FSWREF'], - "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FSWREF', # ['&DEFINE.WTIN.FSWREF', 'WPAB.FSWREF'], + "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity_area', + }, units='unitless', # TODO FLOPS says unitless, sfwate.f line 828 desc='reference wing area for fuel capacity', default_value=0.0, @@ -2893,10 +2879,11 @@ add_meta_data( Aircraft.Fuel.WING_REF_CAPACITY_TERM_A, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FUSCLA', # ['&DEFINE.WTIN.FUSCLA', 'WPAB.FUSCLA'], - "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity_1_5_term' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FUSCLA', # ['&DEFINE.WTIN.FUSCLA', 'WPAB.FUSCLA'], + "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity_1_5_term', + }, units='unitless', desc='scaling factor A', default_value=0.0, @@ -2905,10 +2892,11 @@ add_meta_data( Aircraft.Fuel.WING_REF_CAPACITY_TERM_B, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FUSCLB', # ['&DEFINE.WTIN.FUSCLB', 'WPAB.FUSCLB'], - "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity_linear_term' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FUSCLB', # ['&DEFINE.WTIN.FUSCLB', 'WPAB.FUSCLB'], + "LEAPS1": 'aircraft.inputs.L0_fuel.wing_ref_capacity_linear_term', + }, units='unitless', desc='scaling factor B', default_value=0.0, @@ -2931,10 +2919,7 @@ add_meta_data( Aircraft.Fuel.WING_VOLUME_DESIGN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FVOLW_DES', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FVOLW_DES', "FLOPS": None, "LEAPS1": None}, units='ft**3', desc='wing tank fuel volume when carrying design fuel plus fuel margin', ) @@ -2942,10 +2927,7 @@ add_meta_data( Aircraft.Fuel.WING_VOLUME_GEOMETRIC_MAX, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FVOLW_GEOM', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FVOLW_GEOM', "FLOPS": None, "LEAPS1": None}, units='ft**3', desc='wing tank fuel volume based on geometry', ) @@ -2953,10 +2935,7 @@ add_meta_data( Aircraft.Fuel.WING_VOLUME_STRUCTURAL_MAX, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FVOLW_MAX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FVOLW_MAX', "FLOPS": None, "LEAPS1": None}, units='ft**3', desc='wing tank volume based on maximum wing fuel weight', ) @@ -2978,13 +2957,15 @@ # - see also: Aircraft.Furnishings.MASS_SCALER Aircraft.Furnishings.MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(8)', - # ['WTS.WSP(22, 2)', '~WEIGHT.WFURN', '~WTSTAT.WSP(22, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._furnishings_group_weight', - 'aircraft.outputs.L0_weights_summary.furnishings_group_weight', - ] - }, + historical_name={ + "GASP": 'INGASP.CW(8)', + # ['WTS.WSP(22, 2)', '~WEIGHT.WFURN', '~WTSTAT.WSP(22, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._furnishings_group_weight', + 'aircraft.outputs.L0_weights_summary.furnishings_group_weight', + ], + }, units='lbm', desc='Total furnishings system mass', default_value=None, @@ -2993,22 +2974,20 @@ add_meta_data( Aircraft.Furnishings.MASS_BASE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='Base furnishings system mass without additional 1% empty mass' + desc='Base furnishings system mass without additional 1% empty mass', ) add_meta_data( Aircraft.Furnishings.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WFURN', 'MISWT.WFURN', 'MISWT.OFURN'], - "FLOPS": 'WTIN.WFURN', - "LEAPS1": 'aircraft.inputs.L0_overrides.furnishings_group_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WFURN', 'MISWT.WFURN', 'MISWT.OFURN'], + "FLOPS": 'WTIN.WFURN', + "LEAPS1": 'aircraft.inputs.L0_overrides.furnishings_group_weight', + }, units='unitless', desc='Furnishings system mass scaler', default_value=1.0, @@ -3027,10 +3006,7 @@ add_meta_data( Aircraft.Fuselage.AISLE_WIDTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WAS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WAS', "FLOPS": None, "LEAPS1": None}, units='inch', desc='width of the aisles in the passenger cabin', option=True, @@ -3042,45 +3018,46 @@ add_meta_data( Aircraft.Fuselage.AVG_DIAMETER, meta_data=_MetaData, - historical_name={"GASP": ['INGASP.WC', 'INGASP.SWF'], - "FLOPS": None, # 'EDETIN.XD', - "LEAPS1": 'aircraft.outputs.L0_fuselage.avg_diam' - }, + historical_name={ + "GASP": ['INGASP.WC', 'INGASP.SWF'], + "FLOPS": None, # 'EDETIN.XD', + "LEAPS1": 'aircraft.outputs.L0_fuselage.avg_diam', + }, units='ft', - desc='average fuselage diameter' + desc='average fuselage diameter', ) add_meta_data( Aircraft.Fuselage.CHARACTERISTIC_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL[4]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[3]', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[3]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL[4]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[3]', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[3]', + ], + }, units='ft', - desc='Reynolds characteristic length for the fuselage' + desc='Reynolds characteristic length for the fuselage', ) add_meta_data( Aircraft.Fuselage.CROSS_SECTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['MISSA.SPI', '~CDCC.SPI'], - "LEAPS1": 'aircraft.outputs.L0_fuselage.mission_cross_sect_area' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['MISSA.SPI', '~CDCC.SPI'], + "LEAPS1": 'aircraft.outputs.L0_fuselage.mission_cross_sect_area', + }, units='ft**2', - desc='fuselage cross sectional area' + desc='fuselage cross sectional area', ) add_meta_data( Aircraft.Fuselage.DELTA_DIAMETER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.HCK', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.HCK', "FLOPS": None, "LEAPS1": None}, units='ft', desc='mean fuselage cabin diameter minus mean fuselage nose diameter', default_value=4.5, @@ -3089,34 +3066,34 @@ add_meta_data( Aircraft.Fuselage.DIAMETER_TO_WING_SPAN, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['MISSA.DB', '~CDCC.DB'], - "LEAPS1": 'aircraft.outputs.L0_fuselage.mission_diam_to_wing_span_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['MISSA.DB', '~CDCC.DB'], + "LEAPS1": 'aircraft.outputs.L0_fuselage.mission_diam_to_wing_span_ratio', + }, units='unitless', - desc='fuselage diameter to wing span ratio' + desc='fuselage diameter to wing span ratio', ) add_meta_data( Aircraft.Fuselage.FINENESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.FR[4]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[3]', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[3]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.FR[4]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[3]', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[3]', + ], + }, units='unitless', - desc='fuselage fineness ratio' + desc='fuselage fineness ratio', ) add_meta_data( Aircraft.Fuselage.FLAT_PLATE_AREA_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELFE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELFE', "FLOPS": None, "LEAPS1": None}, units='ft**2', desc='increment to fuselage flat plate area', ) @@ -3124,22 +3101,20 @@ add_meta_data( Aircraft.Fuselage.FORM_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKF', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKF', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='fuselage form factor', - default_value=1 + default_value=1, ) add_meta_data( Aircraft.Fuselage.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRLB', # ['&DEFINE.AERIN.TRLB', 'XLAM.TRLB', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.fuselage_percent_laminar_flow_lower_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRLB', # ['&DEFINE.AERIN.TRLB', 'XLAM.TRLB', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.fuselage_percent_laminar_flow_lower_surface', + }, units='unitless', desc='define percent laminar flow for fuselage lower surface', default_value=0.0, @@ -3148,10 +3123,11 @@ add_meta_data( Aircraft.Fuselage.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRUB', # ['&DEFINE.AERIN.TRUB', 'XLAM.TRUB', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.fuselage_percent_laminar_flow_upper_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRUB', # ['&DEFINE.AERIN.TRUB', 'XLAM.TRUB', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.fuselage_percent_laminar_flow_upper_surface', + }, units='unitless', desc='define percent laminar flow for fuselage upper surface', default_value=0.0, @@ -3161,35 +3137,38 @@ add_meta_data( Aircraft.Fuselage.LENGTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELF', - "FLOPS": 'WTIN.XL', - # [ # inputs - # '&DEFINE.WTIN.XL', 'WTS.XL', - # # outputs - # 'EDETIN.BL', '~DEFAER.BL', - # ], - "LEAPS1": ['aircraft.inputs.L0_fuselage.total_length', - 'aircraft.outputs.L0_fuselage.total_length', - # other - 'aircraft.cached.L0_fuselage.total_length', - ] - }, + historical_name={ + "GASP": 'INGASP.ELF', + "FLOPS": 'WTIN.XL', + # [ # inputs + # '&DEFINE.WTIN.XL', 'WTS.XL', + # # outputs + # 'EDETIN.BL', '~DEFAER.BL', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_fuselage.total_length', + 'aircraft.outputs.L0_fuselage.total_length', + # other + 'aircraft.cached.L0_fuselage.total_length', + ], + }, units='ft', desc='Define the Fuselage total length. If total_length is not input for a ' - 'passenger transport, LEAPS will calculate the fuselage length, width and ' - 'depth and the length of the passenger compartment.', + 'passenger transport, LEAPS will calculate the fuselage length, width and ' + 'depth and the length of the passenger compartment.', default_value=0.0, ) add_meta_data( Aircraft.Fuselage.LENGTH_TO_DIAMETER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['MISSA.BODYLD', '~CDCC.BODYLD'], - "LEAPS1": 'aircraft.outputs.L0_fuselage.mission_len_to_diam_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['MISSA.BODYLD', '~CDCC.BODYLD'], + "LEAPS1": 'aircraft.outputs.L0_fuselage.mission_len_to_diam_ratio', + }, units='unitless', - desc='fuselage length to diameter ratio' + desc='fuselage length to diameter ratio', ) add_meta_data( @@ -3197,13 +3176,15 @@ # - see also: Aircraft.Fuselage.MASS_SCALER Aircraft.Fuselage.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(6, 2)', '~WEIGHT.WFUSE', '~WTSTAT.WSP(6, 2)', '~INERT.WFUSE', ], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._fuselage_weight', - 'aircraft.outputs.L0_weights_summary.fuselage_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(6, 2)', '~WEIGHT.WFUSE', '~WTSTAT.WSP(6, 2)', '~INERT.WFUSE', ], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._fuselage_weight', + 'aircraft.outputs.L0_weights_summary.fuselage_weight', + ], + }, units='lbm', desc='mass of the fuselage structure', default_value=None, @@ -3212,10 +3193,7 @@ add_meta_data( Aircraft.Fuselage.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKB', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKB', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of fuselage', default_value=136, @@ -3224,10 +3202,11 @@ add_meta_data( Aircraft.Fuselage.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRFU', # ['&DEFINE.WTIN.FRFU', 'WTS.FRFU'], - "LEAPS1": 'aircraft.inputs.L0_overrides.fuselage_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRFU', # ['&DEFINE.WTIN.FRFU', 'WTS.FRFU'], + "LEAPS1": 'aircraft.inputs.L0_overrides.fuselage_weight', + }, units='unitless', desc='mass scaler of the fuselage structure', default_value=1.0, @@ -3236,30 +3215,33 @@ add_meta_data( Aircraft.Fuselage.MAX_HEIGHT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.DF', # ['&DEFINE.WTIN.DF', 'WTS.DF'], - "LEAPS1": 'aircraft.inputs.L0_fuselage.max_height' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.DF', # ['&DEFINE.WTIN.DF', 'WTS.DF'], + "LEAPS1": 'aircraft.inputs.L0_fuselage.max_height', + }, units='ft', - desc='maximum fuselage height' + desc='maximum fuselage height', ) add_meta_data( Aircraft.Fuselage.MAX_WIDTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.WF', - # [ # inputs - # '&DEFINE.WTIN.WF', 'WTS.WF', - # # outputs - # 'MIMOD.FWID', - # ], - "LEAPS1": ['aircraft.inputs.L0_fuselage.max_width', - 'aircraft.outputs.L0_fuselage.max_width', - # other - 'aircraft.cached.L0_fuselage.max_width', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.WF', + # [ # inputs + # '&DEFINE.WTIN.WF', 'WTS.WF', + # # outputs + # 'MIMOD.FWID', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_fuselage.max_width', + 'aircraft.outputs.L0_fuselage.max_width', + # other + 'aircraft.cached.L0_fuselage.max_width', + ], + }, units='ft', desc='maximum fuselage width', default_value=0.0, @@ -3269,12 +3251,14 @@ add_meta_data( Aircraft.Fuselage.MILITARY_CARGO_FLOOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.CARGF', # ['&DEFINE.WTIN.CARGF', 'WTS.CARGF'], - "LEAPS1": ['aircraft.inputs.L0_crew_and_payload.military_cargo', - 'aircraft.cached.L0_crew_and_payload.military_cargo', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.CARGF', # ['&DEFINE.WTIN.CARGF', 'WTS.CARGF'], + "LEAPS1": [ + 'aircraft.inputs.L0_crew_and_payload.military_cargo', + 'aircraft.cached.L0_crew_and_payload.military_cargo', + ], + }, units='unitless', desc='indicate whether or not there is a military cargo aircraft floor', option=True, @@ -3285,10 +3269,7 @@ add_meta_data( Aircraft.Fuselage.NOSE_FINENESS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELODN', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ELODN', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='length to diameter ratio of nose cone', default_value=1, @@ -3297,10 +3278,7 @@ add_meta_data( Aircraft.Fuselage.NUM_AISLES, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.AS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.AS', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='number of aisles in the passenger cabin', types=int, @@ -3311,14 +3289,16 @@ add_meta_data( Aircraft.Fuselage.NUM_FUSELAGES, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.NFUSE', 'EDETIN.NFUSE', '~WWGHT.NFUSE'], - "FLOPS": 'WTIN.NFUSE', - "LEAPS1": ['aircraft.inputs.L0_fuselage.count', - # other - 'aircraft.cached.L0_fuselage.count', - ] - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.NFUSE', 'EDETIN.NFUSE', '~WWGHT.NFUSE'], + "FLOPS": 'WTIN.NFUSE', + "LEAPS1": [ + 'aircraft.inputs.L0_fuselage.count', + # other + 'aircraft.cached.L0_fuselage.count', + ], + }, units='unitless', desc='number of fuselages', types=int, @@ -3329,10 +3309,7 @@ add_meta_data( Aircraft.Fuselage.NUM_SEATS_ABREAST, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SAB', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SAB', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='seats abreast in fuselage', types=int, @@ -3343,12 +3320,14 @@ add_meta_data( Aircraft.Fuselage.PASSENGER_COMPARTMENT_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.XLP', # ['&DEFINE.WTIN.XLP', 'WTS.XLP'], - "LEAPS1": ['aircraft.inputs.L0_fuselage.passenger_compartment_length', - 'aircraft.cached.L0_fuselage.passenger_compartment_length', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.XLP', # ['&DEFINE.WTIN.XLP', 'WTS.XLP'], + "LEAPS1": [ + 'aircraft.inputs.L0_fuselage.passenger_compartment_length', + 'aircraft.cached.L0_fuselage.passenger_compartment_length', + ], + }, units='ft', desc='length of passenger compartment', default_value=0.0, @@ -3357,10 +3336,7 @@ add_meta_data( Aircraft.Fuselage.PILOT_COMPARTMENT_LENGTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELPC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ELPC', "FLOPS": None, "LEAPS1": None}, units='ft', desc='length of the pilot compartment', ) @@ -3368,21 +3344,19 @@ add_meta_data( Aircraft.Fuselage.PLANFORM_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.FPAREA', - "LEAPS1": '(WeightABC)self._fuselage_planform_area' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.FPAREA', + "LEAPS1": '(WeightABC)self._fuselage_planform_area', + }, units='ft**2', - desc='fuselage planform area' + desc='fuselage planform area', ) add_meta_data( Aircraft.Fuselage.PRESSURE_DIFFERENTIAL, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELP', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELP', "FLOPS": None, "LEAPS1": None}, units='psi', desc='fuselage pressure differential during cruise', default_value=7.5, @@ -3391,10 +3365,7 @@ add_meta_data( Aircraft.Fuselage.SEAT_PITCH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.PS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.PS', "FLOPS": None, "LEAPS1": None}, units='inch', desc='pitch of the economy class seats', option=True, @@ -3404,10 +3375,7 @@ add_meta_data( Aircraft.Fuselage.SEAT_WIDTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WS', "FLOPS": None, "LEAPS1": None}, units='inch', desc='width of the economy class seats', option=True, @@ -3417,10 +3385,7 @@ add_meta_data( Aircraft.Fuselage.TAIL_FINENESS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELODT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ELODT', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='length to diameter ratio of tail cone', default_value=1, @@ -3431,15 +3396,16 @@ # - see also: Aircraft.Fuselage.WETTED_AREA_SCALER Aircraft.Fuselage.WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SF', - "FLOPS": None, # ['ACTWET.SWTFU', 'MISSA.SWET[4]'], - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.fuselage_wetted_area', - 'aircraft.outputs.L0_aerodynamics' - '.mission_component_wetted_area_table[3]', - 'aircraft.cached.L0_aerodynamics' - '.mission_component_wetted_area_table[3]', - ] - }, + historical_name={ + "GASP": 'INGASP.SF', + "FLOPS": None, # ['ACTWET.SWTFU', 'MISSA.SWET[4]'], + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.fuselage_wetted_area', + 'aircraft.outputs.L0_aerodynamics' + '.mission_component_wetted_area_table[3]', + 'aircraft.cached.L0_aerodynamics' '.mission_component_wetted_area_table[3]', + ], + }, units='ft**2', desc='fuselage wetted area', default_value=None, @@ -3448,10 +3414,11 @@ add_meta_data( Aircraft.Fuselage.WETTED_AREA_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SF_FAC', - "FLOPS": 'AERIN.SWETF', # ['&DEFINE.AERIN.SWETF', 'AWETO.SWETF', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.fuselage_wetted_area' - }, + historical_name={ + "GASP": 'INGASP.SF_FAC', + "FLOPS": 'AERIN.SWETF', # ['&DEFINE.AERIN.SWETF', 'AWETO.SWETF', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.fuselage_wetted_area', + }, units='unitless', desc='fuselage wetted area scaler', default_value=1.0, @@ -3468,25 +3435,28 @@ add_meta_data( Aircraft.HorizontalTail.AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SHT', - "FLOPS": 'WTIN.SHT', # ['&DEFINE.WTIN.SHT', 'EDETIN.SHT'], - "LEAPS1": ['aircraft.inputs.L0_horizontal_tail.area', - 'aircraft.cached.L0_horizontal_tail.area', - ] - }, + historical_name={ + "GASP": 'INGASP.SHT', + "FLOPS": 'WTIN.SHT', # ['&DEFINE.WTIN.SHT', 'EDETIN.SHT'], + "LEAPS1": [ + 'aircraft.inputs.L0_horizontal_tail.area', + 'aircraft.cached.L0_horizontal_tail.area', + ], + }, units='ft**2', desc='horizontal tail theoretical area; overridden by vol_coeff, if ' - 'vol_coeff > 0.0', # this appears to never be calculated in Aviary, need to show users the overriding capability of Aviary + 'vol_coeff > 0.0', # this appears to never be calculated in Aviary, need to show users the overriding capability of Aviary default_value=0.0, ) add_meta_data( Aircraft.HorizontalTail.ASPECT_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ARHT', - "FLOPS": 'WTIN.ARHT', # ['&DEFINE.WTIN.ARHT', 'EDETIN.ARHT'], - "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.aspect_ratio' - }, + historical_name={ + "GASP": 'INGASP.ARHT', + "FLOPS": 'WTIN.ARHT', # ['&DEFINE.WTIN.ARHT', 'EDETIN.ARHT'], + "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.aspect_ratio', + }, units='unitless', desc='horizontal tail theoretical aspect ratio', default_value=None, @@ -3495,10 +3465,7 @@ add_meta_data( Aircraft.HorizontalTail.AVERAGE_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CBARHT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CBARHT', "FLOPS": None, "LEAPS1": None}, units='ft', desc='mean aerodynamic chord of horizontal tail', ) @@ -3506,47 +3473,50 @@ add_meta_data( Aircraft.HorizontalTail.CHARACTERISTIC_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL[2]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[1]', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[1]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL[2]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[1]', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[1]', + ], + }, units='ft', - desc='Reynolds characteristic length for the horizontal tail' + desc='Reynolds characteristic length for the horizontal tail', ) add_meta_data( Aircraft.HorizontalTail.FINENESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.FR[2]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[1]', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[1]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.FR[2]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[1]', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[1]', + ], + }, units='unitless', - desc='horizontal tail fineness ratio' + desc='horizontal tail fineness ratio', ) add_meta_data( Aircraft.HorizontalTail.FORM_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKHT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKHT', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='horizontal tail form factor', + default_value=1.25, ) add_meta_data( Aircraft.HorizontalTail.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRLH', # ['&DEFINE.AERIN.TRLH', 'XLAM.TRLH', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.horizontal_tail_percent_laminar_flow_lower_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRLH', # ['&DEFINE.AERIN.TRLH', 'XLAM.TRLH', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.horizontal_tail_percent_laminar_flow_lower_surface', + }, units='unitless', desc='define percent laminar flow for horizontal tail lower surface', default_value=0.0, @@ -3555,10 +3525,11 @@ add_meta_data( Aircraft.HorizontalTail.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRUH', # ['&DEFINE.AERIN.TRUH', 'XLAM.TRUH', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.horizontal_tail_percent_laminar_flow_upper_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRUH', # ['&DEFINE.AERIN.TRUH', 'XLAM.TRUH', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.horizontal_tail_percent_laminar_flow_upper_surface', + }, units='unitless', desc='define percent laminar flow for horizontal tail upper surface', default_value=0.0, @@ -3569,13 +3540,15 @@ # - see also: Aircraft.HorizontalTail.MASS_SCALER Aircraft.HorizontalTail.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(2, 2)', '~WEIGHT.WHT', '~WTSTAT.WSP(2, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._horizontal_tail_weight', - 'aircraft.outputs.L0_weights_summary.horizontal_tail_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(2, 2)', '~WEIGHT.WHT', '~WTSTAT.WSP(2, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._horizontal_tail_weight', + 'aircraft.outputs.L0_weights_summary.horizontal_tail_weight', + ], + }, units='lbm', desc='mass of horizontal tail', default_value=None, @@ -3584,22 +3557,20 @@ add_meta_data( Aircraft.HorizontalTail.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKY', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKY', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of horizontal tail', - default_value=.18, + default_value=0.18, ) add_meta_data( Aircraft.HorizontalTail.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRHT', # ['&DEFINE.WTIN.FRHT', 'WTS.FRHT'], - "LEAPS1": 'aircraft.inputs.L0_overrides.horizontal_tail_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRHT', # ['&DEFINE.WTIN.FRHT', 'WTS.FRHT'], + "LEAPS1": 'aircraft.inputs.L0_overrides.horizontal_tail_weight', + }, units='unitless', desc='mass scaler of the horizontal tail structure', default_value=1.0, @@ -3608,10 +3579,7 @@ add_meta_data( Aircraft.HorizontalTail.MOMENT_ARM, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELTH', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ELTH', "FLOPS": None, "LEAPS1": None}, units='ft', desc='moment arm of horizontal tail', ) @@ -3619,10 +3587,7 @@ add_meta_data( Aircraft.HorizontalTail.MOMENT_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.COELTH', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.COELTH', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='Ratio of wing chord to horizontal tail moment arm', ) @@ -3630,10 +3595,7 @@ add_meta_data( Aircraft.HorizontalTail.ROOT_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CRCLHT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CRCLHT', "FLOPS": None, "LEAPS1": None}, units='ft', desc='horizontal tail root chord', ) @@ -3641,10 +3603,7 @@ add_meta_data( Aircraft.HorizontalTail.SPAN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.BHT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.BHT', "FLOPS": None, "LEAPS1": None}, units='ft', desc='span of horizontal tail', ) @@ -3652,12 +3611,14 @@ add_meta_data( Aircraft.HorizontalTail.SWEEP, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DWPQCH', - "FLOPS": 'WTIN.SWPHT', # , 'WTS.SWPHT'], - "LEAPS1": ['aircraft.inputs.L0_horizontal_tail.sweep_at_quarter_chord', - 'aircraft.cached.L0_horizontal_tail.sweep_at_quarter_chord' - ] - }, + historical_name={ + "GASP": 'INGASP.DWPQCH', + "FLOPS": 'WTIN.SWPHT', # , 'WTS.SWPHT'], + "LEAPS1": [ + 'aircraft.inputs.L0_horizontal_tail.sweep_at_quarter_chord', + 'aircraft.cached.L0_horizontal_tail.sweep_at_quarter_chord', + ], + }, units='deg', desc='quarter-chord sweep of horizontal tail', ) @@ -3665,10 +3626,11 @@ add_meta_data( Aircraft.HorizontalTail.TAPER_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SLMH', - "FLOPS": 'WTIN.TRHT', # , 'EDETIN.TRHT'], - "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.taper_ratio' - }, + historical_name={ + "GASP": 'INGASP.SLMH', + "FLOPS": 'WTIN.TRHT', # , 'EDETIN.TRHT'], + "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.taper_ratio', + }, units='unitless', desc='horizontal tail theoretical taper ratio', default_value=None, @@ -3677,10 +3639,11 @@ add_meta_data( Aircraft.HorizontalTail.THICKNESS_TO_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TCHT', - "FLOPS": 'WTIN.TCHT', # , 'EDETIN.TCHT'], - "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.thickness_to_chord_ratio' - }, + historical_name={ + "GASP": 'INGASP.TCHT', + "FLOPS": 'WTIN.TCHT', # , 'EDETIN.TCHT'], + "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.thickness_to_chord_ratio', + }, units='unitless', desc='horizontal tail thickness-chord ratio', default_value=0.0, @@ -3690,25 +3653,23 @@ add_meta_data( Aircraft.HorizontalTail.VERTICAL_TAIL_FRACTION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SAH', - "FLOPS": 'WTIN.HHT', # ['&DEFINE.WTIN.HHT', 'EDETIN.HHT'], - "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.vertical_tail_fraction' - }, + historical_name={ + "GASP": 'INGASP.SAH', + "FLOPS": 'WTIN.HHT', # ['&DEFINE.WTIN.HHT', 'EDETIN.HHT'], + "LEAPS1": 'aircraft.inputs.L0_horizontal_tail.vertical_tail_fraction', + }, units='unitless', desc='Define the decimal fraction of vertical tail span where horizontal ' - 'tail is mounted. Defaults: 0.0 == for body mounted (default for ' - 'transport with all engines on wing); 1.0 == for T tail ' - '(default for transport with multiple engines on fuselage)', + 'tail is mounted. Defaults: 0.0 == for body mounted (default for ' + 'transport with all engines on wing); 1.0 == for T tail ' + '(default for transport with multiple engines on fuselage)', default_value=None, ) add_meta_data( Aircraft.HorizontalTail.VOLUME_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.VBARHX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.VBARHX', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='tail volume coefficicient of horizontal tail', ) @@ -3718,15 +3679,16 @@ # - see also: Aircraft.HorizontalTail.WETTED_AREA_SCALER Aircraft.HorizontalTail.WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['ACTWET.SWTHT', 'MISSA.SWET[2]'], - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.horizontal_tail_wetted_area', - 'aircraft.outputs.L0_aerodynamics' - '.mission_component_wetted_area_table[1]', - 'aircraft.cached.L0_aerodynamics' - '.mission_component_wetted_area_table[1]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['ACTWET.SWTHT', 'MISSA.SWET[2]'], + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.horizontal_tail_wetted_area', + 'aircraft.outputs.L0_aerodynamics' + '.mission_component_wetted_area_table[1]', + 'aircraft.cached.L0_aerodynamics' '.mission_component_wetted_area_table[1]', + ], + }, units='ft**2', desc='horizontal tail wetted area', default_value=None, @@ -3735,10 +3697,11 @@ add_meta_data( Aircraft.HorizontalTail.WETTED_AREA_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.SWETH', # ['&DEFINE.AERIN.SWETH', 'AWETO.SWETH', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.horizontal_tail_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.SWETH', # ['&DEFINE.AERIN.SWETH', 'AWETO.SWETH', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.horizontal_tail_wetted_area', + }, units='unitless', desc='horizontal tail wetted area scaler', default_value=1.0, @@ -3757,10 +3720,7 @@ add_meta_data( Aircraft.Hydraulics.FLIGHT_CONTROL_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(3)', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CW(3)', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='mass trend coefficient of hydraulics for flight control system', default_value=0.10, @@ -3769,10 +3729,7 @@ add_meta_data( Aircraft.Hydraulics.GEAR_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(4)', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CW(4)', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='mass trend coefficient of hydraulics for landing gear', default_value=0.16, @@ -3783,13 +3740,15 @@ # - see also: Aircraft.Hydraulics.MASS_SCALER Aircraft.Hydraulics.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(19, 2)', '~WEIGHT.WHYD', '~WTSTAT.WSP(19, 2)', '~INERT.WHYD'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._hydraulics_group_weight', - 'aircraft.outputs.L0_weights_summary.hydraulics_group_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(19, 2)', '~WEIGHT.WHYD', '~WTSTAT.WSP(19, 2)', '~INERT.WHYD'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._hydraulics_group_weight', + 'aircraft.outputs.L0_weights_summary.hydraulics_group_weight', + ], + }, units='lbm', desc='mass of hydraulic system', default_value=None, @@ -3798,11 +3757,12 @@ add_meta_data( Aircraft.Hydraulics.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WHYD', 'MISWT.WHYD', 'MISWT.OHYD'], - "FLOPS": 'WTIN.WHYD', - "LEAPS1": 'aircraft.inputs.L0_overrides.hydraulics_group_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WHYD', 'MISWT.WHYD', 'MISWT.OHYD'], + "FLOPS": 'WTIN.WHYD', + "LEAPS1": 'aircraft.inputs.L0_overrides.hydraulics_group_weight', + }, units='unitless', desc='mass scaler of the hydraulic system', default_value=1.0, @@ -3811,10 +3771,11 @@ add_meta_data( Aircraft.Hydraulics.SYSTEM_PRESSURE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.HYDPR', # ['&DEFINE.WTIN.HYDPR', 'WTS.HYDPR'], - "LEAPS1": 'aircraft.inputs.L0_weights.hydraulic_sys_press' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.HYDPR', # ['&DEFINE.WTIN.HYDPR', 'WTS.HYDPR'], + "LEAPS1": 'aircraft.inputs.L0_weights.hydraulic_sys_press', + }, units='psi', desc='hydraulic system pressure', default_value=3000.0, @@ -3834,13 +3795,15 @@ # - see also: Aircraft.Instruments.MASS_SCALER Aircraft.Instruments.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(18, 2)', '~WEIGHT.WIN', '~WTSTAT.WSP(18, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._instrument_group_weight', - 'aircraft.outputs.L0_weights_summary.instrument_group_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(18, 2)', '~WEIGHT.WIN', '~WTSTAT.WSP(18, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._instrument_group_weight', + 'aircraft.outputs.L0_weights_summary.instrument_group_weight', + ], + }, units='lbm', desc='instrument group mass', default_value=None, @@ -3849,10 +3812,7 @@ add_meta_data( Aircraft.Instruments.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CW(2)', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CW(2)', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='mass trend coefficient of instruments', default_value=0.0862, @@ -3861,11 +3821,12 @@ add_meta_data( Aircraft.Instruments.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WIN', 'MISWT.WIN', 'MISWT.OIN'], - "FLOPS": 'WTIN.WIN', - "LEAPS1": 'aircraft.inputs.L0_overrides.instrument_group_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WIN', 'MISWT.WIN', 'MISWT.OIN'], + "FLOPS": 'WTIN.WIN', + "LEAPS1": 'aircraft.inputs.L0_overrides.instrument_group_weight', + }, units='unitless', desc='mass scaler of the instrument group', default_value=1.0, @@ -3884,14 +3845,15 @@ add_meta_data( Aircraft.LandingGear.CARRIER_BASED, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.CARBAS', # ['&DEFINE.WTIN.CARBAS', 'FAWT.CARBAS'], - "LEAPS1": 'aircraft.inputs.L0_landing_gear.carrier_based' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.CARBAS', # ['&DEFINE.WTIN.CARBAS', 'FAWT.CARBAS'], + "LEAPS1": 'aircraft.inputs.L0_landing_gear.carrier_based', + }, units='unitless', desc='carrier based aircraft switch, affects mass of flight crew, ' - 'avionics, and nose gear where true is carrier based and false is land ' - 'based', + 'avionics, and nose gear where true is carrier based and false is land ' + 'based', option=True, types=bool, default_value=False, @@ -3904,26 +3866,30 @@ # ['&DEFTOL.TOLIN.CDGEAR', '~DEFTOL.CDGEAR', 'ROTDAT.CDGEAR'], 'FLOPS': 'TOLIN.CDGEAR', 'GASP': None, - 'LEAPS1': None}, + 'LEAPS1': None, + }, option=True, - default_value=0., + default_value=0.0, units='unitless', - desc='landing gear drag coefficient') + desc='landing gear drag coefficient', +) add_meta_data( - Aircraft.LandingGear.FIXED_GEAR, meta_data=_MetaData, + Aircraft.LandingGear.FIXED_GEAR, + meta_data=_MetaData, historical_name={"GASP": 'INGASP.IGEAR', "FLOPS": None, "LEAPS1": None}, - option=True, default_value=True, types=bool, units="unitless", - desc='Type of landing gear. In GASP, 0 is retractable and 1 is deployed (fixed). Here, ' - 'false is retractable and true is deployed (fixed).',) + option=True, + default_value=True, + types=bool, + units="unitless", + desc='Type of landing gear. In GASP, 0 is retractable and 1 is fixed. Here, ' + 'false is retractable and true is fixed.', +) add_meta_data( Aircraft.LandingGear.MAIN_GEAR_LOCATION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.YMG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.YMG', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='span fraction of main gear on wing (0=on fuselage, 1=at tip)', default_value=0, @@ -3934,33 +3900,32 @@ # - see also: Aircraft.LandingGear.MAIN_GEAR_MASS_SCALER Aircraft.LandingGear.MAIN_GEAR_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'INI.WLGM', - "LEAPS1": '(WeightABC)self._landing_gear_main_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'INI.WLGM', + "LEAPS1": '(WeightABC)self._landing_gear_main_weight', + }, units='lbm', - desc='mass of main landing gear' + desc='mass of main landing gear', ) add_meta_data( Aircraft.LandingGear.MAIN_GEAR_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKMG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKMG', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of main gear, fraction of total landing gear', - default_value=.85, + default_value=0.85, ) add_meta_data( Aircraft.LandingGear.MAIN_GEAR_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRLGM', # ['&DEFINE.WTIN.FRLGM', 'WTS.FRLGM'], - "LEAPS1": 'aircraft.inputs.L0_overrides.landing_gear_main_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRLGM', # ['&DEFINE.WTIN.FRLGM', 'WTS.FRLGM'], + "LEAPS1": 'aircraft.inputs.L0_overrides.landing_gear_main_weight', + }, units='unitless', desc='mass scaler of the main landing gear structure', default_value=1.0, @@ -3969,13 +3934,15 @@ add_meta_data( Aircraft.LandingGear.MAIN_GEAR_OLEO_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.XMLG', # ['&DEFINE.WTIN.XMLG', 'WTS.XMLG'], - "LEAPS1": ['aircraft.inputs.L0_landing_gear.extend_main_gear_oleo_len', - 'aircraft.outputs.L0_landing_gear.extend_main_gear_oleo_len', - 'aircraft.cached.L0_landing_gear.extend_main_gear_oleo_len', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.XMLG', # ['&DEFINE.WTIN.XMLG', 'WTS.XMLG'], + "LEAPS1": [ + 'aircraft.inputs.L0_landing_gear.extend_main_gear_oleo_len', + 'aircraft.outputs.L0_landing_gear.extend_main_gear_oleo_len', + 'aircraft.cached.L0_landing_gear.extend_main_gear_oleo_len', + ], + }, units='inch', desc='length of extended main landing gear oleo', default_value=0.0, @@ -3984,10 +3951,7 @@ add_meta_data( Aircraft.LandingGear.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKLG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKLG', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of landing gear', ) @@ -3997,10 +3961,11 @@ # - see also: Aircraft.LandingGear.NOSE_GEAR_MASS_SCALER Aircraft.LandingGear.NOSE_GEAR_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.WLGN', - "LEAPS1": '(WeightABC)self._landing_gear_nose_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.WLGN', + "LEAPS1": '(WeightABC)self._landing_gear_nose_weight', + }, units='lbm', desc='mass of nose landing gear', default_value=None, @@ -4009,10 +3974,11 @@ add_meta_data( Aircraft.LandingGear.NOSE_GEAR_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRLGN', # ['&DEFINE.WTIN.FRLGN', 'WTS.FRLGN'], - "LEAPS1": 'aircraft.inputs.L0_overrides.landing_gear_nose_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRLGN', # ['&DEFINE.WTIN.FRLGN', 'WTS.FRLGN'], + "LEAPS1": 'aircraft.inputs.L0_overrides.landing_gear_nose_weight', + }, units='unitless', desc='mass scaler of the nose landing gear structure', default_value=1.0, @@ -4021,13 +3987,15 @@ add_meta_data( Aircraft.LandingGear.NOSE_GEAR_OLEO_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.XNLG', # ['&DEFINE.WTIN.XNLG', 'WTS.XNLG'], - "LEAPS1": ['aircraft.inputs.L0_landing_gear.extend_nose_gear_oleo_len', - 'aircraft.outputs.L0_landing_gear.extend_nose_gear_oleo_len', - 'aircraft.cached.L0_landing_gear.extend_nose_gear_oleo_len', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.XNLG', # ['&DEFINE.WTIN.XNLG', 'WTS.XNLG'], + "LEAPS1": [ + 'aircraft.inputs.L0_landing_gear.extend_nose_gear_oleo_len', + 'aircraft.outputs.L0_landing_gear.extend_nose_gear_oleo_len', + 'aircraft.cached.L0_landing_gear.extend_nose_gear_oleo_len', + ], + }, units='inch', desc='length of extended nose landing gear oleo', default_value=0.0, @@ -4036,10 +4004,7 @@ add_meta_data( Aircraft.LandingGear.TAIL_HOOK_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKTL', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKTL', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='factor on tail mass for arresting hook', default_value=1, @@ -4048,10 +4013,7 @@ add_meta_data( Aircraft.LandingGear.TOTAL_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WLG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WLG', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of landing gear', default_value=0, @@ -4060,10 +4022,7 @@ add_meta_data( Aircraft.LandingGear.TOTAL_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CK12', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CK12', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='technology factor on landing gear mass', default_value=1, @@ -4080,12 +4039,13 @@ add_meta_data( Aircraft.Nacelle.AVG_DIAMETER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DBARN', - "FLOPS": 'WTIN.DNAC', # ['&DEFINE.WTIN.DNAC', 'EDETIN.DNAC'], - "LEAPS1": 'aircraft.inputs.L0_engine.nacelle_avg_diam' - }, + historical_name={ + "GASP": 'INGASP.DBARN', + "FLOPS": 'WTIN.DNAC', # ['&DEFINE.WTIN.DNAC', 'EDETIN.DNAC'], + "LEAPS1": 'aircraft.inputs.L0_engine.nacelle_avg_diam', + }, units='ft', - desc='Average diameter of engine nacelles for each engine model' + desc='Average diameter of engine nacelles for each engine model', ) add_meta_data( @@ -4093,34 +4053,34 @@ meta_data=_MetaData, # NOTE this is not specified as an average in GASP, but calculations make # it appear to be one - historical_name={"GASP": 'INGASP.ELN', - "FLOPS": 'WTIN.XNAC', # ['&DEFINE.WTIN.XNAC', 'EDETIN.XNAC'], - "LEAPS1": 'aircraft.inputs.L0_engine.nacelle_avg_length' - }, + historical_name={ + "GASP": 'INGASP.ELN', + "FLOPS": 'WTIN.XNAC', # ['&DEFINE.WTIN.XNAC', 'EDETIN.XNAC'], + "LEAPS1": 'aircraft.inputs.L0_engine.nacelle_avg_length', + }, units='ft', - desc='Average length of nacelles for each engine model' + desc='Average length of nacelles for each engine model', ) add_meta_data( Aircraft.Nacelle.CHARACTERISTIC_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL[5]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[4]', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[4]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL[5]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[4]', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[4]', + ], + }, units='ft', - desc='Reynolds characteristic length for nacelle for each engine model' + desc='Reynolds characteristic length for nacelle for each engine model', ) add_meta_data( Aircraft.Nacelle.CLEARANCE_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CLEARqDN', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CLEARqDN', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='the minimum number of nacelle diameters above the ground that the bottom of the nacelle must be', default_value=0.2, @@ -4129,10 +4089,7 @@ add_meta_data( Aircraft.Nacelle.CORE_DIAMETER_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DNQDE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DNQDE', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='ratio of nacelle diameter to engine core diameter', default_value=1.25, @@ -4141,34 +4098,35 @@ add_meta_data( Aircraft.Nacelle.FINENESS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.XLQDE', - "FLOPS": None, # 'MISSA.FR[5]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[4]', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[4]', - ] - }, + historical_name={ + "GASP": 'INGASP.XLQDE', + "FLOPS": None, # 'MISSA.FR[5]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[4]', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[4]', + ], + }, units='unitless', - desc='nacelle fineness ratio' + desc='nacelle fineness ratio', ) add_meta_data( Aircraft.Nacelle.FORM_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKN', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKN', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='nacelle form factor', + default_value=1.5, ) add_meta_data( Aircraft.Nacelle.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRLN', # ['&DEFINE.AERIN.TRLN', 'XLAM.TRLN', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.nacelle_percent_laminar_flow_lower_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRLN', # ['&DEFINE.AERIN.TRLN', 'XLAM.TRLN', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.nacelle_percent_laminar_flow_lower_surface', + }, units='unitless', desc='define percent laminar flow for nacelle lower surface for each engine model', default_value=0.0, @@ -4177,10 +4135,11 @@ add_meta_data( Aircraft.Nacelle.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRUN', # ['&DEFINE.AERIN.TRUN', 'XLAM.TRUN', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.nacelle_percent_laminar_flow_upper_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRUN', # ['&DEFINE.AERIN.TRUN', 'XLAM.TRUN', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.nacelle_percent_laminar_flow_upper_surface', + }, units='unitless', desc='define percent laminar flow for nacelle upper surface for each engine model', default_value=0.0, @@ -4191,13 +4150,15 @@ # - see also: Aircraft.Nacelle.MASS_SCALER Aircraft.Nacelle.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(8, 2)', '~WEIGHT.WNAC', '~WTSTAT.WSP(8, 2)', '~INERT.WNAC'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._nacelle_weight', - 'aircraft.outputs.L0_weights_summary.nacelle_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(8, 2)', '~WEIGHT.WNAC', '~WTSTAT.WSP(8, 2)', '~INERT.WNAC'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._nacelle_weight', + 'aircraft.outputs.L0_weights_summary.nacelle_weight', + ], + }, units='lbm', desc='estimated mass of the nacelles for each engine model', default_value=None, @@ -4206,10 +4167,11 @@ add_meta_data( Aircraft.Nacelle.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRNA', # ['&DEFINE.WTIN.FRNA', 'WTS.FRNA'], - "LEAPS1": 'aircraft.inputs.L0_overrides.nacelle_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRNA', # ['&DEFINE.WTIN.FRNA', 'WTS.FRNA'], + "LEAPS1": 'aircraft.inputs.L0_overrides.nacelle_weight', + }, units='unitless', desc='mass scaler of the nacelle structure for each engine model', default_value=1.0, @@ -4218,10 +4180,7 @@ add_meta_data( Aircraft.Nacelle.MASS_SPECIFIC, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.UWNAC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.UWNAC', "FLOPS": None, "LEAPS1": None}, units='lbm/ft**2', desc='nacelle mass/nacelle surface area; lbm per sq ft.', default_value=0.0, @@ -4230,49 +4189,50 @@ add_meta_data( Aircraft.Nacelle.SURFACE_AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SN', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SN', "FLOPS": None, "LEAPS1": None}, units='ft**2', desc='surface area of the outside of one entire nacelle, ' - 'not just the wetted area', + 'not just the wetted area', ) add_meta_data( Aircraft.Nacelle.TOTAL_WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'ACTWET.SWTNA', - "LEAPS1": 'aircraft.outputs.L0_aerodynamics.nacelle_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'ACTWET.SWTNA', + "LEAPS1": 'aircraft.outputs.L0_aerodynamics.nacelle_wetted_area', + }, units='ft**2', - desc='total nacelles wetted area' + desc='total nacelles wetted area', ) add_meta_data( Aircraft.Nacelle.WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.SWET[5]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table[4]', - 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table[4]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.SWET[5]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table[4]', + 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table[4]', + ], + }, units='ft**2', - desc='wetted area of a single nacelle for each engine model' + desc='wetted area of a single nacelle for each engine model', ) add_meta_data( Aircraft.Nacelle.WETTED_AREA_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.SWETN', # ['&DEFINE.AERIN.SWETN', 'AWETO.SWETN', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.nacelle_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.SWETN', # ['&DEFINE.AERIN.SWETN', 'AWETO.SWETN', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.nacelle_wetted_area', + }, units='unitless', desc='nacelle wetted area scaler for each engine model', - default_value=1.0 + default_value=1.0, ) # _____ _ _ @@ -4286,23 +4246,26 @@ add_meta_data( Aircraft.Paint.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'DARM.WTPNT', - "LEAPS1": ['(WeightABC)self._total_paint_weight', - 'aircraft.outputs.L0_weights_summary.total_paint_weight', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'DARM.WTPNT', + "LEAPS1": [ + '(WeightABC)self._total_paint_weight', + 'aircraft.outputs.L0_weights_summary.total_paint_weight', + ], + }, units='lbm', - desc='mass of paint for all wetted area' + desc='mass of paint for all wetted area', ) add_meta_data( Aircraft.Paint.MASS_PER_UNIT_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.WPAINT', # ['&DEFINE.WTIN.WPAINT', 'DARM.WPAINT'], - "LEAPS1": 'aircraft.inputs.L0_weights.paint_per_unit_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.WPAINT', # ['&DEFINE.WTIN.WPAINT', 'DARM.WPAINT'], + "LEAPS1": 'aircraft.inputs.L0_weights.paint_per_unit_area', + }, units='lbm/ft**2', desc='mass of paint per unit area for all wetted area', default_value=0.0, @@ -4322,11 +4285,12 @@ add_meta_data( Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WOIL', 'MISWT.WOIL', 'MISWT.OOIL'], - "FLOPS": 'WTIN.WOIL', - "LEAPS1": 'aircraft.inputs.L0_overrides.engine_oil_weight' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WOIL', 'MISWT.WOIL', 'MISWT.OOIL'], + "FLOPS": 'WTIN.WOIL', + "LEAPS1": 'aircraft.inputs.L0_overrides.engine_oil_weight', + }, units='unitless', desc='Scaler for engine oil mass', default_value=1.0, @@ -4335,52 +4299,49 @@ add_meta_data( Aircraft.Propulsion.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(15, 2)', '~WEIGHT.WPRO', '~WTSTAT.WSP(15, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._prop_sys_weight', - 'aircraft.outputs.L0_weights_summary.prop_sys_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(15, 2)', '~WEIGHT.WPRO', '~WTSTAT.WSP(15, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._prop_sys_weight', + 'aircraft.outputs.L0_weights_summary.prop_sys_weight', + ], + }, units='lbm', - desc='Total propulsion group mass' + desc='Total propulsion group mass', ) # TODO clash with per-engine scaling, need to resolve w/ heterogeneous engine add_meta_data( Aircraft.Propulsion.MISC_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.WPMSC', 'MISWT.WPMSC', 'MISWT.OPMSC'], - "FLOPS": 'WTIN.WPMSC', - "LEAPS1": ['aircraft.inputs.L0_overrides.misc_propulsion_weight'] - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.WPMSC', 'MISWT.WPMSC', 'MISWT.OPMSC'], + "FLOPS": 'WTIN.WPMSC', + "LEAPS1": ['aircraft.inputs.L0_overrides.misc_propulsion_weight'], + }, units='unitless', desc='scaler applied to miscellaneous engine mass (sum of engine control, starter, ' - 'and additional mass)', + 'and additional mass)', default_value=1.0, ) add_meta_data( Aircraft.Propulsion.TOTAL_ENGINE_CONTROLS_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='total estimated mass of the engine controls for all engines on aircraft' + desc='total estimated mass of the engine controls for all engines on aircraft', ) add_meta_data( Aircraft.Propulsion.TOTAL_ENGINE_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WEP', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WEP', "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='total mass of all engines on aircraft' + desc='total mass of all engines on aircraft', ) add_meta_data( @@ -4388,13 +4349,15 @@ # - see also: Aircraft.Propulsion.ENGINE_OIL_MASS_SCALER Aircraft.Propulsion.TOTAL_ENGINE_OIL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(30, 2)', '~WEIGHT.WOIL', '~WTSTAT.WSP(30, 2)', '~INERT.WOIL'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._engine_oil_weight', - 'aircraft.outputs.L0_weights_summary.engine_oil_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(30, 2)', '~WEIGHT.WOIL', '~WTSTAT.WSP(30, 2)', '~INERT.WOIL'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._engine_oil_weight', + 'aircraft.outputs.L0_weights_summary.engine_oil_weight', + ], + }, units='lbm', desc='engine oil mass', default_value=None, @@ -4403,12 +4366,9 @@ add_meta_data( Aircraft.Propulsion.TOTAL_ENGINE_POD_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='total engine pod mass for all engines on aircraft' + desc='total engine pod mass for all engines on aircraft', ) add_meta_data( @@ -4416,26 +4376,19 @@ # - see also: Aircraft.Propulsion.MISC_WEIGHT_SCALER Aircraft.Propulsion.TOTAL_MISC_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='sum of engine control, starter, and additional mass for all engines ' - 'on aircraft', + 'on aircraft', default_value=None, ) add_meta_data( Aircraft.Propulsion.TOTAL_NUM_ENGINES, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', - desc='total number of engines for the aircraft ' - '(fuselage, wing, or otherwise)', + desc='total number of engines for the aircraft ' '(fuselage, wing, or otherwise)', types=int, option=True, default_value=None, @@ -4444,10 +4397,7 @@ add_meta_data( Aircraft.Propulsion.TOTAL_NUM_FUSELAGE_ENGINES, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='total number of fuselage-mounted engines for the aircraft', types=int, @@ -4458,10 +4408,7 @@ add_meta_data( Aircraft.Propulsion.TOTAL_NUM_WING_ENGINES, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='total number of wing-mounted engines for the aircraft', types=int, @@ -4472,10 +4419,7 @@ add_meta_data( Aircraft.Propulsion.TOTAL_REFERENCE_SLS_THRUST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbf', desc='total maximum thrust of all unscalsed engines on aircraft, sea-level static', option=True, @@ -4485,10 +4429,7 @@ add_meta_data( Aircraft.Propulsion.TOTAL_SCALED_SLS_THRUST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbf', desc='total maximum thrust of all scaled engines on aircraft, sea-level static', default_value=0.0, @@ -4497,10 +4438,7 @@ add_meta_data( Aircraft.Propulsion.TOTAL_STARTER_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of starters for all engines on aircraft', default_value=0.0, @@ -4511,10 +4449,7 @@ # - see also: Aircraft.Engine.THRUST_REVERSERS_MASS_SCALER Aircraft.Propulsion.TOTAL_THRUST_REVERSERS_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total mass of thrust reversers for all engines on aircraft', default_value=None, @@ -4531,10 +4466,7 @@ add_meta_data( Aircraft.Strut.AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.STRTWS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.STRTWS', "FLOPS": None, "LEAPS1": None}, units='ft**2', desc='strut area', default_value=0, @@ -4543,10 +4475,7 @@ add_meta_data( Aircraft.Strut.AREA_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SSTQSW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SSTQSW', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='ratio of strut area to wing area', ) @@ -4554,10 +4483,11 @@ add_meta_data( Aircraft.Strut.ATTACHMENT_LOCATION, meta_data=_MetaData, - historical_name={"GASP": ['INGASP.STRUT', 'INGASP.STRUTX', 'INGASP.XSTRUT'], - "FLOPS": None, - "LEAPS1": None - }, + historical_name={ + "GASP": ['INGASP.STRUT', 'INGASP.STRUTX', 'INGASP.XSTRUT'], + "FLOPS": None, + "LEAPS1": None, + }, units='ft', desc='attachment location of strut the full attachment-to-attachment span', ) @@ -4566,10 +4496,7 @@ add_meta_data( Aircraft.Strut.ATTACHMENT_LOCATION_DIMENSIONLESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='attachment location of strut as fraction of the half-span', ) @@ -4577,10 +4504,7 @@ add_meta_data( Aircraft.Strut.CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.STRTCHD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.STRTCHD', "FLOPS": None, "LEAPS1": None}, units='ft', desc='chord of the strut', ) @@ -4588,36 +4512,28 @@ add_meta_data( Aircraft.Strut.DIMENSIONAL_LOCATION_SPECIFIED, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", option=True, default_value=True, types=bool, desc='if true the location of the strut is given dimensionally, otherwise ' - 'it is given non-dimensionally. In GASP this depended on STRUT', + 'it is given non-dimensionally. In GASP this depended on STRUT', ) add_meta_data( Aircraft.Strut.FUSELAGE_INTERFERENCE_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKSTRT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKSTRT', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='strut/fuselage interference factor', + default_value=0.0, ) add_meta_data( Aircraft.Strut.LENGTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.STRTLNG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.STRTLNG', "FLOPS": None, "LEAPS1": None}, units='ft', desc='length of the strut', default_value=0, @@ -4626,10 +4542,7 @@ add_meta_data( Aircraft.Strut.MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WSTRUT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WSTRUT', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of the strut', default_value=0, @@ -4638,10 +4551,7 @@ add_meta_data( Aircraft.Strut.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKSTRUT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKSTRUT', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of the strut', default_value=0, @@ -4650,10 +4560,7 @@ add_meta_data( Aircraft.Strut.THICKNESS_TO_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TCSTRT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.TCSTRT', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='thickness to chord ratio of the strut', default_value=0, @@ -4670,10 +4577,7 @@ add_meta_data( Aircraft.TailBoom.LENGTH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELFFC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ELFFC', "FLOPS": None, "LEAPS1": None}, units='ft', desc='cabin length for the tail boom fuselage', ) @@ -4690,15 +4594,17 @@ add_meta_data( Aircraft.VerticalTail.AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SVT', - "FLOPS": 'WTIN.SVT', # ['&DEFINE.WTIN.SVT', 'EDETIN.SVT'], - "LEAPS1": ['aircraft.inputs.L0_vertical_tails.area', - 'aircraft.cached.L0_vertical_tails.area', - ] - }, + historical_name={ + "GASP": 'INGASP.SVT', + "FLOPS": 'WTIN.SVT', # ['&DEFINE.WTIN.SVT', 'EDETIN.SVT'], + "LEAPS1": [ + 'aircraft.inputs.L0_vertical_tails.area', + 'aircraft.cached.L0_vertical_tails.area', + ], + }, units='ft**2', desc='vertical tail theoretical area (per tail); overridden by vol_coeff ' - 'if vol_coeff > 0.0', + 'if vol_coeff > 0.0', # this appears to never be calculated in Aviary, need to make user aware # of Aviary overriding support default_value=0.0, @@ -4707,13 +4613,15 @@ add_meta_data( Aircraft.VerticalTail.ASPECT_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ARVT', - "FLOPS": 'WTIN.ARVT', # ['&DEFINE.WTIN.ARVT', 'EDETIN.ARVT'], - "LEAPS1": ['aircraft.inputs.L0_vertical_tails.aspect_ratio', - # ??? where is this assigned; potential error??? - 'aircraft.cached.L0_vertical_tails.aspect_ratio', - ] - }, + historical_name={ + "GASP": 'INGASP.ARVT', + "FLOPS": 'WTIN.ARVT', # ['&DEFINE.WTIN.ARVT', 'EDETIN.ARVT'], + "LEAPS1": [ + 'aircraft.inputs.L0_vertical_tails.aspect_ratio', + # ??? where is this assigned; potential error??? + 'aircraft.cached.L0_vertical_tails.aspect_ratio', + ], + }, units='unitless', desc='vertical tail theoretical aspect ratio', default_value=None, @@ -4722,10 +4630,7 @@ add_meta_data( Aircraft.VerticalTail.AVERAGE_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CBARVT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CBARVT', "FLOPS": None, "LEAPS1": None}, units='ft', desc='mean aerodynamic chord of vertical tail', ) @@ -4733,47 +4638,50 @@ add_meta_data( Aircraft.VerticalTail.CHARACTERISTIC_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL[3]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[2]', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[2]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL[3]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[2]', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[2]', + ], + }, units='ft', - desc='Reynolds characteristic length for the vertical tail' + desc='Reynolds characteristic length for the vertical tail', ) add_meta_data( Aircraft.VerticalTail.FINENESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.FR[3]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[2]', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[2]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.FR[3]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[2]', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[2]', + ], + }, units='unitless', - desc='vertical tail fineness ratio' + desc='vertical tail fineness ratio', ) add_meta_data( Aircraft.VerticalTail.FORM_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKVT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKVT', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='vertical tail form factor', + default_value=1.25, ) add_meta_data( Aircraft.VerticalTail.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRLV', # ['&DEFINE.AERIN.TRLV', 'XLAM.TRLV', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.vertical_tail_percent_laminar_flow_lower_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRLV', # ['&DEFINE.AERIN.TRLV', 'XLAM.TRLV', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.vertical_tail_percent_laminar_flow_lower_surface', + }, units='unitless', desc='define percent laminar flow for vertical tail lower surface', default_value=0.0, @@ -4782,10 +4690,11 @@ add_meta_data( Aircraft.VerticalTail.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRUV', # ['&DEFINE.AERIN.TRUV', 'XLAM.TRUV', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.vertical_tail_percent_laminar_flow_upper_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRUV', # ['&DEFINE.AERIN.TRUV', 'XLAM.TRUV', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.vertical_tail_percent_laminar_flow_upper_surface', + }, units='unitless', desc='define percent laminar flow for vertical tail upper surface', default_value=0.0, @@ -4796,13 +4705,15 @@ # - see also: Aircraft.VerticalTail.MASS_SCALER Aircraft.VerticalTail.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(3, 2)', '~WEIGHT.WVT', '~WTSTAT.WSP(3, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._vertical_tail_weight', - 'aircraft.outputs.L0_weights_summary.vertical_tail_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(3, 2)', '~WEIGHT.WVT', '~WTSTAT.WSP(3, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._vertical_tail_weight', + 'aircraft.outputs.L0_weights_summary.vertical_tail_weight', + ], + }, units='lbm', desc='mass of vertical tail', default_value=None, @@ -4811,10 +4722,7 @@ add_meta_data( Aircraft.VerticalTail.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKZ', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKZ', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of the vertical tail', default_value=0.22, @@ -4823,10 +4731,11 @@ add_meta_data( Aircraft.VerticalTail.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRVT', # ['&DEFINE.WTIN.FRVT', 'WTS.FRVT'], - "LEAPS1": 'aircraft.inputs.L0_overrides.vertical_tail_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRVT', # ['&DEFINE.WTIN.FRVT', 'WTS.FRVT'], + "LEAPS1": 'aircraft.inputs.L0_overrides.vertical_tail_weight', + }, units='unitless', desc='mass scaler of the vertical tail structure', default_value=1.0, @@ -4835,10 +4744,7 @@ add_meta_data( Aircraft.VerticalTail.MOMENT_ARM, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ELTV', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ELTV', "FLOPS": None, "LEAPS1": None}, units='ft', desc='moment arm of vertical tail', ) @@ -4846,10 +4752,7 @@ add_meta_data( Aircraft.VerticalTail.MOMENT_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.BOELTV', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.BOELTV', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='ratio of wing span to vertical tail moment arm', ) @@ -4857,10 +4760,11 @@ add_meta_data( Aircraft.VerticalTail.NUM_TAILS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.NVERT', # ['&DEFINE.WTIN.NVERT', 'EDETIN.NVERT'], - "LEAPS1": 'aircraft.inputs.L0_vertical_tails.count' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.NVERT', # ['&DEFINE.WTIN.NVERT', 'EDETIN.NVERT'], + "LEAPS1": 'aircraft.inputs.L0_vertical_tails.count', + }, units='unitless', desc='number of vertical tails', types=int, @@ -4871,10 +4775,7 @@ add_meta_data( Aircraft.VerticalTail.ROOT_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CRCLVT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CRCLVT', "FLOPS": None, "LEAPS1": None}, units='ft', desc='root chord of vertical tail', ) @@ -4882,10 +4783,7 @@ add_meta_data( Aircraft.VerticalTail.SPAN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.BVT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.BVT', "FLOPS": None, "LEAPS1": None}, units='ft', desc='span of vertical tail', ) @@ -4893,12 +4791,14 @@ add_meta_data( Aircraft.VerticalTail.SWEEP, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DWPQCV', - "FLOPS": 'WTIN.SWPVT', # ['&DEFINE.WTIN.SWPVT', 'WTS.SWPVT'], - "LEAPS1": ['aircraft.inputs.L0_vertical_tail.sweep_at_quarter_chord', - 'aircraft.cached.L0_vertical_tail.sweep_at_quarter_chord' - ] - }, + historical_name={ + "GASP": 'INGASP.DWPQCV', + "FLOPS": 'WTIN.SWPVT', # ['&DEFINE.WTIN.SWPVT', 'WTS.SWPVT'], + "LEAPS1": [ + 'aircraft.inputs.L0_vertical_tail.sweep_at_quarter_chord', + 'aircraft.cached.L0_vertical_tail.sweep_at_quarter_chord', + ], + }, units='deg', desc='quarter-chord sweep of vertical tail', ) @@ -4906,10 +4806,11 @@ add_meta_data( Aircraft.VerticalTail.TAPER_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SLMV', - "FLOPS": 'WTIN.TRVT', # ['&DEFINE.WTIN.TRVT', 'EDETIN.TRVT'], - "LEAPS1": 'aircraft.inputs.L0_vertical_tails.taper_ratio' - }, + historical_name={ + "GASP": 'INGASP.SLMV', + "FLOPS": 'WTIN.TRVT', # ['&DEFINE.WTIN.TRVT', 'EDETIN.TRVT'], + "LEAPS1": 'aircraft.inputs.L0_vertical_tails.taper_ratio', + }, units='unitless', desc='vertical tail theoretical taper ratio', default_value=None, @@ -4918,12 +4819,14 @@ add_meta_data( Aircraft.VerticalTail.THICKNESS_TO_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TCVT', - "FLOPS": 'WTIN.TCVT', # ['&DEFINE.WTIN.TCVT', 'EDETIN.TCVT', ], - "LEAPS1": ['aircraft.inputs.L0_vertical_tails.thickness_to_chord_ratio', - 'aircraft.cached.L0_vertical_tails.thickness_to_chord_ratio', - ] - }, + historical_name={ + "GASP": 'INGASP.TCVT', + "FLOPS": 'WTIN.TCVT', # ['&DEFINE.WTIN.TCVT', 'EDETIN.TCVT', ], + "LEAPS1": [ + 'aircraft.inputs.L0_vertical_tails.thickness_to_chord_ratio', + 'aircraft.cached.L0_vertical_tails.thickness_to_chord_ratio', + ], + }, units='unitless', desc='vertical tail thickness-chord ratio', default_value=0.0, @@ -4932,10 +4835,7 @@ add_meta_data( Aircraft.VerticalTail.VOLUME_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.VBARVX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.VBARVX', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='tail volume coefficient of the vertical tail', ) @@ -4945,13 +4845,15 @@ # - see also: Aircraft.VerticalTail.WETTED_AREA_SCALER Aircraft.VerticalTail.WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['ACTWET.SWTVT', 'MISSA.SWET[3]', ], - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.vertical_tail_wetted_area', - 'aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table[2]', - 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table[2]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['ACTWET.SWTVT', 'MISSA.SWET[3]', ], + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.vertical_tail_wetted_area', + 'aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table[2]', + 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table[2]', + ], + }, units='ft**2', desc='vertical tails wetted area', default_value=None, @@ -4960,10 +4862,11 @@ add_meta_data( Aircraft.VerticalTail.WETTED_AREA_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.SWETV', # ['&DEFINE.AERIN.SWETV', 'AWETO.SWETV', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.vertical_tail_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.SWETV', # ['&DEFINE.AERIN.SWETV', 'AWETO.SWETV', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.vertical_tail_wetted_area', + }, units='unitless', desc='vertical tail wetted area scaler', default_value=1.0, @@ -4982,37 +4885,40 @@ add_meta_data( Aircraft.Wing.AEROELASTIC_TAILORING_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.FAERT', 'WTS.FAERT', '~WWGHT.FAERT', '~BNDMAT.FAERT'], - "FLOPS": 'WTIN.FAERT', - "LEAPS1": 'aircraft.inputs.L0_wing.aeroelastic_fraction' - }, - units='unitless', + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.FAERT', 'WTS.FAERT', '~WWGHT.FAERT', '~BNDMAT.FAERT'], + "FLOPS": 'WTIN.FAERT', + "LEAPS1": 'aircraft.inputs.L0_wing.aeroelastic_fraction', + }, + units='unitless', desc='Define the decimal fraction of amount of aeroelastic tailoring used ' - 'in design of wing where: 0.0 == no aeroelastic tailoring; ' - '1.0 == maximum aeroelastic tailoring.', + 'in design of wing where: 0.0 == no aeroelastic tailoring; ' + '1.0 == maximum aeroelastic tailoring.', default_value=0.0, ) add_meta_data( Aircraft.Wing.AIRFOIL_TECHNOLOGY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.AITEK', - # [ # inputs - # '&DEFINE.AERIN.AITEK', 'EDETIN.AITEK', - # # outputs - # 'MISSA.AITEK', 'MISSA.AITEKX', - # ], - "LEAPS1": ['aircraft.inputs.L0_aerodynamics.airfoil', - 'aircraft.outputs.L0_aerodynamics.mission_airfoil', - 'aircraft.cached.L0_aerodynamics.mission_airfoil', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.AITEK', + # [ # inputs + # '&DEFINE.AERIN.AITEK', 'EDETIN.AITEK', + # # outputs + # 'MISSA.AITEK', 'MISSA.AITEKX', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_aerodynamics.airfoil', + 'aircraft.outputs.L0_aerodynamics.mission_airfoil', + 'aircraft.cached.L0_aerodynamics.mission_airfoil', + ], + }, units='unitless', desc='Airfoil technology parameter. Limiting values are: 1.0 represents ' - 'conventional technology wing (Default); 2.0 represents advanced ' - 'technology wing.', + 'conventional technology wing (Default); 2.0 represents advanced ' + 'technology wing.', default_value=1.0, option=True, ) @@ -5020,21 +4926,23 @@ add_meta_data( Aircraft.Wing.AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SW', - "FLOPS": 'CONFIN.SW', - # [ # inputs - # '&DEFINE.CONFIN.SW', 'PARVAR.DVD(1,4)', - # # outputs - # 'CONFIG.SW', 'CONFIG.DVA(4)', '~FLOPS.DVA(4)', '~ANALYS.DVA(4)', - # '~TOFF.SW', '~LNDING.SW', '~PROFIL.SW', '~INMDAT.SW', '~WWGHT.SW', - # # other - # 'MISSA.SREF', '~CDCC.SREF', - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.wing_ref_area', - 'aircraft.outputs.L0_design_variables.wing_ref_area', - 'aircraft.outputs.L0_design_variables.mission_wing_ref_area', - ] - }, + historical_name={ + "GASP": 'INGASP.SW', + "FLOPS": 'CONFIN.SW', + # [ # inputs + # '&DEFINE.CONFIN.SW', 'PARVAR.DVD(1,4)', + # # outputs + # 'CONFIG.SW', 'CONFIG.DVA(4)', '~FLOPS.DVA(4)', '~ANALYS.DVA(4)', + # '~TOFF.SW', '~LNDING.SW', '~PROFIL.SW', '~INMDAT.SW', '~WWGHT.SW', + # # other + # 'MISSA.SREF', '~CDCC.SREF', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.wing_ref_area', + 'aircraft.outputs.L0_design_variables.wing_ref_area', + 'aircraft.outputs.L0_design_variables.mission_wing_ref_area', + ], + }, units='ft**2', desc='reference wing area', default_value=0.0, @@ -5043,22 +4951,24 @@ add_meta_data( Aircraft.Wing.ASPECT_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.AR', - "FLOPS": 'CONFIN.AR', - # [ # inputs - # '&DEFINE.CONFIN.AR', 'PARVAR.DVD(1, 2)', '~BUFFET.AR', '~CDPP.AR', - # '~DPREP.ARX', - # # outputs - # 'CONFIG.AR', 'CONFIG.DVA(2)', '~FLOPS.DVA(2)', '~ANALYS.DVA(2)', - # '~TOFF.ARN', '~LNDING.ARN', '~PROFIL.ARN', '~WWGHT.ARN', '~INERT.ARN', - # # other - # 'MISSA.AR', 'MISSA.ARX', '~CDCC.AR', '~CLDESN.AR', '~MDESN.AR', - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.wing_aspect_ratio', - 'aircraft.outputs.L0_design_variables.wing_aspect_ratio', - 'aircraft.outputs.L0_design_variables.mission_wing_aspect_ratio', - ] - }, + historical_name={ + "GASP": 'INGASP.AR', + "FLOPS": 'CONFIN.AR', + # [ # inputs + # '&DEFINE.CONFIN.AR', 'PARVAR.DVD(1, 2)', '~BUFFET.AR', '~CDPP.AR', + # '~DPREP.ARX', + # # outputs + # 'CONFIG.AR', 'CONFIG.DVA(2)', '~FLOPS.DVA(2)', '~ANALYS.DVA(2)', + # '~TOFF.ARN', '~LNDING.ARN', '~PROFIL.ARN', '~WWGHT.ARN', '~INERT.ARN', + # # other + # 'MISSA.AR', 'MISSA.ARX', '~CDCC.AR', '~CLDESN.AR', '~MDESN.AR', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.wing_aspect_ratio', + 'aircraft.outputs.L0_design_variables.wing_aspect_ratio', + 'aircraft.outputs.L0_design_variables.mission_wing_aspect_ratio', + ], + }, units='unitless', desc='ratio of the wing span to its mean chord', default_value=0.0, @@ -5067,21 +4977,19 @@ add_meta_data( Aircraft.Wing.ASPECT_RATIO_REF, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.ARREF', # ['&DEFINE.WTIN.ARREF'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.ref_aspect_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.ARREF', # ['&DEFINE.WTIN.ARREF'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.ref_aspect_ratio', + }, units='unitless', - desc='Reference aspect ratio, used for detailed wing bending.' + desc='Reference aspect ratio, used for detailed wing bending.', ) add_meta_data( Aircraft.Wing.AVERAGE_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CBARW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CBARW', "FLOPS": None, "LEAPS1": None}, units='ft', desc='mean aerodynamic chord of the wing', ) @@ -5089,12 +4997,13 @@ add_meta_data( Aircraft.Wing.BENDING_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['~WWGHT.BT', '~BNDMAT.W'], - "LEAPS1": 'aircraft.outputs.L0_wing.bending_material_factor' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['~WWGHT.BT', '~BNDMAT.W'], + "LEAPS1": 'aircraft.outputs.L0_wing.bending_material_factor', + }, units='unitless', - desc='wing bending factor' + desc='wing bending factor', ) add_meta_data( @@ -5102,10 +5011,11 @@ # - see also: Aircraft.Wing.BENDING_MASS_SCALER Aircraft.Wing.BENDING_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WWGHT.W1', - "LEAPS1": 'aircraft.outputs.L0_wing.bending_mat_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WWGHT.W1', + "LEAPS1": 'aircraft.outputs.L0_wing.bending_mat_weight', + }, units='lbm', desc='wing mass breakdown term 1', default_value=None, @@ -5114,10 +5024,11 @@ add_meta_data( Aircraft.Wing.BENDING_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRWI1', # ['&DEFINE.WTIN.FRWI1', 'WIOR3.FRWI1'], - "LEAPS1": 'aircraft.inputs.L0_overrides.wing_bending_mat_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRWI1', # ['&DEFINE.WTIN.FRWI1', 'WIOR3.FRWI1'], + "LEAPS1": 'aircraft.inputs.L0_overrides.wing_bending_mat_weight', + }, units='unitless', desc='mass scaler of the bending wing mass term', default_value=1.0, @@ -5128,10 +5039,11 @@ # - see also: Aircraft.Wing.BWB_AFTBODY_MASS_SCALER Aircraft.Wing.BWB_AFTBODY_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WWGHT.W4', - "LEAPS1": 'aircraft.outputs.L0_wing.bwb_aft_body_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WWGHT.W4', + "LEAPS1": 'aircraft.outputs.L0_wing.bwb_aft_body_weight', + }, units='lbm', desc='wing mass breakdown term 4', default_value=None, @@ -5140,10 +5052,11 @@ add_meta_data( Aircraft.Wing.BWB_AFTBODY_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRWI4', # ['&DEFINE.WTIN.FRWI4', 'WIOR3.FRWI4'], - "LEAPS1": 'aircraft.inputs.L0_overrides.bwb_aft_body_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRWI4', # ['&DEFINE.WTIN.FRWI4', 'WIOR3.FRWI4'], + "LEAPS1": 'aircraft.inputs.L0_overrides.bwb_aft_body_weight', + }, units='unitless', desc='mass scaler of the blended-wing-body aft-body wing mass term', default_value=1.0, @@ -5152,10 +5065,7 @@ add_meta_data( Aircraft.Wing.CENTER_CHORD, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CRCLW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CRCLW', "FLOPS": None, "LEAPS1": None}, units='ft', desc='wing chord at fuselage centerline', ) @@ -5163,108 +5073,107 @@ add_meta_data( Aircraft.Wing.CENTER_DISTANCE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.XWQLF', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.XWQLF', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='distance (percent fuselage length) from nose to the wing ' - 'aerodynamic center', + 'aerodynamic center', ) add_meta_data( Aircraft.Wing.CHARACTERISTIC_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.EL[1]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[0]', - 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[0]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.EL[1]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_component_char_len_table[0]', + 'aircraft.cached.L0_aerodynamics.mission_component_char_len_table[0]', + ], + }, units='ft', - desc='Reynolds characteristic length for the wing' + desc='Reynolds characteristic length for the wing', ) add_meta_data( Aircraft.Wing.CHOOSE_FOLD_LOCATION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", default_value=True, types=bool, option=True, desc='if true, fold location is based on your chosen value, otherwise it is ' - 'based on strut location. In GASP this depended on STRUT or YWFOLD', + 'based on strut location. In GASP this depended on STRUT or YWFOLD', ) add_meta_data( # see also: station_chord_lengths Aircraft.Wing.CHORD_PER_SEMISPAN_DIST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.CHD', # ['&DEFINE.WTIN.CHD', 'WDEF.CHD'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_chord_lengths' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.CHD', # ['&DEFINE.WTIN.CHD', 'WDEF.CHD'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_chord_lengths', + }, units='unitless', desc='chord lengths as fractions of semispan at station locations; ' - 'overwrites station_chord_lengths', + 'overwrites station_chord_lengths', default_value=None, ) add_meta_data( Aircraft.Wing.COMPOSITE_FRACTION, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.FCOMP', 'WTS.FCOMP', '~WWGHT.FCOMP'], - "FLOPS": 'WTIN.FCOMP', - "LEAPS1": 'aircraft.inputs.L0_wing.composite_fraction' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.FCOMP', 'WTS.FCOMP', '~WWGHT.FCOMP'], + "FLOPS": 'WTIN.FCOMP', + "LEAPS1": 'aircraft.inputs.L0_wing.composite_fraction', + }, units='unitless', desc='Define the decimal fraction of amount of composites used in wing ' - 'structure where: 0.0 == no composites; 1.0 == maximum use of composites, ' - 'approximately equivalent bending_mat_weight=.6, ' - 'struct_weights=.83, misc_weight=.7 ' - '(not necessarily all composite).', + 'structure where: 0.0 == no composites; 1.0 == maximum use of composites, ' + 'approximately equivalent bending_mat_weight=.6, ' + 'struct_weights=.83, misc_weight=.7 ' + '(not necessarily all composite).', default_value=0.0, ) add_meta_data( Aircraft.Wing.CONTROL_SURFACE_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WEIGHT.SFLAP', # TODO ~WWGHT.SFLAP: similar, but separate calculation - "LEAPS1": ['~WeightABC._pre_surface_ctrls.surface_flap_area', # TODO ~WingWeight.__call__.flap_ratio: see ~WWGHT.SFLAP - '~WeightABC.calc_surface_ctrls.surface_flap_area', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WEIGHT.SFLAP', # TODO ~WWGHT.SFLAP: similar, but separate calculation + "LEAPS1": [ + # TODO ~WingWeight.__call__.flap_ratio: see ~WWGHT.SFLAP + '~WeightABC._pre_surface_ctrls.surface_flap_area', + '~WeightABC.calc_surface_ctrls.surface_flap_area', + ], + }, units='ft**2', - desc='area of wing control surfaces' + desc='area of wing control surfaces', ) add_meta_data( Aircraft.Wing.CONTROL_SURFACE_AREA_RATIO, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.FLAPR', 'WTS.FLAPR', '~WWGHT.FLAPR'], - "FLOPS": 'WTIN.FLAPR', - "LEAPS1": 'aircraft.inputs.L0_wing.flap_ratio' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.FLAPR', 'WTS.FLAPR', '~WWGHT.FLAPR'], + "FLOPS": 'WTIN.FLAPR', + "LEAPS1": 'aircraft.inputs.L0_wing.flap_ratio', + }, units='unitless', desc='Defines the ratio of total moveable wing control surface areas ' - '(flaps, elevators, spoilers, etc.) to reference wing area.', + '(flaps, elevators, spoilers, etc.) to reference wing area.', default_value=0.333, ) add_meta_data( Aircraft.Wing.DETAILED_WING, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='use a detailed wing model', option=True, @@ -5275,49 +5184,51 @@ add_meta_data( Aircraft.Wing.DIHEDRAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.DIH', # ['&DEFINE.WTIN.DIH', 'WTS.DIH', ], - "LEAPS1": ['aircraft.inputs.L0_wing.dihedral', - # unit converted value for reporting - 'aircraft.cached.L0_wing.dihedral', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.DIH', # ['&DEFINE.WTIN.DIH', 'WTS.DIH', ], + "LEAPS1": [ + 'aircraft.inputs.L0_wing.dihedral', + # unit converted value for reporting + 'aircraft.cached.L0_wing.dihedral', + ], + }, units='deg', desc='wing dihedral (positive) or anhedral (negative) angle', - default_value=0.0 + default_value=0.0, ) add_meta_data( Aircraft.Wing.ENG_POD_INERTIA_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WWGHT.CAYE', - "LEAPS1": 'aircraft.outputs.L0_wing.engine_inertia_relief_factor' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WWGHT.CAYE', + "LEAPS1": 'aircraft.outputs.L0_wing.engine_inertia_relief_factor', + }, units='unitless', - desc='engine inertia relief factor' + desc='engine inertia relief factor', ) add_meta_data( Aircraft.Wing.FINENESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # 'MISSA.FR[1]', - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[0]', - 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[0]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # 'MISSA.FR[1]', + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.mission_fineness_ratio_table[0]', + 'aircraft.cached.L0_aerodynamics.mission_fineness_ratio_table[0]', + ], + }, units='unitless', - desc='wing fineness ratio' + desc='wing fineness ratio', ) add_meta_data( Aircraft.Wing.FLAP_CHORD_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CFOC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CFOC', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='ratio of flap chord to wing chord', ) @@ -5325,32 +5236,23 @@ add_meta_data( Aircraft.Wing.FLAP_DEFLECTION_LANDING, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DFLPLD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DFLPLD', "FLOPS": None, "LEAPS1": None}, units='deg', - desc='Deflection of flaps for landing' + desc='Deflection of flaps for landing', ) add_meta_data( Aircraft.Wing.FLAP_DEFLECTION_TAKEOFF, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DFLPTO', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DFLPTO', "FLOPS": None, "LEAPS1": None}, units='deg', - desc='Deflection of flaps for takeoff' + desc='Deflection of flaps for takeoff', ) add_meta_data( Aircraft.Wing.FLAP_DRAG_INCREMENT_OPTIMUM, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCDOTE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCDOTE', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='drag coefficient increment due to optimally deflected trailing edge flaps (default depends on flap type)', ) @@ -5358,10 +5260,7 @@ add_meta_data( Aircraft.Wing.FLAP_LIFT_INCREMENT_OPTIMUM, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCLMTE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCLMTE', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='lift coefficient increment due to optimally deflected trailing edge flaps (default depends on flap type)', ) @@ -5369,10 +5268,7 @@ add_meta_data( Aircraft.Wing.FLAP_SPAN_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.BTEOB', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.BTEOB', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='fraction of wing trailing edge with flaps', default_value=0.65, @@ -5381,33 +5277,32 @@ add_meta_data( Aircraft.Wing.FLAP_TYPE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.JFLTYP', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.JFLTYP', "FLOPS": None, "LEAPS1": None}, units="unitless", default_value=FlapType.DOUBLE_SLOTTED, types=FlapType, option=True, desc='Set the flap type. Available choices are: plain, split, single_slotted, ' - 'double_slotted, triple_slotted, fowler, and double_slotted_fowler. ' - 'In GASP this was JFLTYP and was provided as an int from 1-7', + 'double_slotted, triple_slotted, fowler, and double_slotted_fowler. ' + 'In GASP this was JFLTYP and was provided as an int from 1-7', ) add_meta_data( - Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, meta_data=_MetaData, + Aircraft.Wing.FOLD_DIMENSIONAL_LOCATION_SPECIFIED, + meta_data=_MetaData, historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, - units="unitless", default_value=False, types=bool, option=True, + units="unitless", + default_value=False, + types=bool, + option=True, desc='if true, fold location from the chosen input is an actual fold span, ' - 'if false it is normalized to the half span. In GASP this depended on STRUT or YWFOLD') + 'if false it is normalized to the half span. In GASP this depended on STRUT or YWFOLD', +) add_meta_data( Aircraft.Wing.FOLD_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WWFOLD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WWFOLD', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of the folding area of the wing', default_value=0, @@ -5416,10 +5311,7 @@ add_meta_data( Aircraft.Wing.FOLD_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKWFOLD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKWFOLD', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of the wing fold', default_value=0, @@ -5428,10 +5320,7 @@ add_meta_data( Aircraft.Wing.FOLDED_SPAN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.YWFOLD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.YWFOLD', "FLOPS": None, "LEAPS1": None}, units='ft', desc='folded wingspan', default_value=118, @@ -5440,10 +5329,7 @@ add_meta_data( Aircraft.Wing.FOLDED_SPAN_DIMENSIONLESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", desc='folded wingspan', default_value=1, @@ -5452,46 +5338,40 @@ add_meta_data( Aircraft.Wing.FOLDING_AREA, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SWFOLD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SWFOLD', "FLOPS": None, "LEAPS1": None}, units='ft**2', - desc='wing area of folding part of wings' + desc='wing area of folding part of wings', ) add_meta_data( Aircraft.Wing.FORM_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKW', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='wing form factor', + default_value=1.25, ) add_meta_data( Aircraft.Wing.FUSELAGE_INTERFERENCE_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKI', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CKI', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='wing/fuselage interference factor', + default_value=1.1, ) add_meta_data( Aircraft.Wing.GLOVE_AND_BAT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.GLOV', - # ['&DEFINE.WTIN.GLOV', 'EDETIN.GLOV', '~TOFF.GLOV', '~LNDING.GLOV', - # '~PROFIL.GLOV' - # ], - "LEAPS1": 'aircraft.inputs.L0_wing.glove_and_bat' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.GLOV', + # ['&DEFINE.WTIN.GLOV', 'EDETIN.GLOV', '~TOFF.GLOV', '~LNDING.GLOV', + # '~PROFIL.GLOV' + # ], + "LEAPS1": 'aircraft.inputs.L0_wing.glove_and_bat', + }, units='ft**2', desc='total glove and bat area beyond theoretical wing', default_value=0.0, @@ -5500,10 +5380,7 @@ add_meta_data( Aircraft.Wing.HAS_FOLD, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", option=True, desc='if true a fold will be included in the wing', @@ -5514,10 +5391,7 @@ add_meta_data( Aircraft.Wing.HAS_STRUT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, option=True, units="unitless", default_value=False, @@ -5528,22 +5402,16 @@ add_meta_data( Aircraft.Wing.HEIGHT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.HTG', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.HTG', "FLOPS": None, "LEAPS1": None}, units='ft', desc='wing height above ground during ground run, measured at roughly ' - 'location of mean aerodynamic chord at the mid plane of the wing', + 'location of mean aerodynamic chord at the mid plane of the wing', ) add_meta_data( Aircraft.Wing.HIGH_LIFT_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WHLDEV', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WHLDEV', "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of the high lift devices', ) @@ -5551,10 +5419,7 @@ add_meta_data( Aircraft.Wing.HIGH_LIFT_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WCFLAP', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.WCFLAP', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of high lift devices (default depends on flap type)', ) @@ -5562,10 +5427,7 @@ add_meta_data( Aircraft.Wing.INCIDENCE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.EYEW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.EYEW', "FLOPS": None, "LEAPS1": None}, units='deg', desc='incidence angle of the wings with respect to the fuselage', default_value=0.0, @@ -5576,13 +5438,14 @@ # NOTE required for blended-wing-body type aircraft Aircraft.Wing.INPUT_STATION_DIST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.ETAW', # ['&DEFINE.WTIN.ETAW', 'WDEF.ETAW'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_locations' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.ETAW', # ['&DEFINE.WTIN.ETAW', 'WDEF.ETAW'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_locations', + }, units='unitless', desc='wing station locations as fractions of semispan; overwrites ' - 'station_locations', + 'station_locations', option=True, default_value=None, ) @@ -5590,10 +5453,11 @@ add_meta_data( Aircraft.Wing.LAMINAR_FLOW_LOWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRLW', # ['&DEFINE.AERIN.TRLW', 'XLAM.TRLW', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_percent_laminar_flow_lower_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRLW', # ['&DEFINE.AERIN.TRLW', 'XLAM.TRLW', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_percent_laminar_flow_lower_surface', + }, units='unitless', desc='define percent laminar flow for wing lower surface', default_value=0.0, @@ -5602,10 +5466,11 @@ add_meta_data( Aircraft.Wing.LAMINAR_FLOW_UPPER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.TRUW', # ['&DEFINE.AERIN.TRUW', 'XLAM.TRUW', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_percent_laminar_flow_upper_surface' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.TRUW', # ['&DEFINE.AERIN.TRUW', 'XLAM.TRUW', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_percent_laminar_flow_upper_surface', + }, units='unitless', desc='define percent laminar flow for wing upper surface', default_value=0.0, @@ -5614,10 +5479,7 @@ add_meta_data( Aircraft.Wing.LEADING_EDGE_SWEEP, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SWPLE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SWPLE', "FLOPS": None, "LEAPS1": None}, units='rad', desc='sweep angle at leading edge of wing', ) @@ -5625,13 +5487,13 @@ add_meta_data( Aircraft.Wing.LOAD_DISTRIBUTION_CONTROL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.PDIST', # ['&DEFINE.WTIN.PDIST', 'WDEF.PDIST'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.pressure_dist' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.PDIST', # ['&DEFINE.WTIN.PDIST', 'WDEF.PDIST'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.pressure_dist', + }, units='unitless', - desc='controls spatial distribution of integratin stations for detailed' - ' wing', + desc='controls spatial distribution of integratin stations for detailed' ' wing', default_value=2.0, option=True, ) @@ -5639,10 +5501,11 @@ add_meta_data( Aircraft.Wing.LOAD_FRACTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.PCTL', # ['&DEFINE.WTIN.PCTL', 'WDEF.PCTL'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.carried_load_fraction' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.PCTL', # ['&DEFINE.WTIN.PCTL', 'WDEF.PCTL'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.carried_load_fraction', + }, units='unitless', desc='fraction of load carried by defined wing', default_value=1.0, @@ -5651,24 +5514,26 @@ add_meta_data( Aircraft.Wing.LOAD_PATH_SWEEP_DIST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.SWL', # ['&DEFINE.WTIN.SWL', 'WDEF.SWL'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_load_path_sweeps' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.SWL', # ['&DEFINE.WTIN.SWL', 'WDEF.SWL'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_load_path_sweeps', + }, units='deg', desc='Define the sweep of load path at station locations. Typically ' - 'parallel to rear spar tending toward max t/c of airfoil. The Ith value ' - 'is used between wing stations I and I+1.', + 'parallel to rear spar tending toward max t/c of airfoil. The Ith value ' + 'is used between wing stations I and I+1.', default_value=None, ) add_meta_data( Aircraft.Wing.LOADING, meta_data=_MetaData, - historical_name={"GASP": ['INGASP.WGS', 'INGASP.WOS'], - "FLOPS": None, - "LEAPS1": None - }, + historical_name={ + "GASP": ['INGASP.WGS', 'INGASP.WOS'], + "FLOPS": None, + "LEAPS1": None, + }, units='lbf/ft**2', desc='wing loading', ) @@ -5676,10 +5541,7 @@ add_meta_data( Aircraft.Wing.LOADING_ABOVE_20, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", desc='if true the wing loading is stated to be above 20 psf. In GASP this depended on WGS', option=True, @@ -5692,13 +5554,15 @@ # - see also: Aircraft.Wing.MASS_SCALER Aircraft.Wing.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(1, 2)', '~WEIGHT.WWING', '~WTSTAT.WSP(1, 2)', '~WWGHT.WWING'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._total_wing_weight', - 'aircraft.outputs.L0_weights_summary.total_wing_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(1, 2)', '~WEIGHT.WWING', '~WTSTAT.WSP(1, 2)', '~WWGHT.WWING'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._total_wing_weight', + 'aircraft.outputs.L0_weights_summary.total_wing_weight', + ], + }, units='lbm', desc='wing total mass', default_value=None, @@ -5707,10 +5571,7 @@ add_meta_data( Aircraft.Wing.MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKWW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKWW', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='mass trend coefficient of the wing without high lift devices', default_value=133.4, @@ -5719,10 +5580,11 @@ add_meta_data( Aircraft.Wing.MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRWI', # ['&DEFINE.WTIN.FRWI', 'WTS.FRWI'], - "LEAPS1": 'aircraft.inputs.L0_overrides.total_wing_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRWI', # ['&DEFINE.WTIN.FRWI', 'WTS.FRWI'], + "LEAPS1": 'aircraft.inputs.L0_overrides.total_wing_weight', + }, units='unitless', desc='mass scaler of the overall wing', default_value=1.0, @@ -5731,10 +5593,7 @@ add_meta_data( Aircraft.Wing.MATERIAL_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKNO', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKNO', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='correction factor for the use of non optimum material', default_value=0, @@ -5743,17 +5602,19 @@ add_meta_data( Aircraft.Wing.MAX_CAMBER_AT_70_SEMISPAN, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.CAM', - # [ # inputs - # '&DEFINE.AERIN.CAM', 'EDETIN.CAM', - # # outputs - # 'MISSA.CAM', 'MISSA.CAMX', - # ], - "LEAPS1": ['aircraft.inputs.L0_aerodynamics.max_camber_at_70_semispan', - 'aircraft.outputs.L0_aerodynamics.mission_max_camber_at_70_semispan', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.CAM', + # [ # inputs + # '&DEFINE.AERIN.CAM', 'EDETIN.CAM', + # # outputs + # 'MISSA.CAM', 'MISSA.CAMX', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_aerodynamics.max_camber_at_70_semispan', + 'aircraft.outputs.L0_aerodynamics.mission_max_camber_at_70_semispan', + ], + }, units='unitless', desc='Maximum camber at 70 percent semispan, percent of local chord', default_value=0.0, @@ -5762,10 +5623,7 @@ add_meta_data( Aircraft.Wing.MAX_LIFT_REF, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.RCLMAX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.RCLMAX', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='input reference maximum lift coefficient for basic wing', ) @@ -5773,10 +5631,7 @@ add_meta_data( Aircraft.Wing.MAX_SLAT_DEFLECTION_LANDING, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELLED', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELLED', "FLOPS": None, "LEAPS1": None}, units='deg', desc='leading edge slat deflection during landing', default_value=10, @@ -5785,10 +5640,7 @@ add_meta_data( Aircraft.Wing.MAX_SLAT_DEFLECTION_TAKEOFF, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELLED', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELLED', "FLOPS": None, "LEAPS1": None}, units='deg', desc='leading edge slat deflection during takeoff', default_value=10, @@ -5797,10 +5649,7 @@ add_meta_data( Aircraft.Wing.MAX_THICKNESS_LOCATION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.XCTCMX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.XCTCMX', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='location (percent chord) of max wing thickness', ) @@ -5808,10 +5657,7 @@ add_meta_data( Aircraft.Wing.MIN_PRESSURE_LOCATION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.XCPS', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.XCPS', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='location (percent chord) of peak suction', ) @@ -5821,10 +5667,11 @@ # - see also: Aircraft.Wing.MISC_MASS_SCALER Aircraft.Wing.MISC_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WWGHT.W3', - "LEAPS1": 'aircraft.outputs.L0_wing.misc_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WWGHT.W3', + "LEAPS1": 'aircraft.outputs.L0_wing.misc_weight', + }, units='lbm', desc='wing mass breakdown term 3', default_value=None, @@ -5833,10 +5680,11 @@ add_meta_data( Aircraft.Wing.MISC_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRWI3', # ['&DEFINE.WTIN.FRWI3', 'WIOR3.FRWI3'], - "LEAPS1": 'aircraft.inputs.L0_overrides.wing_misc_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRWI3', # ['&DEFINE.WTIN.FRWI3', 'WIOR3.FRWI3'], + "LEAPS1": 'aircraft.inputs.L0_overrides.wing_misc_weight', + }, units='unitless', desc='mass scaler of the miscellaneous wing mass term', default_value=1.0, @@ -5845,10 +5693,7 @@ add_meta_data( Aircraft.Wing.MOUNTING_TYPE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.HWING', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.HWING', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='wing location on fuselage (0 = low wing, 1 = high wing)', ) @@ -5856,10 +5701,7 @@ add_meta_data( Aircraft.Wing.NUM_FLAP_SEGMENTS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.FLAPN', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.FLAPN', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='number of flap segments per wing panel', types=int, @@ -5870,11 +5712,12 @@ add_meta_data( Aircraft.Wing.NUM_INTEGRATION_STATIONS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.NSTD', 'WDEF.NSTD', '~BNDMAT.NSD', '~DETA.NSD'], - "FLOPS": 'WTIN.NSTD', - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.integration_station_count' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.NSTD', 'WDEF.NSTD', '~BNDMAT.NSD', '~DETA.NSD'], + "FLOPS": 'WTIN.NSTD', + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.integration_station_count', + }, units='unitless', desc='number of integration stations', types=int, @@ -5885,10 +5728,7 @@ add_meta_data( Aircraft.Wing.OPTIMUM_FLAP_DEFLECTION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELTEO', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELTEO', "FLOPS": None, "LEAPS1": None}, units='deg', desc='optimum flap deflection angle (default depends on flap type)', ) @@ -5896,10 +5736,7 @@ add_meta_data( Aircraft.Wing.OPTIMUM_SLAT_DEFLECTION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELLEO', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELLEO', "FLOPS": None, "LEAPS1": None}, units='deg', desc='optimum slat deflection angle', default_value=20, @@ -5908,10 +5745,11 @@ add_meta_data( Aircraft.Wing.ROOT_CHORD, meta_data=_MetaData, - historical_name={"GASP": ['INGASP.CROOT', 'INGASP.CROOTW'], - "FLOPS": None, - "LEAPS1": None - }, + historical_name={ + "GASP": ['INGASP.CROOT', 'INGASP.CROOTW'], + "FLOPS": None, + "LEAPS1": None, + }, units='ft', desc='wing chord length at wing root', ) @@ -5921,10 +5759,11 @@ # - see also: Aircraft.Wing.SHEAR_CONTROL_MASS_SCALER Aircraft.Wing.SHEAR_CONTROL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~WWGHT.W2', - "LEAPS1": 'aircraft.outputs.L0_wing.struct_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~WWGHT.W2', + "LEAPS1": 'aircraft.outputs.L0_wing.struct_weight', + }, units='lbm', desc='wing mass breakdown term 2', default_value=None, @@ -5933,10 +5772,11 @@ add_meta_data( Aircraft.Wing.SHEAR_CONTROL_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRWI2', # ['&DEFINE.WTIN.FRWI2', 'WIOR3.FRWI2'], - "LEAPS1": 'aircraft.inputs.L0_overrides.wing_struct_weights' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRWI2', # ['&DEFINE.WTIN.FRWI2', 'WIOR3.FRWI2'], + "LEAPS1": 'aircraft.inputs.L0_overrides.wing_struct_weights', + }, units='unitless', desc='mass scaler of the shear and control term', default_value=1.0, @@ -5945,10 +5785,7 @@ add_meta_data( Aircraft.Wing.SLAT_CHORD_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CLEOC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CLEOC', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='ratio of slat chord to wing chord', default_value=0.15, @@ -5957,10 +5794,7 @@ add_meta_data( Aircraft.Wing.SLAT_LIFT_INCREMENT_OPTIMUM, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCLMLE', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCLMLE', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='lift coefficient increment due to optimally deflected LE slats', ) @@ -5968,10 +5802,7 @@ add_meta_data( Aircraft.Wing.SLAT_SPAN_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.BLEOB', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.BLEOB', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='fraction of wing leading edge with slats', default_value=0.9, @@ -5980,18 +5811,20 @@ add_meta_data( Aircraft.Wing.SPAN, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.B', - "FLOPS": 'WTIN.SPAN', - # [ # inputs - # '&DEFINE.WTIN.SPAN', - # # outputs - # '~WEIGHT.B', '~WWGHT.B', '~GESURF.B' - # ], - "LEAPS1": ['aircraft.inputs.L0_wing.span', - 'aircraft.outputs.L0_wing.span', - 'BasicTransportWeight.wing_span' - ] - }, + historical_name={ + "GASP": 'INGASP.B', + "FLOPS": 'WTIN.SPAN', + # [ # inputs + # '&DEFINE.WTIN.SPAN', + # # outputs + # '~WEIGHT.B', '~WWGHT.B', '~GESURF.B' + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_wing.span', + 'aircraft.outputs.L0_wing.span', + 'BasicTransportWeight.wing_span', + ], + }, units='ft', desc='span of main wing', default_value=0.0, @@ -6000,10 +5833,11 @@ add_meta_data( Aircraft.Wing.SPAN_EFFICIENCY_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.E', # ['&DEFINE.AERIN.E', 'OSWALD.E', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_span_efficiency_factor' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.E', # ['&DEFINE.AERIN.E', 'OSWALD.E', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_span_efficiency_factor', + }, units='unitless', desc='coefficient for calculating span efficiency for extreme taper ratios', default_value=1.0, @@ -6012,32 +5846,34 @@ add_meta_data( Aircraft.Wing.SPAN_EFFICIENCY_REDUCTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.MIKE', # ['&DEFINE.AERIN.MIKE', 'MIMOD.MIKE'], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_span_efficiency_reduction' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.MIKE', # ['&DEFINE.AERIN.MIKE', 'MIMOD.MIKE'], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_span_efficiency_reduction', + }, units='unitless', desc='Define a switch for span efficiency reduction for extreme taper ' - 'ratios: True == a span efficiency factor ' - '(*wing_span_efficiency_factor0*) is calculated based on wing taper ratio ' - 'and aspect ratio; False == a span efficiency factor ' - '(*wing_span_efficiency_factor0*) is set to 1.0.', + 'ratios: True == a span efficiency factor ' + '(*wing_span_efficiency_factor0*) is calculated based on wing taper ratio ' + 'and aspect ratio; False == a span efficiency factor ' + '(*wing_span_efficiency_factor0*) is set to 1.0.', option=True, types=bool, - default_value=False + default_value=False, ) add_meta_data( Aircraft.Wing.STRUT_BRACING_FACTOR, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.FSTRT', 'WTS.FSTRT', '~WWGHT.FSTRT', '~BNDMAT.FSTRT'], - "FLOPS": 'WTIN.FSTRT', - "LEAPS1": 'aircraft.inputs.L0_wing.struct_bracing_factor' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.FSTRT', 'WTS.FSTRT', '~WWGHT.FSTRT', '~BNDMAT.FSTRT'], + "FLOPS": 'WTIN.FSTRT', + "LEAPS1": 'aircraft.inputs.L0_wing.struct_bracing_factor', + }, units='unitless', desc='Define the wing strut-bracing factor where: 0.0 == no wing-strut; ' - '1.0 == full benefit from strut bracing.', + '1.0 == full benefit from strut bracing.', default_value=0.0, ) @@ -6046,13 +5882,15 @@ # - see also: Aircraft.Wing.SURFACE_CONTROL_MASS_SCALER Aircraft.Wing.SURFACE_CONTROL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - # ['WTS.WSP(16, 2)', '~WEIGHT.WSC', '~WTSTAT.WSP(16, 2)'], - "FLOPS": None, - "LEAPS1": ['(WeightABC)self._surface_ctrls_weight', - 'aircraft.outputs.L0_weights_summary.surface_ctrls_weight', - ] - }, + historical_name={ + "GASP": None, + # ['WTS.WSP(16, 2)', '~WEIGHT.WSC', '~WTSTAT.WSP(16, 2)'], + "FLOPS": None, + "LEAPS1": [ + '(WeightABC)self._surface_ctrls_weight', + 'aircraft.outputs.L0_weights_summary.surface_ctrls_weight', + ], + }, units='lbm', desc='mass of surface controls', default_value=None, @@ -6061,10 +5899,7 @@ add_meta_data( Aircraft.Wing.SURFACE_CONTROL_MASS_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SKFW', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SKFW', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='Surface controls weight coefficient', default_value=0.404, @@ -6073,10 +5908,11 @@ add_meta_data( Aircraft.Wing.SURFACE_CONTROL_MASS_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.FRSC', # ['&DEFINE.WTIN.FRSC', 'WTS.FRSC'], - "LEAPS1": 'aircraft.inputs.L0_overrides.surface_ctrls_weight' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.FRSC', # ['&DEFINE.WTIN.FRSC', 'WTS.FRSC'], + "LEAPS1": 'aircraft.inputs.L0_overrides.surface_ctrls_weight', + }, units='unitless', desc='Surface controls mass scaler', default_value=1.0, @@ -6085,22 +5921,24 @@ add_meta_data( Aircraft.Wing.SWEEP, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DLMC4', - "FLOPS": "CONFIN.SWEEP", - # [ # inputs - # '&DEFINE.CONFIN.SWEEP', 'PARVAR.DVD(1,6)', - # # outputs - # 'CONFIG.SWEEP', 'CONFIG.DVA(6)', '~FLOPS.DVA(6)', '~ANALYS.DVA(6)', - # '~WWGHT.SWEEP', '~INERT.SWEEP', - # # other - # 'MISSA.SW25', '~BUFFET.SW25', '~CDCC.SW25', '~CLDESN.SW25', - # '~MDESN.SW25', - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.wing_sweep_at_quarter_chord', - 'aircraft.outputs.L0_design_variables.wing_sweep_at_quarter_chord', - 'aircraft.outputs.L0_design_variables.mission_wing_sweep_at_quarter_chord', - ] - }, + historical_name={ + "GASP": 'INGASP.DLMC4', + "FLOPS": "CONFIN.SWEEP", + # [ # inputs + # '&DEFINE.CONFIN.SWEEP', 'PARVAR.DVD(1,6)', + # # outputs + # 'CONFIG.SWEEP', 'CONFIG.DVA(6)', '~FLOPS.DVA(6)', '~ANALYS.DVA(6)', + # '~WWGHT.SWEEP', '~INERT.SWEEP', + # # other + # 'MISSA.SW25', '~BUFFET.SW25', '~CDCC.SW25', '~CLDESN.SW25', + # '~MDESN.SW25', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.wing_sweep_at_quarter_chord', + 'aircraft.outputs.L0_design_variables.wing_sweep_at_quarter_chord', + 'aircraft.outputs.L0_design_variables.mission_wing_sweep_at_quarter_chord', + ], + }, units='deg', desc='quarter-chord sweep angle of the wing', default_value=0.0, # TODO required @@ -6109,21 +5947,23 @@ add_meta_data( Aircraft.Wing.TAPER_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SLM', - "FLOPS": "CONFIN.TR", - # [ # inputs - # '&DEFINE.CONFIN.TR', 'PARVAR.DVD(1,5)', - # # outputs - # 'CONFIG.TR', 'CONFIG.DVA(5)', 'CONFIG.TR1', '~FLOPS.DVA(5)', - # '~ANALYS.DVA(5)', '~GESURF.TR', '~WWGHT.TR', '~INERT.TR', - # # other - # 'MISSA.TAPER', '~CDCC.TAPER', '~MDESN.TAPER', - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.wing_taper_ratio', - 'aircraft.outputs.L0_design_variables.wing_taper_ratio', - 'aircraft.outputs.L0_design_variables.mission_wing_taper_ratio', - ] - }, + historical_name={ + "GASP": 'INGASP.SLM', + "FLOPS": "CONFIN.TR", + # [ # inputs + # '&DEFINE.CONFIN.TR', 'PARVAR.DVD(1,5)', + # # outputs + # 'CONFIG.TR', 'CONFIG.DVA(5)', 'CONFIG.TR1', '~FLOPS.DVA(5)', + # '~ANALYS.DVA(5)', '~GESURF.TR', '~WWGHT.TR', '~INERT.TR', + # # other + # 'MISSA.TAPER', '~CDCC.TAPER', '~MDESN.TAPER', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.wing_taper_ratio', + 'aircraft.outputs.L0_design_variables.wing_taper_ratio', + 'aircraft.outputs.L0_design_variables.mission_wing_taper_ratio', + ], + }, units='unitless', desc='taper ratio of the wing', default_value=0.0, # TODO required @@ -6132,22 +5972,24 @@ add_meta_data( Aircraft.Wing.THICKNESS_TO_CHORD, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'CONFIN.TCA', - # [ # inputs - # '&DEFINE.CONFIN.TCA', 'PARVAR.DVD(1,7)', - # # outputs - # 'CONFIG.TCA', 'CONFIG.DVA(7)', '~FLOPS.DVA(7)', '~ANALYS.DVA(7)', - # '~WWGHT.TCA', - # # other - # 'MISSA.TC', '~BUFFET.TC', '~CDCC.TC', '~CDPP.TC', '~CLDESN.TC', - # '~MDESN.TC', - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.wing_thickness_to_chord_ratio', - 'aircraft.outputs.L0_design_variables.wing_thickness_to_chord_ratio', - 'aircraft.outputs.L0_design_variables.mission_wing_thickness_to_chord_ratio', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'CONFIN.TCA', + # [ # inputs + # '&DEFINE.CONFIN.TCA', 'PARVAR.DVD(1,7)', + # # outputs + # 'CONFIG.TCA', 'CONFIG.DVA(7)', '~FLOPS.DVA(7)', '~ANALYS.DVA(7)', + # '~WWGHT.TCA', + # # other + # 'MISSA.TC', '~BUFFET.TC', '~CDCC.TC', '~CDPP.TC', '~CLDESN.TC', + # '~MDESN.TC', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.wing_thickness_to_chord_ratio', + 'aircraft.outputs.L0_design_variables.wing_thickness_to_chord_ratio', + 'aircraft.outputs.L0_design_variables.mission_wing_thickness_to_chord_ratio', + ], + }, units='unitless', desc='wing thickness-chord ratio (weighted average)', default_value=0.0, # TODO required @@ -6156,10 +5998,11 @@ add_meta_data( Aircraft.Wing.THICKNESS_TO_CHORD_DIST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.TOC', # ['&DEFINE.WTIN.TOC', 'WDEF.TOC'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_thickness_to_chord_ratios' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.TOC', # ['&DEFINE.WTIN.TOC', 'WDEF.TOC'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.wing_station_thickness_to_chord_ratios', + }, units='unitless', desc='the thickeness-chord ratios at station locations', default_value=None, @@ -6168,22 +6011,20 @@ add_meta_data( Aircraft.Wing.THICKNESS_TO_CHORD_REF, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.TCREF', # ['&DEFINE.WTIN.TCREF'], - "LEAPS1": 'aircraft.inputs.L0_detailed_wing.ref_thickness_to_chord_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.TCREF', # ['&DEFINE.WTIN.TCREF'], + "LEAPS1": 'aircraft.inputs.L0_detailed_wing.ref_thickness_to_chord_ratio', + }, units='unitless', desc='Reference thickness-to-chord ratio, used for detailed wing bending.', - default_value=0.0 + default_value=0.0, ) add_meta_data( Aircraft.Wing.THICKNESS_TO_CHORD_ROOT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TCR', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.TCR', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='thickness-to-chord ratio at the root of the wing', ) @@ -6191,10 +6032,7 @@ add_meta_data( Aircraft.Wing.THICKNESS_TO_CHORD_TIP, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TCT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.TCT', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='thickness-to-chord ratio at the tip of the wing', ) @@ -6202,21 +6040,20 @@ add_meta_data( Aircraft.Wing.THICKNESS_TO_CHORD_UNWEIGHTED, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.TC', "FLOPS": None, "LEAPS1": None}, units='unitless', - desc='wing thickness-chord ratio at the wing station of the mean aerodynamic chord') + desc='wing thickness-chord ratio at the wing station of the mean aerodynamic chord', +) add_meta_data( Aircraft.Wing.ULTIMATE_LOAD_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ULF', - # ['&DEFINE.WTIN.ULF', 'WTS.ULF', '~WWGHT.ULF'], - "FLOPS": 'WTIN.ULF', - "LEAPS1": 'aircraft.inputs.L0_weights.struct_ult_load_factor' - }, + historical_name={ + "GASP": 'INGASP.ULF', + # ['&DEFINE.WTIN.ULF', 'WTS.ULF', '~WWGHT.ULF'], + "FLOPS": 'WTIN.ULF', + "LEAPS1": 'aircraft.inputs.L0_weights.struct_ult_load_factor', + }, units='unitless', desc='structural ultimate load factor', default_value=3.75, @@ -6225,14 +6062,15 @@ add_meta_data( Aircraft.Wing.VAR_SWEEP_MASS_PENALTY, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFINE.WTIN.VARSWP', 'FAWT.VARSWP', '~WWGHT.VARSWP'], - "FLOPS": 'WTIN.VARSWP', - "LEAPS1": 'aircraft.inputs.L0_wing.var_sweep_weight_penalty' - }, + historical_name={ + "GASP": None, + # ['&DEFINE.WTIN.VARSWP', 'FAWT.VARSWP', '~WWGHT.VARSWP'], + "FLOPS": 'WTIN.VARSWP', + "LEAPS1": 'aircraft.inputs.L0_wing.var_sweep_weight_penalty', + }, units='unitless', desc='Define the fraction of wing variable sweep mass penalty where: ' - '0.0 == fixed-geometry wing; 1.0 == full variable-sweep wing.', + '0.0 == fixed-geometry wing; 1.0 == full variable-sweep wing.', default_value=0.0, ) @@ -6241,13 +6079,15 @@ # - see also: Aircraft.Wing.WETTED_AREA_SCALER Aircraft.Wing.WETTED_AREA, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['ACTWET.SWTWG', 'MISSA.SWET[1]'], - "LEAPS1": ['aircraft.outputs.L0_aerodynamics.wing_wetted_area', - 'aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table[0]', - 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table[0]', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['ACTWET.SWTWG', 'MISSA.SWET[1]'], + "LEAPS1": [ + 'aircraft.outputs.L0_aerodynamics.wing_wetted_area', + 'aircraft.outputs.L0_aerodynamics.mission_component_wetted_area_table[0]', + 'aircraft.cached.L0_aerodynamics.mission_component_wetted_area_table[0]', + ], + }, units='ft**2', desc='wing wetted area', default_value=None, @@ -6256,10 +6096,11 @@ add_meta_data( Aircraft.Wing.WETTED_AREA_SCALER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.SWETW', # ['&DEFINE.AERIN.SWETW', 'AWETO.SWETW', ], - "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_wetted_area' - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.SWETW', # ['&DEFINE.AERIN.SWETW', 'AWETO.SWETW', ], + "LEAPS1": 'aircraft.inputs.L0_aerodynamics.wing_wetted_area', + }, units='unitless', desc='wing wetted area scaler', default_value=1.0, @@ -6268,10 +6109,7 @@ add_meta_data( Aircraft.Wing.ZERO_LIFT_ANGLE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ALPHL0', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ALPHL0', "FLOPS": None, "LEAPS1": None}, units='deg', desc='zero lift angle of attack', ) @@ -6290,506 +6128,439 @@ # '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' '----------------' # ============================================================================================================================================ -# __ __ _ _ -# | \/ | (_) (_) -# | \ / | _ ___ ___ _ ___ _ __ -# | |\/| | | | / __| / __| | | / _ \ | '_ \ -# | | | | | | \__ \ \__ \ | | | (_) | | | | | -# |_| |_| |_| |___/ |___/ |_| \___/ |_| |_| -# ============================================ +# _ _ +# /\ | | | | +# / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ ___ +# / /\ \ | __| | '_ ` _ \ / _ \ / __| | '_ \ | '_ \ / _ \ | '__| / _ \ +# / ____ \ | |_ | | | | | | | (_) | \__ \ | |_) | | | | | | __/ | | | __/ +# /_/ \_\ \__| |_| |_| |_| \___/ |___/ | .__/ |_| |_| \___| |_| \___| +# | | +# |_| +# ================================================================================ add_meta_data( - Dynamic.Mission.ALTITUDE, + Dynamic.Atmosphere.DENSITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='ft', - desc='Current altitude of the vehicle' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/ft**3', + desc="Atmospheric density at the vehicle's current altitude", ) add_meta_data( - Dynamic.Mission.ALTITUDE_RATE, + Dynamic.Atmosphere.DYNAMIC_PRESSURE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='ft/s', - desc='Current rate of altitude change (climb rate) of the vehicle' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbf/ft**2', + desc="Atmospheric dynamic pressure at the vehicle's current flight condition", ) add_meta_data( - Dynamic.Mission.ALTITUDE_RATE_MAX, + Dynamic.Atmosphere.KINEMATIC_VISCOSITY, meta_data=_MetaData, - historical_name={"GASP": None, + historical_name={"GASP": 'XKV', "FLOPS": None, "LEAPS1": None }, - units='ft/s', - desc='Current maximum possible rate of altitude change (climb rate) of the vehicle ' - '(at hypothetical maximum thrust condition)' + units='ft**2/s', + desc="Atmospheric kinematic viscosity at the vehicle's current flight condition" ) add_meta_data( - Dynamic.Mission.BATTERY_STATE_OF_CHARGE, + Dynamic.Atmosphere.MACH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', - desc="battery's current state of charge" + desc='Current Mach number of the vehicle', ) add_meta_data( - Dynamic.Mission.CUMULATIVE_ELECTRIC_ENERGY_USED, + Dynamic.Atmosphere.MACH_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='kJ', - desc='Total amount of electric energy consumed by the vehicle up until this point in the mission', + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='unitless', + desc='Current rate at which the Mach number of the vehicle is changing', ) add_meta_data( - Dynamic.Mission.DENSITY, + Dynamic.Atmosphere.SPEED_OF_SOUND, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbm/ft**3', - desc="Atmospheric density at the vehicle's current altitude" + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='ft/s', + desc="Atmospheric speed of sound at vehicle's current flight condition", ) add_meta_data( - Dynamic.Mission.DISTANCE, + Dynamic.Atmosphere.STATIC_PRESSURE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'range', - "LEAPS1": None - }, - units='NM', - desc="The total distance the vehicle has traveled since brake release at the current time" + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbf/ft**2', + desc="Atmospheric static pressure at the vehicle's current flight condition", ) add_meta_data( - Dynamic.Mission.DISTANCE_RATE, + Dynamic.Atmosphere.TEMPERATURE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'range_rate', - "LEAPS1": None - }, - units='NM/s', - desc="The rate at which the distance traveled is changing at the current time" + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='degR', + desc="Atmospheric temperature at vehicle's current flight condition", +) + + +# __ __ _ _ +# | \/ | (_) (_) +# | \ / | _ ___ ___ _ ___ _ __ +# | |\/| | | | / __| / __| | | / _ \ | '_ \ +# | | | | | | \__ \ \__ \ | | | (_) | | | | | +# |_| |_| |_| |___/ |___/ |_| \___/ |_| |_| +# ============================================ +add_meta_data( + Dynamic.Mission.ALTITUDE, + meta_data=_MetaData, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='ft', + desc='Current altitude of the vehicle', ) add_meta_data( - Dynamic.Mission.DRAG, + Dynamic.Mission.ALTITUDE_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbf', - desc='Current total drag experienced by the vehicle' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='ft/s', + desc='Current rate of altitude change (climb rate) of the vehicle', ) add_meta_data( - Dynamic.Mission.DYNAMIC_PRESSURE, + Dynamic.Mission.ALTITUDE_RATE_MAX, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbf/ft**2', - desc="Atmospheric dynamic pressure at the vehicle's current flight condition" + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='ft/s', + desc='Current maximum possible rate of altitude change (climb rate) of the vehicle ' + '(at hypothetical maximum thrust condition)', ) add_meta_data( - Dynamic.Mission.ELECTRIC_POWER_IN, + Dynamic.Mission.DISTANCE, meta_data=_MetaData, historical_name={"GASP": None, - "FLOPS": None, + "FLOPS": 'range', "LEAPS1": None }, - units='kW', - desc='Current electric power consumption of each engine', + units='NM', + desc="The total distance the vehicle has traveled since brake release at the current time" ) add_meta_data( - Dynamic.Mission.ELECTRIC_POWER_IN_TOTAL, + Dynamic.Mission.DISTANCE_RATE, meta_data=_MetaData, historical_name={"GASP": None, - "FLOPS": None, + "FLOPS": 'range_rate', "LEAPS1": None }, - units='kW', - desc='Current total electric power consumption of the vehicle' + units='NM/s', + desc="The rate at which the distance traveled is changing at the current time" ) -# add_meta_data( -# Dynamic.Mission.EXIT_AREA, -# meta_data=_MetaData, -# historical_name={"GASP": None, -# "FLOPS": None, -# "LEAPS1": None -# }, -# units='kW', -# desc='Current nozzle exit area of engines, per single instance of each ' -# 'engine model' -# ) - add_meta_data( Dynamic.Mission.FLIGHT_PATH_ANGLE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='rad', - desc='Current flight path angle' + desc='Current flight path angle', ) add_meta_data( Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='rad/s', - desc='Current rate at which flight path angle is changing' + desc='Current rate at which flight path angle is changing', ) add_meta_data( - Dynamic.Mission.FUEL_FLOW_RATE, + Dynamic.Mission.SPECIFIC_ENERGY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbm/h', - desc='Current rate of fuel consumption of the vehicle, per single instance of ' - 'each engine model. Consumption (i.e. mass reduction) of fuel is defined as ' - 'positive.' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='m/s', + desc='Rate of change in specific energy (energy per unit weight) of the vehicle at current ' + 'flight condition', ) add_meta_data( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE, meta_data=_MetaData, + Dynamic.Mission.SPECIFIC_ENERGY_RATE, + meta_data=_MetaData, historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, - units='lbm/h', - desc='Current rate of fuel consumption of the vehicle, per single instance of each ' - 'engine model. Consumption (i.e. mass reduction) of fuel is defined as negative.') + units='m/s', + desc='Rate of change in specific energy (specific power) of the vehicle at current ' + 'flight condition', +) add_meta_data( - Dynamic.Mission.FUEL_FLOW_RATE_NEGATIVE_TOTAL, + Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbm/h', - desc='Current rate of total fuel consumption of the vehicle. Consumption (i.e. ' - 'mass reduction) of fuel is defined as negative.' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='m/s', + desc='Specific excess power of the vehicle at current flight condition and at ' + 'hypothetical maximum thrust', ) add_meta_data( - Dynamic.Mission.FUEL_FLOW_RATE_TOTAL, + Dynamic.Mission.VELOCITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbm/h', - desc='Current rate of total fuel consumption of the vehicle. Consumption (i.e. ' - 'mass reduction) of fuel is defined as positive.' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='ft/s', + desc='Current velocity of the vehicle along its body axis', ) add_meta_data( - Dynamic.Mission.HYBRID_THROTTLE, + Dynamic.Mission.VELOCITY_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - desc='Current secondary throttle setting of each individual engine model on the ' - 'vehicle, used as an additional degree of control for hybrid engines' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='ft/s**2', + desc='Current rate of change in velocity (acceleration) of the vehicle along its ' + 'body axis', ) +# __ __ _ _ _ +# \ \ / / | | (_) | | +# \ \ / / ___ | |__ _ ___ | | ___ +# \ \/ / / _ \ | '_ \ | | / __| | | / _ \ +# \ / | __/ | | | | | | | (__ | | | __/ +# \/ \___| |_| |_| |_| \___| |_| \___| +# ================================================ + add_meta_data( - Dynamic.Mission.KINEMATIC_VISCOSITY, + Dynamic.Vehicle.BATTERY_STATE_OF_CHARGE, meta_data=_MetaData, - historical_name={"GASP": 'XKV', - "FLOPS": None, - "LEAPS1": None - }, - units='ft**2/s', - desc="Atmospheric kinematic viscosity at the vehicle's current flight condition" + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='unitless', + desc="battery's current state of charge", ) add_meta_data( - Dynamic.Mission.LIFT, + Dynamic.Vehicle.CUMULATIVE_ELECTRIC_ENERGY_USED, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbf', - desc='Current total lift produced by the vehicle' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='kJ', + desc='Total amount of electric energy consumed by the vehicle up until this point in the mission', ) add_meta_data( - Dynamic.Mission.MACH, + Dynamic.Vehicle.DRAG, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - desc='Current Mach number of the vehicle' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbf', + desc='Current total drag experienced by the vehicle', ) add_meta_data( - Dynamic.Mission.MACH_RATE, + Dynamic.Vehicle.LIFT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='unitless', - desc='Current rate at which the Mach number of the vehicle is changing' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbf', + desc='Current total lift produced by the vehicle', ) add_meta_data( - Dynamic.Mission.MASS, + Dynamic.Vehicle.MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='Current total mass of the vehicle' + desc='Current total mass of the vehicle', ) add_meta_data( - Dynamic.Mission.MASS_RATE, + Dynamic.Vehicle.MASS_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm/s', - desc='Current rate at which the mass of the vehicle is changing' + desc='Current rate at which the mass of the vehicle is changing', ) +# ___ _ _ +# | _ \ _ _ ___ _ __ _ _ | | ___ (_) ___ _ _ +# | _/ | '_| / _ \ | '_ \ | || | | | (_-< | | / _ \ | ' \ +# |_| |_| \___/ | .__/ \_,_| |_| /__/ |_| \___/ |_||_| +# |_| +# ========================================================== + add_meta_data( - Dynamic.Mission.NOX_RATE, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbm/h', - desc='Current rate of nitrous oxide (NOx) production by the vehicle, per single ' - 'instance of each engine model' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='kW', + desc='Current electric power consumption of each engine', ) add_meta_data( - Dynamic.Mission.NOX_RATE_TOTAL, + Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbm/h', - desc='Current total rate of nitrous oxide (NOx) production by the vehicle' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='kW', + desc='Current total electric power consumption of the vehicle', ) +# add_meta_data( +# Dynamic.Vehicle.Propulsion.EXIT_AREA, +# meta_data=_MetaData, +# historical_name={"GASP": None, +# "FLOPS": None, +# "LEAPS1": None +# }, +# units='kW', +# desc='Current nozzle exit area of engines, per single instance of each ' +# 'engine model' +# ) + add_meta_data( - Dynamic.Mission.PROPELLER_TIP_SPEED, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='ft/s', - desc='linear propeller tip speed due to rotation (not airspeed at propeller tip)', - default_value=500.0, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/h', + desc='Current rate of fuel consumption of the vehicle, per single instance of ' + 'each engine model. Consumption (i.e. mass reduction) of fuel is defined as ' + 'positive.', ) add_meta_data( - Dynamic.Mission.RPM, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE, meta_data=_MetaData, - historical_name={"GASP": ['RPM', 'RPMe'], "FLOPS": None, "LEAPS1": None}, - units='rpm', - desc='Rotational rate of shaft, per engine.', + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/h', + desc='Current rate of fuel consumption of the vehicle, per single instance of each ' + 'engine model. Consumption (i.e. mass reduction) of fuel is defined as negative.', ) add_meta_data( - Dynamic.Mission.SPECIFIC_ENERGY, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='m/s', - desc='Rate of change in specific energy (energy per unit weight) of the vehicle at current ' - 'flight condition' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/h', + desc='Current rate of total fuel consumption of the vehicle. Consumption (i.e. ' + 'mass reduction) of fuel is defined as negative.', ) add_meta_data( - Dynamic.Mission.SPECIFIC_ENERGY_RATE, + Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_TOTAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='m/s', - desc='Rate of change in specific energy (specific power) of the vehicle at current ' - 'flight condition' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/h', + desc='Current rate of total fuel consumption of the vehicle. Consumption (i.e. ' + 'mass reduction) of fuel is defined as positive.', ) add_meta_data( - Dynamic.Mission.SHAFT_POWER, + Dynamic.Vehicle.Propulsion.HYBRID_THROTTLE, meta_data=_MetaData, - historical_name={"GASP": ['SHP, EHP'], "FLOPS": None, "LEAPS1": None}, - units='hp', - desc='current shaft power, per engine', + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='unitless', + desc='Current secondary throttle setting of each individual engine model on the ' + 'vehicle, used as an additional degree of control for hybrid engines', ) add_meta_data( - Dynamic.Mission.SHAFT_POWER_MAX, + Dynamic.Vehicle.Propulsion.NOX_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='hp', - desc='The maximum possible shaft power currently producible, per engine' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/h', + desc='Current rate of nitrous oxide (NOx) production by the vehicle, per single ' + 'instance of each engine model', ) add_meta_data( - Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS, + Dynamic.Vehicle.Propulsion.NOX_RATE_TOTAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='m/s', - desc='Specific excess power of the vehicle at current flight condition and at ' - 'hypothetical maximum thrust' + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='lbm/h', + desc='Current total rate of nitrous oxide (NOx) production by the vehicle', ) add_meta_data( - Dynamic.Mission.SPEED_OF_SOUND, + Dynamic.Vehicle.Propulsion.PROPELLER_TIP_SPEED, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='ft/s', - desc="Atmospheric speed of sound at vehicle's current flight condition" + desc='linear propeller tip speed due to rotation (not airspeed at propeller tip)', + default_value=500.0, ) add_meta_data( - Dynamic.Mission.STATIC_PRESSURE, + Dynamic.Vehicle.Propulsion.RPM, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='lbf/ft**2', - desc="Atmospheric static pressure at the vehicle's current flight condition" + historical_name={"GASP": ['RPM', 'RPMe'], "FLOPS": None, "LEAPS1": None}, + units='rpm', + desc='Rotational rate of shaft, per engine.', ) add_meta_data( - Dynamic.Mission.TEMPERATURE, + Dynamic.Vehicle.Propulsion.SHAFT_POWER, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='degR', - desc="Atmospheric temperature at vehicle's current flight condition" + historical_name={"GASP": ['SHP, EHP'], "FLOPS": None, "LEAPS1": None}, + units='hp', + desc='current shaft power, per engine', ) add_meta_data( - Dynamic.Mission.TEMPERATURE_T4, + Dynamic.Vehicle.Propulsion.SHAFT_POWER_MAX, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, + units='hp', + desc='The maximum possible shaft power currently producible, per engine', +) + +add_meta_data( + Dynamic.Vehicle.Propulsion.TEMPERATURE_T4, + meta_data=_MetaData, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='degR', desc='Current turbine exit temperature (T4) of turbine engines on vehicle, per ' - 'single instance of each engine model' + 'single instance of each engine model', ) add_meta_data( - Dynamic.Mission.THROTTLE, + Dynamic.Vehicle.Propulsion.THROTTLE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', - desc='Current throttle setting for each individual engine model on the vehicle' + desc='Current throttle setting for each individual engine model on the vehicle', ) add_meta_data( - Dynamic.Mission.THRUST, + Dynamic.Vehicle.Propulsion.THRUST, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbf', desc='Current net thrust produced by engines, per single instance of each engine ' - 'model' + 'model', ) add_meta_data( - Dynamic.Mission.THRUST_MAX, + Dynamic.Vehicle.Propulsion.THRUST_MAX, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbf', desc="Hypothetical maximum possible net thrust that can be produced per single " - "instance of each engine model at the vehicle's current flight condition" + "instance of each engine model at the vehicle's current flight condition", ) add_meta_data( - Dynamic.Mission.THRUST_MAX_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_MAX_TOTAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbf', desc='Hypothetical maximum possible net thrust produced by the vehicle at its ' - 'current flight condition' + 'current flight condition', ) add_meta_data( - Dynamic.Mission.THRUST_TOTAL, + Dynamic.Vehicle.Propulsion.THRUST_TOTAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbf', - desc='Current total net thrust produced by the vehicle' + desc='Current total net thrust produced by the vehicle', ) add_meta_data( - Dynamic.Mission.TORQUE, + Dynamic.Vehicle.Propulsion.TORQUE, meta_data=_MetaData, historical_name={"GASP": 'TORQUE', "FLOPS": None, "LEAPS1": None}, units='N*m', @@ -6797,7 +6568,7 @@ ) add_meta_data( - Dynamic.Mission.TORQUE_MAX, + Dynamic.Vehicle.Propulsion.TORQUE_MAX, meta_data=_MetaData, historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='N*m', @@ -6805,29 +6576,6 @@ 'condition, per engine', ) -add_meta_data( - Dynamic.Mission.VELOCITY, - meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='ft/s', - desc='Current velocity of the vehicle along its body axis' -) - -add_meta_data( - Dynamic.Mission.VELOCITY_RATE, - meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, - units='ft/s**2', - desc='Current rate of change in velocity (acceleration) of the vehicle along its ' - 'body axis' -) - # ============================================================================================================================================ # .----------------. .----------------. .----------------. .----------------. .----------------. .----------------. .-----------------. # | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. || .--------------. | @@ -6849,6 +6597,7 @@ # | |____ | (_) | | | | | \__ \ | |_ | | | (_| | | | | | | | | |_ \__ \ # \_____| \___/ |_| |_| |___/ \__| |_| \__,_| |_| |_| |_| \__| |___/ # =========================================================================== + add_meta_data( Mission.Constraints.GEARBOX_SHAFT_POWER_RESIDUAL, meta_data=_MetaData, @@ -6860,30 +6609,29 @@ add_meta_data( Mission.Constraints.MASS_RESIDUAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='residual to make sure aircraft mass closes on actual ' - 'gross takeoff mass, value should be zero at convergence ' - '(within acceptable tolerance)', + 'gross takeoff mass, value should be zero at convergence ' + '(within acceptable tolerance)', ) add_meta_data( Mission.Constraints.MAX_MACH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'WTIN.VMMO', - # [ # inputs - # '&DEFINE.WTIN.VMMO', 'VLIMIT.VMMO', - # # outputs - # 'VLIMIT.VMAX', - # ], - "LEAPS1": ['aircraft.inputs.L0_weights.max_mach', - 'aircraft.outputs.L0_weights.max_mach', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'WTIN.VMMO', + # [ # inputs + # '&DEFINE.WTIN.VMMO', 'VLIMIT.VMMO', + # # outputs + # 'VLIMIT.VMAX', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_weights.max_mach', + 'aircraft.outputs.L0_weights.max_mach', + ], + }, units='unitless', desc='aircraft cruise mach number', # TODO: derived default value: Mission.Summary.CRUISE_MACH ??? @@ -6894,27 +6642,21 @@ add_meta_data( Mission.Constraints.RANGE_RESIDUAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='NM', desc='residual to make sure aircraft range is equal to the targeted ' - 'range, value should be zero at convergence (within acceptable ' - 'tolerance)', + 'range, value should be zero at convergence (within acceptable ' + 'tolerance)', ) add_meta_data( Mission.Constraints.RANGE_RESIDUAL_RESERVE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='NM', desc='residual to make sure aircraft reserve mission range is equal to the targeted ' - 'range, value should be zero at convergence (within acceptable ' - 'tolerance)', + 'range, value should be zero at convergence (within acceptable ' + 'tolerance)', ) # _____ _ @@ -6930,23 +6672,18 @@ add_meta_data( Mission.Design.CRUISE_ALTITUDE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CRALT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.CRALT', "FLOPS": None, "LEAPS1": None}, option=True, units='ft', default_value=25000, desc='design mission cruise altitude', - types=[int, float] + types=[int, float], ) add_meta_data( Mission.Design.CRUISE_RANGE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None}, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='NM', desc='the distance flown by the aircraft during cruise', default_value=0.0, @@ -6955,45 +6692,45 @@ add_meta_data( Mission.Design.FUEL_MASS, meta_data=_MetaData, - historical_name={"GASP": "INGASP.WFADES", - "FLOPS": None, # ['WSP(38, 2)', '~WEIGHT.FUELM', '~INERT.FUELM'], - "LEAPS1": ['(WeightABC)self._fuel_weight', - 'aircraft.outputs.L0_weights_summary.fuel_weight' - ] - }, + historical_name={ + "GASP": "INGASP.WFADES", + "FLOPS": None, # ['WSP(38, 2)', '~WEIGHT.FUELM', '~INERT.FUELM'], + "LEAPS1": [ + '(WeightABC)self._fuel_weight', + 'aircraft.outputs.L0_weights_summary.fuel_weight', + ], + }, units='lbm', desc='fuel carried by the aircraft when it is on the ramp at the ' - 'beginning of the design mission', + 'beginning of the design mission', ) add_meta_data( Mission.Design.FUEL_MASS_REQUIRED, meta_data=_MetaData, - historical_name={"GASP": "INGASP.WFAREQ", - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": "INGASP.WFAREQ", "FLOPS": None, "LEAPS1": None}, units='lbm', desc='fuel carried by the aircraft when it is on the ramp at the ' - 'beginning of the design mission', + 'beginning of the design mission', ) add_meta_data( Mission.Design.GROSS_MASS, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.WG', - # ['&DEFINE.WTIN.DGW', 'WTS.DGW', '~WEIGHT.DG', '~WWGHT.DG'], - "FLOPS": 'WTIN.DGW', - "LEAPS1": [ # TODO: 'aircraft.inputs.L0_weights.design_ramp_weight_fraction' ??? - # - design_ramp_weight_fraction has a default: 1.0 - # - design_ramp_weight does not have an explicit default - # - design_ramp_weight has an implicit default, by way of - # design_ramp_weight_fraction: - # [L0_design_variables] ramp_weight - 'aircraft.inputs.L0_weights.design_ramp_weight', - '(weightABC)self._design_gross_weight' - ] - }, + historical_name={ + "GASP": 'INGASP.WG', + # ['&DEFINE.WTIN.DGW', 'WTS.DGW', '~WEIGHT.DG', '~WWGHT.DG'], + "FLOPS": 'WTIN.DGW', + "LEAPS1": [ # TODO: 'aircraft.inputs.L0_weights.design_ramp_weight_fraction' ??? + # - design_ramp_weight_fraction has a default: 1.0 + # - design_ramp_weight does not have an explicit default + # - design_ramp_weight has an implicit default, by way of + # design_ramp_weight_fraction: + # [L0_design_variables] ramp_weight + 'aircraft.inputs.L0_weights.design_ramp_weight', + '(weightABC)self._design_gross_weight', + ], + }, units='lbm', desc='design gross mass of the aircraft', default_value=None, @@ -7003,50 +6740,55 @@ # NOTE: user override (no scaling) Mission.Design.LIFT_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.FCLDES', - # [ # inputs - # '&DEFINE.AERIN.FCLDES', 'OSWALD.FCLDES', - # # outputs - # '~EDET.CLDES', '~CLDESN.CLDES', '~MDESN.CLDES' - # ], - "LEAPS1": ['aircraft.inputs.L0_aerodynamics.design_lift_coeff', - 'aircraft.outputs.L0_aerodynamics.design_lift_coeff' - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.FCLDES', + # [ # inputs + # '&DEFINE.AERIN.FCLDES', 'OSWALD.FCLDES', + # # outputs + # '~EDET.CLDES', '~CLDESN.CLDES', '~MDESN.CLDES' + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_aerodynamics.design_lift_coeff', + 'aircraft.outputs.L0_aerodynamics.design_lift_coeff', + ], + }, units='unitless', desc='Fixed design lift coefficient. If input, overrides design lift ' - 'coefficient computed by EDET.', + 'coefficient computed by EDET.', default_value=None, ) add_meta_data( Mission.Design.LIFT_COEFFICIENT_MAX_FLAPS_UP, meta_data=_MetaData, - historical_name={"GASP": ['INGASP.CLMWFU', 'INGASP.CLMAX'], - "FLOPS": None, - "LEAPS1": None - }, + historical_name={ + "GASP": ['INGASP.CLMWFU', 'INGASP.CLMAX'], + "FLOPS": None, + "LEAPS1": None, + }, units='unitless', desc='maximum lift coefficient from flaps model when flaps are up ' - '(not deployed)', + '(not deployed)', ) add_meta_data( # NOTE: user override (no scaling) Mission.Design.MACH, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CRMACH', - "FLOPS": 'AERIN.FMDES', - # [ # inputs - # '&DEFINE.AERIN.FMDES', 'OSWALD.FMDES' - # # outputs - # '~EDET.DESM', '~MDESN.DESM' - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.design_mach', - 'aircraft.outputs.L0_design_variables.design_mach', - ] - }, + historical_name={ + "GASP": 'INGASP.CRMACH', + "FLOPS": 'AERIN.FMDES', + # [ # inputs + # '&DEFINE.AERIN.FMDES', 'OSWALD.FMDES' + # # outputs + # '~EDET.DESM', '~MDESN.DESM' + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.design_mach', + 'aircraft.outputs.L0_design_variables.design_mach', + ], + }, units='unitless', desc='aircraft design Mach number', ) @@ -7054,11 +6796,12 @@ add_meta_data( Mission.Design.RANGE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ARNGE', - # ['&DEFINE.CONFIN.DESRNG', 'CONFIG.DESRNG'], - "FLOPS": 'CONFIN.DESRNG', - "LEAPS1": 'aircraft.inputs.L0_configuration.design_range' - }, + historical_name={ + "GASP": 'INGASP.ARNGE', + # ['&DEFINE.CONFIN.DESRNG', 'CONFIG.DESRNG'], + "FLOPS": 'CONFIN.DESRNG', + "LEAPS1": 'aircraft.inputs.L0_configuration.design_range', + }, units='NM', desc='the aircraft target distance', default_value=0.0, @@ -7067,10 +6810,7 @@ add_meta_data( Mission.Design.RATE_OF_CLIMB_AT_TOP_OF_CLIMB, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ROCTOC', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ROCTOC', "FLOPS": None, "LEAPS1": None}, option=True, units='ft/min', desc='The required rate of climb at top of climb', @@ -7080,13 +6820,10 @@ add_meta_data( Mission.Design.RESERVE_FUEL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="lbm", desc='the total fuel reserves which is the sum of: ' - 'RESERVE_FUEL_BURNED, RESERVE_FUEL_ADDITIONAL, RESERVE_FUEL_FRACTION', + 'RESERVE_FUEL_BURNED, RESERVE_FUEL_ADDITIONAL, RESERVE_FUEL_FRACTION', default_value=0, ) @@ -7094,17 +6831,19 @@ # TODO move to Engine? Mission.Design.THRUST_TAKEOFF_PER_ENG, meta_data=_MetaData, - historical_name={"GASP": None, - # FLOPS may scale the input value as it resizes the engine if requested by - # the user - # ['&DEFINE.AERIN.THROFF', 'LANDG.THROF', 'LANDG.THROFF'], - "FLOPS": 'AERIN.THROFF', - # LEAPS1 uses the average thrust_takeoff of all operational engines - # actually on the airplane, possibly after resizing (as with FLOPS) - "LEAPS1": ['aircraft.inputs.L0_engine.thrust_takeoff', - '(SimpleTakeoff)self.thrust', - ] - }, + historical_name={ + "GASP": None, + # FLOPS may scale the input value as it resizes the engine if requested by + # the user + # ['&DEFINE.AERIN.THROFF', 'LANDG.THROF', 'LANDG.THROFF'], + "FLOPS": 'AERIN.THROFF', + # LEAPS1 uses the average thrust_takeoff of all operational engines + # actually on the airplane, possibly after resizing (as with FLOPS) + "LEAPS1": [ + 'aircraft.inputs.L0_engine.thrust_takeoff', + '(SimpleTakeoff)self.thrust', + ], + }, units='lbf', # need better description of what state. rolling takeoff condition? alt? mach? desc='thrust on the aircraft for takeoff', @@ -7124,10 +6863,7 @@ add_meta_data( Mission.Landing.AIRPORT_ALTITUDE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.ALTLND', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.ALTLND', "FLOPS": None, "LEAPS1": None}, units='ft', desc='altitude of airport where aircraft lands', default_value=0, @@ -7136,10 +6872,7 @@ add_meta_data( Mission.Landing.BRAKING_DELAY, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.TDELAY', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.TDELAY', "FLOPS": None, "LEAPS1": None}, units='s', desc='time delay between touchdown and the application of brakes', default_value=1, @@ -7153,17 +6886,16 @@ # 'FLOPS': ['&DEFTOL.TOLIN.BRAKMU', 'BALFLD.BRAKMU'], # 'GASP': None, # 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.braking_mu'}, - historical_name={'FLOPS': None, 'GASP': None, 'LEAPS1': None}, default_value=0.3, + historical_name={'FLOPS': None, 'GASP': None, 'LEAPS1': None}, + default_value=0.3, units='unitless', - desc='landing coefficient of friction, with brakes on') + desc='landing coefficient of friction, with brakes on', +) add_meta_data( Mission.Landing.DRAG_COEFFICIENT_FLAP_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCD', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='drag coefficient increment at landing due to flaps', ) @@ -7171,10 +6903,11 @@ add_meta_data( Mission.Landing.DRAG_COEFFICIENT_MIN, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.CDMLD', # ['&DEFINE.AERIN.CDMLD', 'LANDG.CDMLD'], - "LEAPS1": None - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.CDMLD', # ['&DEFINE.AERIN.CDMLD', 'LANDG.CDMLD'], + "LEAPS1": None, + }, units='unitless', desc='Minimum drag coefficient for takeoff. Typically this is CD at zero lift.', default_value=0.0, @@ -7183,21 +6916,19 @@ add_meta_data( Mission.Landing.FIELD_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~ANALYS.FARLDG', - "LEAPS1": '(SimpleLanding)self.landing_distance' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~ANALYS.FARLDG', + "LEAPS1": '(SimpleLanding)self.landing_distance', + }, units='ft', - desc='FAR landing field length' + desc='FAR landing field length', ) add_meta_data( Mission.Landing.FLARE_RATE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'TOLIN.VANGLD', - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": 'TOLIN.VANGLD', "LEAPS1": None}, units="deg/s", desc='flare rate in detailed landing', default_value=2.0, @@ -7206,10 +6937,7 @@ add_meta_data( Mission.Landing.GLIDE_TO_STALL_RATIO, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.VRATT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.VRATT', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='ratio of glide (approach) speed to stall speed', default_value=1.3, @@ -7218,55 +6946,48 @@ add_meta_data( Mission.Landing.GROUND_DISTANCE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DLT', # Is DLT actual landing distance or field length? - "FLOPS": None, - "LEAPS1": None - }, + historical_name={ + "GASP": 'INGASP.DLT', # Is DLT actual landing distance or field length? + "FLOPS": None, + "LEAPS1": None, + }, units='ft', - desc='distance covered over the ground during landing' + desc='distance covered over the ground during landing', ) add_meta_data( Mission.Landing.INITIAL_ALTITUDE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.HIN', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.HIN', "FLOPS": None, "LEAPS1": None}, units='ft', - desc='altitude where landing calculations begin' + desc='altitude where landing calculations begin', ) add_meta_data( Mission.Landing.INITIAL_MACH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", desc='approach mach number', - default_value=0.1 + default_value=0.1, ) add_meta_data( Mission.Landing.INITIAL_VELOCITY, meta_data=_MetaData, - historical_name={"GASP": "INGASP.VGL", - "FLOPS": 'AERIN.VAPPR', - "LEAPS1": '(SimpleLanding)self.vapp' - }, + historical_name={ + "GASP": "INGASP.VGL", + "FLOPS": 'AERIN.VAPPR', + "LEAPS1": '(SimpleLanding)self.vapp', + }, units='ft/s', - desc='approach velocity' + desc='approach velocity', ) add_meta_data( Mission.Landing.LIFT_COEFFICIENT_FLAP_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCL', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCL', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='lift coefficient increment at landing due to flaps', ) @@ -7277,10 +6998,11 @@ # CLLDM (this variable) Mission.Landing.LIFT_COEFFICIENT_MAX, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CLMWLD', - "FLOPS": 'AERIN.CLLDM', # ['&DEFINE.AERIN.CLLDM', 'LANDG.CLLDM'], - "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.max_landing_lift_coeff' - }, + historical_name={ + "GASP": 'INGASP.CLMWLD', + "FLOPS": 'AERIN.CLLDM', # ['&DEFINE.AERIN.CLLDM', 'LANDG.CLLDM'], + "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.max_landing_lift_coeff', + }, units='unitless', desc='maximum lift coefficient for landing', default_value=3.0, @@ -7289,10 +7011,7 @@ add_meta_data( Mission.Landing.MAXIMUM_FLARE_LOAD_FACTOR, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.XLFMX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.XLFMX', "FLOPS": None, "LEAPS1": None}, units="unitless", desc='maximum load factor during landing flare', default_value=1.15, @@ -7301,10 +7020,7 @@ add_meta_data( Mission.Landing.MAXIMUM_SINK_RATE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.RSMX', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.RSMX', "FLOPS": None, "LEAPS1": None}, units='ft/min', desc='maximum rate of sink during glide', default_value=1000, @@ -7313,10 +7029,7 @@ add_meta_data( Mission.Landing.OBSTACLE_HEIGHT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.HAPP', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.HAPP', "FLOPS": None, "LEAPS1": None}, units='ft', desc='landing obstacle height above the ground at airport altitude', default_value=50, @@ -7335,8 +7048,7 @@ # }, historical_name={'FLOPS': None, 'GASP': None, 'LEAPS1': None}, units='unitless', - desc='coefficient of rolling friction for groundroll ' - 'portion of takeoff', + desc='coefficient of rolling friction for groundroll ' 'portion of takeoff', default_value=0.025, ) @@ -7369,10 +7081,7 @@ add_meta_data( Mission.Landing.STALL_VELOCITY, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.VST', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.VST', "FLOPS": None, "LEAPS1": None}, units='ft/s', desc='stall speed during approach', ) @@ -7380,24 +7089,22 @@ add_meta_data( Mission.Landing.TOUCHDOWN_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # ['~ANALYS.WLDG', '~LNDING.GROSWT'], - "LEAPS1": '(SimpleLanding)self.weight' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # ['~ANALYS.WLDG', '~LNDING.GROSWT'], + "LEAPS1": '(SimpleLanding)self.weight', + }, units='lbm', desc='computed mass of aircraft for landing, is only ' - 'required to be equal to Aircraft.Design.TOUCHDOWN_MASS ' - 'when the design case is being run ' - 'for HEIGHT_ENERGY missions this is the mass at the end of the last regular phase (non-reserve phase)', + 'required to be equal to Aircraft.Design.TOUCHDOWN_MASS ' + 'when the design case is being run ' + 'for HEIGHT_ENERGY missions this is the mass at the end of the last regular phase (non-reserve phase)', ) add_meta_data( Mission.Landing.TOUCHDOWN_SINK_RATE, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.SINKTD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.SINKTD', "FLOPS": None, "LEAPS1": None}, units='ft/s', desc='sink rate at touchdown', default_value=3, @@ -7416,25 +7123,19 @@ add_meta_data( Mission.Objectives.FUEL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='regularized objective that minimizes total fuel mass subject ' - 'to other necessary additions', + 'to other necessary additions', ) add_meta_data( Mission.Objectives.RANGE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='unitless', desc='regularized objective that maximizes range subject to other ' - 'necessary additions', + 'necessary additions', ) # _____ @@ -7450,20 +7151,22 @@ add_meta_data( Mission.Summary.CRUISE_MACH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'CONFIN.VCMN', - # [ # inputs - # '&DEFINE.CONFIN.VCMN', 'PARVAR.DVD(1,8)', - # # outputs - # 'CONFIG.VCMN', 'CONFIG.DVA(8)', '~FLOPS.DVA(8)', '~ANALYS.DVA(8)', - # # other - # 'MISSA.VCMIN', - # ], - "LEAPS1": ['aircraft.inputs.L0_design_variables.cruise_mach', - 'aircraft.outputs.L0_design_variables.cruise_mach', - 'aircraft.outputs.L0_design_variables.mission_cruise_mach', - ] - }, + historical_name={ + "GASP": None, + "FLOPS": 'CONFIN.VCMN', + # [ # inputs + # '&DEFINE.CONFIN.VCMN', 'PARVAR.DVD(1,8)', + # # outputs + # 'CONFIG.VCMN', 'CONFIG.DVA(8)', '~FLOPS.DVA(8)', '~ANALYS.DVA(8)', + # # other + # 'MISSA.VCMIN', + # ], + "LEAPS1": [ + 'aircraft.inputs.L0_design_variables.cruise_mach', + 'aircraft.outputs.L0_design_variables.cruise_mach', + 'aircraft.outputs.L0_design_variables.mission_cruise_mach', + ], + }, units='unitless', desc='aircraft cruise mach number', default_value=0.0, # TODO: required @@ -7472,10 +7175,7 @@ add_meta_data( Mission.Summary.CRUISE_MASS_FINAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='mass of the aircraft at the end of cruise', default_value=0.0, @@ -7484,13 +7184,10 @@ add_meta_data( Mission.Summary.FUEL_BURNED, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='fuel burned during regular phases, this ' - 'does not include fuel burned in reserve phases' + 'does not include fuel burned in reserve phases', ) # NOTE if per-mission level scaling is not best mapping for GASP's 'CKFF', map @@ -7500,65 +7197,54 @@ add_meta_data( Mission.Summary.FUEL_FLOW_SCALER, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CKFF', - "FLOPS": 'MISSIN.FACT', # ['&DEFMSS.MISSIN.FACT', 'TRNSF.FACT'], - "LEAPS1": ['aircraft.inputs.L0_fuel_flow.overall_factor'] - }, + historical_name={ + "GASP": 'INGASP.CKFF', + "FLOPS": 'MISSIN.FACT', # ['&DEFMSS.MISSIN.FACT', 'TRNSF.FACT'], + "LEAPS1": ['aircraft.inputs.L0_fuel_flow.overall_factor'], + }, units='unitless', desc='scale factor on overall fuel flow', default_value=1.0, - option=True + option=True, ) add_meta_data( Mission.Summary.GROSS_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='gross takeoff mass of aircraft for that specific mission, not ' - 'necessarily the value for the aircraft`s design mission' + 'necessarily the value for the aircraft`s design mission', ) add_meta_data( Mission.Summary.RANGE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='NM', desc='actual range that the aircraft flies, whether ' - 'it is a design case or an off design case. Equal ' - 'to Mission.Design.RANGE value in the design case.' + 'it is a design case or an off design case. Equal ' + 'to Mission.Design.RANGE value in the design case.', ) add_meta_data( Mission.Summary.RESERVE_FUEL_BURNED, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', desc='fuel burned during reserve phases, this ' - 'does not include fuel burned in regular phases', - default_value=0., + 'does not include fuel burned in regular phases', + default_value=0.0, ) add_meta_data( Mission.Summary.TOTAL_FUEL_MASS, meta_data=_MetaData, - historical_name={"GASP": "INGASP.WFA", - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": "INGASP.WFA", "FLOPS": None, "LEAPS1": None}, units='lbm', desc='total fuel carried at the beginnning of a mission ' - 'includes fuel burned in the mission, reserve fuel ' - 'and fuel margin', + 'includes fuel burned in the mission, reserve fuel ' + 'and fuel margin', ) @@ -7573,12 +7259,9 @@ add_meta_data( Mission.Takeoff.AIRPORT_ALTITUDE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='ft', - desc='altitude of airport where aircraft takes off' + desc='altitude of airport where aircraft takes off', ) add_meta_data( @@ -7588,19 +7271,18 @@ # ['&DEFTOL.TOLIN.ALPRUN', 'BALFLD.ALPRUN', '~CLGRAD.ALPRUN'], 'FLOPS': 'TOLIN.ALPRUN', 'GASP': None, - 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.alpha_runway'}, + 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.alpha_runway', + }, option=True, - default_value=0., + default_value=0.0, units='deg', - desc='angle of attack on ground') + desc='angle of attack on ground', +) add_meta_data( Mission.Takeoff.ASCENT_DURATION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='s', desc='duration of the ascent phase of takeoff', ) @@ -7608,10 +7290,7 @@ add_meta_data( Mission.Takeoff.ASCENT_T_INTIIAL, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='s', desc='time that the ascent phase of takeoff starts at', default_value=10, @@ -7624,18 +7303,17 @@ historical_name={ 'FLOPS': 'TOLIN.BRAKMU', # ['&DEFTOL.TOLIN.BRAKMU', 'BALFLD.BRAKMU'], 'GASP': None, - 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.braking_mu'}, + 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.braking_mu', + }, default_value=0.3, units='unitless', - desc='takeoff coefficient of friction, with brakes on') + desc='takeoff coefficient of friction, with brakes on', +) add_meta_data( Mission.Takeoff.DECISION_SPEED_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DV1', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DV1', "FLOPS": None, "LEAPS1": None}, units='kn', desc='increment of engine failure decision speed above stall speed', default_value=5, @@ -7644,10 +7322,7 @@ add_meta_data( Mission.Takeoff.DRAG_COEFFICIENT_FLAP_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCD', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCD', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='drag coefficient increment at takeoff due to flaps', ) @@ -7655,10 +7330,11 @@ add_meta_data( Mission.Takeoff.DRAG_COEFFICIENT_MIN, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'AERIN.CDMTO', # ['&DEFINE.AERIN.CDMTO', 'LANDG.CDMTO'], - "LEAPS1": None - }, + historical_name={ + "GASP": None, + "FLOPS": 'AERIN.CDMTO', # ['&DEFINE.AERIN.CDMTO', 'LANDG.CDMTO'], + "LEAPS1": None, + }, units='unitless', desc='Minimum drag coefficient for takeoff. Typically this is CD at zero lift.', default_value=0.0, @@ -7667,22 +7343,24 @@ add_meta_data( Mission.Takeoff.FIELD_LENGTH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~ANALYS.FAROFF', - "LEAPS1": '(SimpleTakeoff)self.takeoff_distance' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~ANALYS.FAROFF', + "LEAPS1": '(SimpleTakeoff)self.takeoff_distance', + }, units='ft', - desc='FAR takeoff field length' + desc='FAR takeoff field length', ) add_meta_data( Mission.Takeoff.FINAL_ALTITUDE, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFTOL.TOLIN.OBSTO', 'TOCOMM.OBSTO', 'TOCOMM.DUMC(8)'], - "FLOPS": 'TOLIN.OBSTO', - "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.obstacle_height' - }, + historical_name={ + "GASP": None, + # ['&DEFTOL.TOLIN.OBSTO', 'TOCOMM.OBSTO', 'TOCOMM.DUMC(8)'], + "FLOPS": 'TOLIN.OBSTO', + "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.obstacle_height', + }, units='ft', desc='altitude of aircraft at the end of takeoff', # Note default value is aircraft type dependent @@ -7694,24 +7372,21 @@ add_meta_data( Mission.Takeoff.FINAL_MACH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None, - }, + historical_name={ + "GASP": None, + "FLOPS": None, + "LEAPS1": None, + }, units='unitless', - desc='Mach number of aircraft after taking off and ' - 'clearing a 35 foot obstacle' + desc='Mach number of aircraft after taking off and ' 'clearing a 35 foot obstacle', ) add_meta_data( Mission.Takeoff.FINAL_MASS, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='lbm', - desc='mass after aircraft has cleared 35 ft obstacle' + desc='mass after aircraft has cleared 35 ft obstacle', ) add_meta_data( @@ -7720,13 +7395,13 @@ # - correct Aviary equations? Mission.Takeoff.FINAL_VELOCITY, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~TOFF.V2', - "LEAPS1": '(ClimbToObstacle)self.V2' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~TOFF.V2', + "LEAPS1": '(ClimbToObstacle)self.V2', + }, units='m/s', - desc='velocity of aircraft after taking off and ' - 'clearing a 35 foot obstacle' + desc='velocity of aircraft after taking off and ' 'clearing a 35 foot obstacle', ) add_meta_data( @@ -7735,13 +7410,15 @@ # part of takeoff Mission.Takeoff.FUEL_SIMPLE, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFMSS.MISSIN.FTKOFL', 'FFLALL.FTKOFL', '~MISSON.TAKOFL'], - "FLOPS": 'MISSIN.FTKOFL', - "LEAPS1": ['aircraft.inputs.L0_mission.fixed_takeoff_fuel', - 'aircraft.outputs.L0_takeoff_and_landing.takeoff_fuel', - ] - }, + historical_name={ + "GASP": None, + # ['&DEFMSS.MISSIN.FTKOFL', 'FFLALL.FTKOFL', '~MISSON.TAKOFL'], + "FLOPS": 'MISSIN.FTKOFL', + "LEAPS1": [ + 'aircraft.inputs.L0_mission.fixed_takeoff_fuel', + 'aircraft.outputs.L0_takeoff_and_landing.takeoff_fuel', + ], + }, units='lbm', desc='fuel burned during simple takeoff calculation', default_value=None, @@ -7750,21 +7427,15 @@ add_meta_data( Mission.Takeoff.GROUND_DISTANCE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units='ft', - desc='ground distance covered by takeoff with all engines operating' + desc='ground distance covered by takeoff with all engines operating', ) add_meta_data( Mission.Takeoff.LIFT_COEFFICIENT_FLAP_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DCL', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DCL', "FLOPS": None, "LEAPS1": None}, units='unitless', desc='lift coefficient increment at takeoff due to flaps', ) @@ -7772,11 +7443,12 @@ add_meta_data( Mission.Takeoff.LIFT_COEFFICIENT_MAX, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.CLMWTO', - # ['&DEFINE.AERIN.CLTOM', 'LANDG.CLTOM', '~DEFTOL.CLTOA'], - "FLOPS": 'AERIN.CLTOM', - "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.max_takeoff_lift_coeff' - }, + historical_name={ + "GASP": 'INGASP.CLMWTO', + # ['&DEFINE.AERIN.CLTOM', 'LANDG.CLTOM', '~DEFTOL.CLTOA'], + "FLOPS": 'AERIN.CLTOM', + "LEAPS1": 'aircraft.inputs.L0_takeoff_and_landing.max_takeoff_lift_coeff', + }, units='unitless', desc='maximum lift coefficient for takeoff', default_value=2.0, @@ -7785,12 +7457,13 @@ add_meta_data( Mission.Takeoff.LIFT_OVER_DRAG, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, # '~ANALYS.CLOD', - "LEAPS1": '(SimpleTakeoff)self.lift_over_drag_ratio' - }, + historical_name={ + "GASP": None, + "FLOPS": None, # '~ANALYS.CLOD', + "LEAPS1": '(SimpleTakeoff)self.lift_over_drag_ratio', + }, units='unitless', - desc='ratio of lift to drag at takeoff' + desc='ratio of lift to drag at takeoff', ) add_meta_data( @@ -7805,36 +7478,34 @@ # Note default value is aircraft type dependent # - transport: 35 ft # assume transport for now - default_value=35., + default_value=35.0, units='ft', - desc='takeoff obstacle height above the ground at airport altitude' + desc='takeoff obstacle height above the ground at airport altitude', ) add_meta_data( Mission.Takeoff.ROLLING_FRICTION_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": None, - # ['&DEFTOL.TOLIN.ROLLMU', 'BALFLD.ROLLMU'], - "FLOPS": 'TOLIN.ROLLMU', - "LEAPS1": ['aircraft.inputs.L0_takeoff_and_landing.rolling_mu', - '(GroundRoll)self.mu', - '(Rotate)self.mu', - '(GroundBrake)self.rolling_mu', - ] - }, + historical_name={ + "GASP": None, + # ['&DEFTOL.TOLIN.ROLLMU', 'BALFLD.ROLLMU'], + "FLOPS": 'TOLIN.ROLLMU', + "LEAPS1": [ + 'aircraft.inputs.L0_takeoff_and_landing.rolling_mu', + '(GroundRoll)self.mu', + '(Rotate)self.mu', + '(GroundBrake)self.rolling_mu', + ], + }, units='unitless', - desc='coefficient of rolling friction for groundroll ' - 'portion of takeoff', + desc='coefficient of rolling friction for groundroll ' 'portion of takeoff', default_value=0.025, ) add_meta_data( Mission.Takeoff.ROTATION_SPEED_INCREMENT, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DVR', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DVR', "FLOPS": None, "LEAPS1": None}, units='kn', desc='increment of takeoff rotation speed above engine failure decision speed', default_value=5, @@ -7843,10 +7514,7 @@ add_meta_data( Mission.Takeoff.ROTATION_VELOCITY, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.VR', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.VR', "FLOPS": None, "LEAPS1": None}, units='kn', desc='rotation velocity', ) @@ -7854,10 +7522,11 @@ add_meta_data( Mission.Takeoff.SPOILER_DRAG_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'TOLIN.CDSPOL', # '&DEFTOL.TOLIN.CDSPOL', - "LEAPS1": None - }, + historical_name={ + "GASP": None, + "FLOPS": 'TOLIN.CDSPOL', # '&DEFTOL.TOLIN.CDSPOL', + "LEAPS1": None, + }, units='unitless', desc='drag coefficient for spoilers during takeoff abort', default_value=0.0, @@ -7866,10 +7535,11 @@ add_meta_data( Mission.Takeoff.SPOILER_LIFT_COEFFICIENT, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": 'TOLIN.CLSPOL', # '&DEFTOL.TOLIN.CLSPOL', - "LEAPS1": None - }, + historical_name={ + "GASP": None, + "FLOPS": 'TOLIN.CLSPOL', # '&DEFTOL.TOLIN.CLSPOL', + "LEAPS1": None, + }, units='unitless', desc='lift coefficient for spoilers during takeoff abort', default_value=0.0, @@ -7881,11 +7551,13 @@ historical_name={ 'FLOPS': 'TOLIN.TINC', # ['&DEFTOL.TOLIN.TINC', 'BALFLD.TINC', '~CLGRAD.TINC'], 'GASP': None, - 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.thrust_incidence_angle'}, + 'LEAPS1': 'aircraft.inputs.L0_takeoff_and_landing.thrust_incidence_angle', + }, option=True, - default_value=0., + default_value=0.0, units='deg', - desc='thrust incidence on ground') + desc='thrust incidence on ground', +) # _______ _ # |__ __| (_) @@ -7898,10 +7570,7 @@ add_meta_data( Mission.Taxi.DURATION, meta_data=_MetaData, - historical_name={"GASP": 'INGASP.DELTT', - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": 'INGASP.DELTT', "FLOPS": None, "LEAPS1": None}, units='h', desc='time spent taxiing before takeoff', option=True, @@ -7911,10 +7580,7 @@ add_meta_data( Mission.Taxi.MACH, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, units="unitless", desc='speed during taxi, must be nonzero if pycycle is enabled', option=True, @@ -7936,10 +7602,7 @@ add_meta_data( Settings.EQUATIONS_OF_MOTION, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, desc='Sets which equations of motion Aviary will use in mission analysis', option=True, types=EquationsOfMotion, @@ -7949,27 +7612,21 @@ add_meta_data( Settings.MASS_METHOD, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, desc="Sets which legacy code's methods will be used for mass estimation", option=True, types=LegacyCode, - default_value=None + default_value=None, ) add_meta_data( Settings.PROBLEM_TYPE, meta_data=_MetaData, - historical_name={"GASP": None, - "FLOPS": None, - "LEAPS1": None - }, + historical_name={"GASP": None, "FLOPS": None, "LEAPS1": None}, desc="Select from Aviary's built in problem types: Sizing, Alternate, and Fallout", option=True, types=ProblemType, - default_value=None + default_value=None, ) add_meta_data( @@ -7980,7 +7637,7 @@ '1. BRIEF: Only important information is output, in human-readable format' '2. VERBOSE: All user-relevant information is output, in human-readable format' '3. DEBUG: Any information can be outtputed, including warnings, intermediate calculations, etc., with no formatting requirement', - option=True, types=Verbosity, default_value=Verbosity.BRIEF) + option=True, types=Verbosity, default_value=Verbosity.BRIEF,) # here we create a copy of the Aviary-core metadata. The reason for this # copy is that if we simply imported the Aviary _MetaData in all the diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 79b699d40..f9ad1c69e 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -39,8 +39,9 @@ class BWB: CABIN_AREA = 'aircraft:blended_wing_body_design:cabin_area' NUM_BAYS = 'aircraft:blended_wing_body_design:num_bays' - PASSENGER_LEADING_EDGE_SWEEP = \ + PASSENGER_LEADING_EDGE_SWEEP = ( 'aircraft:blended_wing_body_design:passenger_leading_edge_sweep' + ) class Canard: AREA = 'aircraft:canard:area' @@ -59,48 +60,50 @@ class Canard: class Controls: COCKPIT_CONTROL_MASS_SCALER = 'aircraft:controls:cockpit_control_mass_scaler' CONTROL_MASS_INCREMENT = 'aircraft:controls:control_mass_increment' - STABILITY_AUGMENTATION_SYSTEM_MASS = \ + STABILITY_AUGMENTATION_SYSTEM_MASS = ( 'aircraft:controls:stability_augmentation_system_mass' - STABILITY_AUGMENTATION_SYSTEM_MASS_SCALER = \ + ) + STABILITY_AUGMENTATION_SYSTEM_MASS_SCALER = ( 'aircraft:controls:stability_augmentation_system_mass_scaler' + ) TOTAL_MASS = 'aircraft:controls:total_mass' class CrewPayload: BAGGAGE_MASS = 'aircraft:crew_and_payload:baggage_mass' - BAGGAGE_MASS_PER_PASSENGER = \ + BAGGAGE_MASS_PER_PASSENGER = ( 'aircraft:crew_and_payload:baggage_mass_per_passenger' + ) - CARGO_CONTAINER_MASS = \ - 'aircraft:crew_and_payload:cargo_container_mass' + CARGO_CONTAINER_MASS = 'aircraft:crew_and_payload:cargo_container_mass' - CARGO_CONTAINER_MASS_SCALER = \ + CARGO_CONTAINER_MASS_SCALER = ( 'aircraft:crew_and_payload:cargo_container_mass_scaler' + ) CARGO_MASS = 'aircraft:crew_and_payload:cargo_mass' - CATERING_ITEMS_MASS_PER_PASSENGER = \ + CATERING_ITEMS_MASS_PER_PASSENGER = ( 'aircraft:crew_and_payload:catering_items_mass_per_passenger' + ) FLIGHT_CREW_MASS = 'aircraft:crew_and_payload:flight_crew_mass' - FLIGHT_CREW_MASS_SCALER = \ - 'aircraft:crew_and_payload:flight_crew_mass_scaler' + FLIGHT_CREW_MASS_SCALER = 'aircraft:crew_and_payload:flight_crew_mass_scaler' MASS_PER_PASSENGER = 'aircraft:crew_and_payload:mass_per_passenger' MISC_CARGO = 'aircraft:crew_and_payload:misc_cargo' - NON_FLIGHT_CREW_MASS = \ - 'aircraft:crew_and_payload:non_flight_crew_mass' + NON_FLIGHT_CREW_MASS = 'aircraft:crew_and_payload:non_flight_crew_mass' - NON_FLIGHT_CREW_MASS_SCALER = \ + NON_FLIGHT_CREW_MASS_SCALER = ( 'aircraft:crew_and_payload:non_flight_crew_mass_scaler' + ) NUM_BUSINESS_CLASS = 'aircraft:crew_and_payload:num_business_class' NUM_FIRST_CLASS = 'aircraft:crew_and_payload:num_first_class' - NUM_FLIGHT_ATTENDANTS = \ - 'aircraft:crew_and_payload:num_flight_attendants' + NUM_FLIGHT_ATTENDANTS = 'aircraft:crew_and_payload:num_flight_attendants' NUM_FLIGHT_CREW = 'aircraft:crew_and_payload:num_flight_crew' NUM_GALLEY_CREW = 'aircraft:crew_and_payload:num_galley_crew' @@ -108,21 +111,20 @@ class CrewPayload: NUM_PASSENGERS = 'aircraft:crew_and_payload:num_passengers' NUM_TOURIST_CLASS = 'aircraft:crew_and_payload:num_tourist_class' - PASSENGER_MASS = \ - 'aircraft:crew_and_payload:passenger_mass' - PASSENGER_MASS_WITH_BAGS = \ - 'aircraft:crew_and_payload:passenger_mass_with_bags' + PASSENGER_MASS = 'aircraft:crew_and_payload:passenger_mass' + PASSENGER_MASS_WITH_BAGS = 'aircraft:crew_and_payload:passenger_mass_with_bags' PASSENGER_PAYLOAD_MASS = 'aircraft:crew_and_payload:passenger_payload_mass' - PASSENGER_SERVICE_MASS = \ - 'aircraft:crew_and_payload:passenger_service_mass' + PASSENGER_SERVICE_MASS = 'aircraft:crew_and_payload:passenger_service_mass' - PASSENGER_SERVICE_MASS_PER_PASSENGER = \ + PASSENGER_SERVICE_MASS_PER_PASSENGER = ( 'aircraft:crew_and_payload:passenger_service_mass_per_passenger' + ) - PASSENGER_SERVICE_MASS_SCALER = \ + PASSENGER_SERVICE_MASS_SCALER = ( 'aircraft:crew_and_payload:passenger_service_mass_scaler' + ) TOTAL_PAYLOAD_MASS = 'aircraft:crew_and_payload:total_payload_mass' WATER_MASS_PER_OCCUPANT = 'aircraft:crew_and_payload:water_mass_per_occupant' @@ -141,8 +143,9 @@ class Design: BASE_AREA = 'aircraft:design:base_area' CG_DELTA = 'aircraft:design:cg_delta' CHARACTERISTIC_LENGTHS = 'aircraft:design:characteristic_lengths' - COCKPIT_CONTROL_MASS_COEFFICIENT = \ + COCKPIT_CONTROL_MASS_COEFFICIENT = ( 'aircraft:design:cockpit_control_mass_coefficient' + ) COMPUTE_HTAIL_VOLUME_COEFF = 'aircraft:design:compute_htail_volume_coeff' COMPUTE_VTAIL_VOLUME_COEFF = 'aircraft:design:compute_vtail_volume_coeff' DRAG_COEFFICIENT_INCREMENT = 'aircraft:design:drag_increment' @@ -152,8 +155,7 @@ class Design: EMPTY_MASS = 'aircraft:design:empty_mass' EMPTY_MASS_MARGIN = 'aircraft:design:empty_mass_margin' - EMPTY_MASS_MARGIN_SCALER = \ - 'aircraft:design:empty_mass_margin_scaler' + EMPTY_MASS_MARGIN_SCALER = 'aircraft:design:empty_mass_margin_scaler' EXTERNAL_SUBSYSTEMS_MASS = 'aircraft:design:external_subsystems_mass' FINENESS = 'aircraft:design:fineness' @@ -163,12 +165,12 @@ class Design: LAMINAR_FLOW_LOWER = 'aircraft:design:laminar_flow_lower' LAMINAR_FLOW_UPPER = 'aircraft:design:laminar_flow_upper' - LANDING_TO_TAKEOFF_MASS_RATIO = \ - 'aircraft:design:landing_to_takeoff_mass_ratio' + LANDING_TO_TAKEOFF_MASS_RATIO = 'aircraft:design:landing_to_takeoff_mass_ratio' LIFT_CURVE_SLOPE = 'aircraft:design:lift_curve_slope' - LIFT_DEPENDENT_DRAG_COEFF_FACTOR = \ + LIFT_DEPENDENT_DRAG_COEFF_FACTOR = ( 'aircraft:design:lift_dependent_drag_coeff_factor' + ) LIFT_POLAR = 'aircraft:design:lift_polar' MAX_FUSELAGE_PITCH_ANGLE = 'aircraft:design:max_fuselage_pitch_angle' @@ -182,13 +184,11 @@ class Design: STRUCTURAL_MASS_INCREMENT = 'aircraft:design:structural_mass_increment' STRUCTURE_MASS = 'aircraft:design:structure_mass' - SUBSONIC_DRAG_COEFF_FACTOR = \ - 'aircraft:design:subsonic_drag_coeff_factor' + SUBSONIC_DRAG_COEFF_FACTOR = 'aircraft:design:subsonic_drag_coeff_factor' SUPERCRITICAL_DIVERGENCE_SHIFT = 'aircraft:design:supercritical_drag_shift' - SUPERSONIC_DRAG_COEFF_FACTOR = \ - 'aircraft:design:supersonic_drag_coeff_factor' + SUPERSONIC_DRAG_COEFF_FACTOR = 'aircraft:design:supersonic_drag_coeff_factor' SYSTEMS_EQUIP_MASS = 'aircraft:design:systems_equip_mass' SYSTEMS_EQUIP_MASS_BASE = 'aircraft:design:systems_equip_mass_base' @@ -199,8 +199,7 @@ class Design: USE_ALT_MASS = 'aircraft:design:use_alt_mass' WETTED_AREAS = 'aircraft:design:wetted_areas' ZERO_FUEL_MASS = 'aircraft:design:zero_fuel_mass' - ZERO_LIFT_DRAG_COEFF_FACTOR = \ - 'aircraft:design:zero_lift_drag_coeff_factor' + ZERO_LIFT_DRAG_COEFF_FACTOR = 'aircraft:design:zero_lift_drag_coeff_factor' class Electrical: HAS_HYBRID_SYSTEM = 'aircraft:electrical:has_hybrid_system' @@ -211,8 +210,6 @@ class Electrical: class Engine: ADDITIONAL_MASS = 'aircraft:engine:additional_mass' ADDITIONAL_MASS_FRACTION = 'aircraft:engine:additional_mass_fraction' - COMPUTE_PROPELLER_INSTALLATION_LOSS = \ - 'aircraft:engine:compute_propeller_installation_loss' CONSTANT_FUEL_CONSUMPTION = 'aircraft:engine:constant_fuel_consumption' CONTROLS_MASS = 'aircraft:engine:controls_mass' DATA_FILE = 'aircraft:engine:data_file' @@ -220,7 +217,9 @@ class Engine: FLIGHT_IDLE_MAX_FRACTION = 'aircraft:engine:flight_idle_max_fraction' FLIGHT_IDLE_MIN_FRACTION = 'aircraft:engine:flight_idle_min_fraction' FLIGHT_IDLE_THRUST_FRACTION = 'aircraft:engine:flight_idle_thrust_fraction' - FUEL_FLOW_SCALER_CONSTANT_TERM = 'aircraft:engine:fuel_flow_scaler_constant_term' + FUEL_FLOW_SCALER_CONSTANT_TERM = ( + 'aircraft:engine:fuel_flow_scaler_constant_term' + ) FUEL_FLOW_SCALER_LINEAR_TERM = 'aircraft:engine:fuel_flow_scaler_linear_term' GENERATE_FLIGHT_IDLE = 'aircraft:engine:generate_flight_idle' GEOPOTENTIAL_ALT = 'aircraft:engine:geopotential_alt' @@ -234,18 +233,10 @@ class Engine: MASS_SPECIFIC = 'aircraft:engine:mass_specific' NUM_ENGINES = 'aircraft:engine:num_engines' NUM_FUSELAGE_ENGINES = 'aircraft:engine:num_fuselage_engines' - NUM_PROPELLER_BLADES = 'aircraft:engine:num_propeller_blades' NUM_WING_ENGINES = 'aircraft:engine:num_wing_engines' POD_MASS = 'aircraft:engine:pod_mass' POD_MASS_SCALER = 'aircraft:engine:pod_mass_scaler' POSITION_FACTOR = 'aircraft:engine:position_factor' - PROPELLER_ACTIVITY_FACTOR = 'aircraft:engine:propeller_activity_factor' - PROPELLER_DATA_FILE = 'aircraft:engine:propeller_data_file' - PROPELLER_DIAMETER = 'aircraft:engine:propeller_diameter' - PROPELLER_INTEGRATED_LIFT_COEFFICIENT = \ - 'aircraft:engine:propeller_integrated_lift_coefficient' - PROPELLER_TIP_MACH_MAX = 'propeller_tip_mach_max' - PROPELLER_TIP_SPEED_MAX = 'aircraft:engine:propeller_tip_speed_max' PYLON_FACTOR = 'aircraft:engine:pylon_factor' REFERENCE_DIAMETER = 'aircraft:engine:reference_diameter' REFERENCE_MASS = 'aircraft:engine:reference_mass' @@ -261,20 +252,33 @@ class Engine: THRUST_REVERSERS_MASS = 'aircraft:engine:thrust_reversers_mass' THRUST_REVERSERS_MASS_SCALER = 'aircraft:engine:thrust_reversers_mass_scaler' TYPE = 'aircraft:engine:type' - USE_PROPELLER_MAP = 'aircraft:engine:use_propeller_map' WING_LOCATIONS = 'aircraft:engine:wing_locations' class Gearbox: - EFFICIENCY = "aircraft:engine:gearbox:efficiency" - GEAR_RATIO = "aircraft:engine:gearbox:gear_ratio" - MASS = "aircraft:engine:gearbox:mass" - SHAFT_POWER_DESIGN = 'aircraft:engine:shaft_power_design' + EFFICIENCY = 'aircraft:engine:gearbox:efficiency' + GEAR_RATIO = 'aircraft:engine:gearbox:gear_ratio' + MASS = 'aircraft:engine:gearbox:mass' + SHAFT_POWER_DESIGN = 'aircraft:engine:gearbox:shaft_power_design' SPECIFIC_TORQUE = "aircraft:engine:gearbox:specific_torque" class Motor: MASS = 'aircraft:engine:motor:mass' TORQUE_MAX = 'aircraft:engine:motor:torque_max' + class Propeller: + ACTIVITY_FACTOR = 'aircraft:engine:propeller:activity_factor' + COMPUTE_INSTALLATION_LOSS = ( + 'aircraft:engine:propeller:compute_installation_loss' + ) + DATA_FILE = 'aircraft:engine:propeller:data_file' + DIAMETER = 'aircraft:engine:propeller:diameter' + INTEGRATED_LIFT_COEFFICIENT = ( + 'aircraft:engine:propeller:integrated_lift_coefficient' + ) + NUM_BLADES = 'aircraft:engine:propeller:num_blades' + TIP_MACH_MAX = 'aircraft:engine:propeller:tip_mach_max' + TIP_SPEED_MAX = 'aircraft:engine:propeller:tip_speed_max' + class Fins: AREA = 'aircraft:fins:area' MASS = 'aircraft:fins:mass' @@ -340,8 +344,7 @@ class Fuselage: NUM_FUSELAGES = 'aircraft:fuselage:num_fuselages' NUM_SEATS_ABREAST = 'aircraft:fuselage:num_seats_abreast' - PASSENGER_COMPARTMENT_LENGTH = \ - 'aircraft:fuselage:passenger_compartment_length' + PASSENGER_COMPARTMENT_LENGTH = 'aircraft:fuselage:passenger_compartment_length' PILOT_COMPARTMENT_LENGTH = 'aircraft:fuselage:pilot_compartment_length' PLANFORM_AREA = 'aircraft:fuselage:planform_area' @@ -357,8 +360,7 @@ class HorizontalTail: ASPECT_RATIO = 'aircraft:horizontal_tail:aspect_ratio' AVERAGE_CHORD = 'aircraft:horizontal_tail:average_chord' - CHARACTERISTIC_LENGTH = \ - 'aircraft:horizontal_tail:characteristic_length' + CHARACTERISTIC_LENGTH = 'aircraft:horizontal_tail:characteristic_length' FINENESS = 'aircraft:horizontal_tail:fineness' FORM_FACTOR = 'aircraft:horizontal_tail:form_factor' @@ -375,16 +377,16 @@ class HorizontalTail: TAPER_RATIO = 'aircraft:horizontal_tail:taper_ratio' THICKNESS_TO_CHORD = 'aircraft:horizontal_tail:thickness_to_chord' - VERTICAL_TAIL_FRACTION = \ - 'aircraft:horizontal_tail:vertical_tail_fraction' + VERTICAL_TAIL_FRACTION = 'aircraft:horizontal_tail:vertical_tail_fraction' VOLUME_COEFFICIENT = 'aircraft:horizontal_tail:volume_coefficient' WETTED_AREA = 'aircraft:horizontal_tail:wetted_area' WETTED_AREA_SCALER = 'aircraft:horizontal_tail:wetted_area_scaler' class Hydraulics: - FLIGHT_CONTROL_MASS_COEFFICIENT = \ + FLIGHT_CONTROL_MASS_COEFFICIENT = ( 'aircraft:hydraulics:flight_control_mass_coefficient' + ) GEAR_MASS_COEFFICIENT = 'aircraft:hydraulics:gear_mass_coefficient' MASS = 'aircraft:hydraulics:mass' MASS_SCALER = 'aircraft:hydraulics:mass_scaler' @@ -402,15 +404,13 @@ class LandingGear: MAIN_GEAR_LOCATION = 'aircraft:landing_gear:main_gear_location' MAIN_GEAR_MASS = 'aircraft:landing_gear:main_gear_mass' MAIN_GEAR_MASS_COEFFICIENT = 'aircraft:landing_gear:main_gear_mass_coefficient' - MAIN_GEAR_MASS_SCALER = \ - 'aircraft:landing_gear:main_gear_mass_scaler' + MAIN_GEAR_MASS_SCALER = 'aircraft:landing_gear:main_gear_mass_scaler' MAIN_GEAR_OLEO_LENGTH = 'aircraft:landing_gear:main_gear_oleo_length' MASS_COEFFICIENT = 'aircraft:landing_gear:mass_coefficient' NOSE_GEAR_MASS = 'aircraft:landing_gear:nose_gear_mass' - NOSE_GEAR_MASS_SCALER = \ - 'aircraft:landing_gear:nose_gear_mass_scaler' + NOSE_GEAR_MASS_SCALER = 'aircraft:landing_gear:nose_gear_mass_scaler' NOSE_GEAR_OLEO_LENGTH = 'aircraft:landing_gear:nose_gear_oleo_length' TAIL_HOOK_MASS_SCALER = 'aircraft:landing_gear:tail_hook_mass_scaler' @@ -440,8 +440,7 @@ class Paint: MASS_PER_UNIT_AREA = 'aircraft:paint:mass_per_unit_area' class Propulsion: - ENGINE_OIL_MASS_SCALER = \ - 'aircraft:propulsion:engine_oil_mass_scaler' + ENGINE_OIL_MASS_SCALER = 'aircraft:propulsion:engine_oil_mass_scaler' MASS = 'aircraft:propulsion:mass' MISC_MASS_SCALER = 'aircraft:propulsion:misc_mass_scaler' @@ -457,15 +456,15 @@ class Propulsion: TOTAL_SCALED_SLS_THRUST = 'aircraft:propulsion:total_scaled_sls_thrust' TOTAL_STARTER_MASS = 'aircraft:propulsion:total_starter_mass' - TOTAL_THRUST_REVERSERS_MASS = \ - 'aircraft:propulsion:total_thrust_reversers_mass' + TOTAL_THRUST_REVERSERS_MASS = 'aircraft:propulsion:total_thrust_reversers_mass' class Strut: AREA = 'aircraft:strut:area' AREA_RATIO = 'aircraft:strut:area_ratio' ATTACHMENT_LOCATION = 'aircraft:strut:attachment_location' - ATTACHMENT_LOCATION_DIMENSIONLESS = \ + ATTACHMENT_LOCATION_DIMENSIONLESS = ( 'aircraft:strut:attachment_location_dimensionless' + ) CHORD = 'aircraft:strut:chord' DIMENSIONAL_LOCATION_SPECIFIED = 'aircraft:strut:dimensional_location_specified' FUSELAGE_INTERFERENCE_FACTOR = 'aircraft:strut:fuselage_interference_factor' @@ -502,8 +501,7 @@ class VerticalTail: WETTED_AREA_SCALER = 'aircraft:vertical_tail:wetted_area_scaler' class Wing: - AEROELASTIC_TAILORING_FACTOR = \ - 'aircraft:wing:aeroelastic_tailoring_factor' + AEROELASTIC_TAILORING_FACTOR = 'aircraft:wing:aeroelastic_tailoring_factor' AIRFOIL_TECHNOLOGY = 'aircraft:wing:airfoil_technology' AREA = 'aircraft:wing:area' @@ -536,8 +534,9 @@ class Wing: FLAP_LIFT_INCREMENT_OPTIMUM = 'aircraft:wing:flap_lift_increment_optimum' FLAP_SPAN_RATIO = 'aircraft:wing:flap_span_ratio' FLAP_TYPE = 'aircraft:wing:flap_type' - FOLD_DIMENSIONAL_LOCATION_SPECIFIED = \ + FOLD_DIMENSIONAL_LOCATION_SPECIFIED = ( 'aircraft:wing:fold_dimensional_location_specified' + ) FOLD_MASS = 'aircraft:wing:fold_mass' FOLD_MASS_COEFFICIENT = 'aircraft:wing:fold_mass_coefficient' FOLDED_SPAN = 'aircraft:wing:folded_span' @@ -581,8 +580,7 @@ class Wing: ROOT_CHORD = 'aircraft:wing:root_chord' SHEAR_CONTROL_MASS = 'aircraft:wing:shear_control_mass' - SHEAR_CONTROL_MASS_SCALER = \ - 'aircraft:wing:shear_control_mass_scaler' + SHEAR_CONTROL_MASS_SCALER = 'aircraft:wing:shear_control_mass_scaler' SLAT_CHORD_RATIO = 'aircraft:wing:slat_chord_ratio' SLAT_LIFT_INCREMENT_OPTIMUM = 'aircraft:wing:slat_lift_increment_optimum' @@ -594,8 +592,7 @@ class Wing: SURFACE_CONTROL_MASS = 'aircraft:wing:surface_ctrl_mass' SURFACE_CONTROL_MASS_COEFFICIENT = 'aircraft:wing:surface_ctrl_mass_coefficient' - SURFACE_CONTROL_MASS_SCALER = \ - 'aircraft:wing:surface_ctrl_mass_scaler' + SURFACE_CONTROL_MASS_SCALER = 'aircraft:wing:surface_ctrl_mass_scaler' SWEEP = 'aircraft:wing:sweep' TAPER_RATIO = 'aircraft:wing:taper_ratio' @@ -613,69 +610,85 @@ class Wing: class Dynamic: - """Dynamic mission data hierarchy""" + """All time-dependent variables used during mission analysis""" + + class Atmosphere: + """Atmospheric and freestream conditions""" + + DENSITY = 'density' + DYNAMIC_PRESSURE = 'dynamic_pressure' + KINEMATIC_VISCOSITY = 'kinematic_viscosity' + MACH = 'mach' + MACH_RATE = 'mach_rate' + SPEED_OF_SOUND = 'speed_of_sound' + STATIC_PRESSURE = 'static_pressure' + TEMPERATURE = 'temperature' class Mission: - # all time-dependent variables used during mission analysis + """ + Kinematic description of vehicle states in a ground-fixed axis. + These values are typically used by the Equations of Motion to determine + vehicle states at other timesteps. + """ + + # TODO Vehicle summary forces, torques, etc. in X,Y,Z axes should also go here ALTITUDE = 'altitude' ALTITUDE_RATE = 'altitude_rate' ALTITUDE_RATE_MAX = 'altitude_rate_max' - BATTERY_STATE_OF_CHARGE = 'battery_state_of_charge' - CUMULATIVE_ELECTRIC_ENERGY_USED = 'cumulative_electric_energy_used' - DENSITY = 'density' + # TODO Angle of Attack DISTANCE = 'distance' DISTANCE_RATE = 'distance_rate' - DRAG = 'drag' - DYNAMIC_PRESSURE = 'dynamic_pressure' - ELECTRIC_POWER_IN = 'electric_power_in' - ELECTRIC_POWER_IN_TOTAL = 'electric_power_in_total' - # EXIT_AREA = 'exit_area' FLIGHT_PATH_ANGLE = 'flight_path_angle' FLIGHT_PATH_ANGLE_RATE = 'flight_path_angle_rate' - FUEL_FLOW_RATE = 'fuel_flow_rate' - FUEL_FLOW_RATE_NEGATIVE = 'fuel_flow_rate_negative' - FUEL_FLOW_RATE_NEGATIVE_TOTAL = 'fuel_flow_rate_negative_total' - FUEL_FLOW_RATE_TOTAL = 'fuel_flow_rate_total' - HYBRID_THROTTLE = 'hybrid_throttle' - KINEMATIC_VISCOSITY = 'kinematic_viscosity' - LIFT = 'lift' - MACH = 'mach' - MACH_RATE = 'mach_rate' - MASS = 'mass' - MASS_RATE = 'mass_rate' - NOX_RATE = 'nox_rate' - NOX_RATE_TOTAL = 'nox_rate_total' - PROPELLER_TIP_SPEED = 'propeller_tip_speed' - RPM = 'rotations_per_minute' - SHAFT_POWER = 'shaft_power' - SHAFT_POWER_MAX = 'shaft_power_max' SPECIFIC_ENERGY = 'specific_energy' SPECIFIC_ENERGY_RATE = 'specific_energy_rate' SPECIFIC_ENERGY_RATE_EXCESS = 'specific_energy_rate_excess' - SPEED_OF_SOUND = 'speed_of_sound' - STATIC_PRESSURE = 'static_pressure' - TEMPERATURE = 'temperature' - TEMPERATURE_T4 = 't4' - THROTTLE = 'throttle' - THRUST = 'thrust_net' - THRUST_MAX = 'thrust_net_max' - THRUST_MAX_TOTAL = 'thrust_net_max_total' - THRUST_TOTAL = 'thrust_net_total' - TORQUE = 'torque' - TORQUE_MAX = 'torque_max' VELOCITY = 'velocity' VELOCITY_RATE = 'velocity_rate' + class Vehicle: + """Vehicle properties and states in a vehicle-fixed reference frame.""" + + BATTERY_STATE_OF_CHARGE = 'battery_state_of_charge' + CUMULATIVE_ELECTRIC_ENERGY_USED = 'cumulative_electric_energy_used' + DRAG = 'drag' + LIFT = 'lift' + MASS = 'mass' + MASS_RATE = 'mass_rate' + + class Propulsion: + # variables specific to the propulsion subsystem + ELECTRIC_POWER_IN = 'electric_power_in' + ELECTRIC_POWER_IN_TOTAL = 'electric_power_in_total' + # EXIT_AREA = 'exit_area' + FUEL_FLOW_RATE = 'fuel_flow_rate' + FUEL_FLOW_RATE_NEGATIVE = 'fuel_flow_rate_negative' + FUEL_FLOW_RATE_NEGATIVE_TOTAL = 'fuel_flow_rate_negative_total' + FUEL_FLOW_RATE_TOTAL = 'fuel_flow_rate_total' + HYBRID_THROTTLE = 'hybrid_throttle' + NOX_RATE = 'nox_rate' + NOX_RATE_TOTAL = 'nox_rate_total' + PROPELLER_TIP_SPEED = 'propeller_tip_speed' + RPM = 'rotations_per_minute' + SHAFT_POWER = 'shaft_power' + SHAFT_POWER_MAX = 'shaft_power_max' + TEMPERATURE_T4 = 't4' + THROTTLE = 'throttle' + THRUST = 'thrust_net' + THRUST_MAX = 'thrust_net_max' + THRUST_MAX_TOTAL = 'thrust_net_max_total' + THRUST_TOTAL = 'thrust_net_total' + TORQUE = 'torque' + TORQUE_MAX = 'torque_max' + class Mission: - """mission data hierarchy""" + """Mission data hierarchy""" class Constraints: # these can be residuals (for equality constraints), # upper bounds, or lower bounds - GEARBOX_SHAFT_POWER_RESIDUAL = ( - 'mission:constraints:gearbox_shaft_power_residual' - ) + GEARBOX_SHAFT_POWER_RESIDUAL = 'mission:constraints:gearbox_shaft_power_residual' MASS_RESIDUAL = 'mission:constraints:mass_residual' MAX_MACH = 'mission:constraints:max_mach' RANGE_RESIDUAL = 'mission:constraints:range_residual' @@ -705,8 +718,9 @@ class Landing: BRAKING_DELAY = 'mission:landing:braking_delay' BRAKING_FRICTION_COEFFICIENT = 'mission:landing:braking_friction_coefficient' - DRAG_COEFFICIENT_FLAP_INCREMENT = \ + DRAG_COEFFICIENT_FLAP_INCREMENT = ( 'mission:landing:drag_coefficient_flap_increment' + ) DRAG_COEFFICIENT_MIN = 'mission:landing:drag_coefficient_min' FIELD_LENGTH = 'mission:landing:field_length' @@ -717,8 +731,9 @@ class Landing: INITIAL_MACH = 'mission:landing:initial_mach' INITIAL_VELOCITY = 'mission:landing:initial_velocity' - LIFT_COEFFICIENT_FLAP_INCREMENT = \ + LIFT_COEFFICIENT_FLAP_INCREMENT = ( 'mission:landing:lift_coefficient_flap_increment' + ) LIFT_COEFFICIENT_MAX = 'mission:landing:lift_coefficient_max' MAXIMUM_FLARE_LOAD_FACTOR = 'mission:landing:maximum_flare_load_factor' @@ -761,8 +776,9 @@ class Takeoff: BRAKING_FRICTION_COEFFICIENT = 'mission:takeoff:braking_friction_coefficient' DECISION_SPEED_INCREMENT = 'mission:takeoff:decision_speed_increment' - DRAG_COEFFICIENT_FLAP_INCREMENT = \ + DRAG_COEFFICIENT_FLAP_INCREMENT = ( 'mission:takeoff:drag_coefficient_flap_increment' + ) DRAG_COEFFICIENT_MIN = 'mission:takeoff:drag_coefficient_min' FIELD_LENGTH = 'mission:takeoff:field_length' @@ -773,8 +789,9 @@ class Takeoff: FUEL_SIMPLE = 'mission:takeoff:fuel_simple' GROUND_DISTANCE = 'mission:takeoff:ground_distance' - LIFT_COEFFICIENT_FLAP_INCREMENT = \ + LIFT_COEFFICIENT_FLAP_INCREMENT = ( 'mission:takeoff:lift_coefficient_flap_increment' + ) LIFT_COEFFICIENT_MAX = 'mission:takeoff:lift_coefficient_max' LIFT_OVER_DRAG = 'mission:takeoff:lift_over_drag' @@ -793,6 +810,7 @@ class Taxi: class Settings: """Setting data hierarchy""" + EQUATIONS_OF_MOTION = 'settings:equations_of_motion' MASS_METHOD = 'settings:mass_method' PROBLEM_TYPE = 'settings:problem_type' diff --git a/aviary/visualization/dashboard.py b/aviary/visualization/dashboard.py index cab3b9704..15c208bed 100644 --- a/aviary/visualization/dashboard.py +++ b/aviary/visualization/dashboard.py @@ -5,6 +5,7 @@ import json import os import pathlib +from pathlib import Path import re import shutil import warnings @@ -26,7 +27,7 @@ from openmdao.utils.units import conversion_to_base_units try: from openmdao.utils.gui_testing_utils import get_free_port -except: +except BaseException: # If get_free_port is unavailable, the default port will be used def get_free_port(): return 5000 @@ -42,8 +43,8 @@ def get_free_port(): from openmdao.utils.array_utils import convert_ndarray_to_support_nans_in_json except ImportError: from openmdao.visualization.n2_viewer.n2_viewer import ( - _convert_ndarray_to_support_nans_in_json as convert_ndarray_to_support_nans_in_json, - ) + _convert_ndarray_to_support_nans_in_json + as convert_ndarray_to_support_nans_in_json,) import aviary.api as av @@ -134,17 +135,19 @@ def _dashboard_setup_parser(parser): help="show debugging output", ) - parser.add_argument("--save", - nargs='?', - const=True, - default=False, - help="Name of zip file in which dashboard files are saved. If no argument given, use the script name to name the zip file", - ) + parser.add_argument( + "--save", + nargs='?', + const=True, + default=False, + help="Name of zip file in which dashboard files are saved. If no argument given, use the script name to name the zip file", + ) - parser.add_argument("--force", - action='store_true', - help="When displaying data from a shared zip file, if the directory in the reports directory exists, overrite if this is True", - ) + parser.add_argument( + "--force", + action='store_true', + help="When displaying data from a shared zip file, if the directory in the reports directory exists, overrite if this is True", + ) def _dashboard_cmd(options, user_args): @@ -174,15 +177,18 @@ def _dashboard_cmd(options, user_args): # if yes, then unzip into reports directory and run dashboard on it if zipfile.is_zipfile(options.script_name): report_dir_name = Path(options.script_name).stem - report_dir_path = Path("reports") / report_dir_name + report_dir_path = Path(f"{report_dir_name}_out") # need to check to see if that directory already exists if not options.force and report_dir_path.is_dir(): raise RuntimeError( - f"The reports directory {report_dir_name} already exists. If you wish to overrite the existing directory, use the --force option") - if report_dir_path.is_dir(): # need to delete it. The unpacking will just add to what is there, not do a clean unpack + f"The reports directory {report_dir_path} already exists. If you wish " + "to overrite the existing directory, use the --force option" + ) + if report_dir_path.is_dir( + ): # need to delete it. The unpacking will just add to what is there, not do a clean unpack shutil.rmtree(report_dir_path) - shutil.unpack_archive(options.script_name, f"reports/{report_dir_name}") + shutil.unpack_archive(options.script_name, report_dir_path) dashboard( report_dir_name, options.problem_recorder, @@ -199,7 +205,7 @@ def _dashboard_cmd(options, user_args): else: save_filename_stem = Path(options.save).stem print(f"Saving to {save_filename_stem}.zip") - shutil.make_archive(save_filename_stem, "zip", f"reports/{options.script_name}") + shutil.make_archive(save_filename_stem, "zip", f"{options.script_name}_out") return dashboard( @@ -211,7 +217,7 @@ def _dashboard_cmd(options, user_args): ) -def create_table_pane_from_json(json_filepath): +def create_table_pane_from_json(json_filepath, documentation): """ Create a Tabulator Pane with Name and Value columns using tabular data from a JSON file. @@ -241,10 +247,20 @@ def create_table_pane_from_json(json_filepath): 'Name': '', 'Value': '', }) + table_pane_with_doc = pn.Column( + pn.pane.HTML(f"

{documentation}

", + styles={'text-align': documentation_text_align}), + table_pane + ) except Exception as err: - warnings.warn(f"Unable to generate table due to: {err}.") - table_pane = None - return table_pane + table_pane_with_doc = pn.Column( + pn.pane.HTML(f"

{documentation}

", + styles={'text-align': documentation_text_align}), + pn.pane.Markdown( + f"# Table not shown because data source JSON file, '{json_filepath}', not found.") + ) + + return table_pane_with_doc # functions for creating Panel Panes given different kinds of @@ -465,7 +481,7 @@ def create_aviary_variables_table_data_nested(script_name, recorder_file): ) aviary_variables_file_path = ( - f"reports/{script_name}/aviary_vars/{aviary_variables_json_file_name}" + f"{script_name}_out/reports/aviary_vars/{aviary_variables_json_file_name}" ) with open(aviary_variables_file_path, "w") as fp: json.dump(table_data_nested, fp) @@ -559,7 +575,7 @@ def create_aircraft_3d_file(recorder_file, reports_dir, outfilepath): The path to the location where the file should be created. """ # Get the location of the HTML template file for this HTML file - aviary_dir = pathlib.Path(importlib.util.find_spec("aviary").origin).parent + aviary_dir = Path(importlib.util.find_spec("aviary").origin).parent aircraft_3d_template_filepath = aviary_dir.joinpath( "visualization/assets/aircraft_3d_file_template.html" ) @@ -568,7 +584,7 @@ def create_aircraft_3d_file(recorder_file, reports_dir, outfilepath): # next to the HTML file shutil.copy( aviary_dir.joinpath("visualization/assets/aviary_airlines.png"), - f"{reports_dir}/aviary_airlines.png", + Path(reports_dir) / "aviary_airlines.png", ) aircraft_3d_model = Aircraft3DModel(recorder_file) @@ -578,7 +594,8 @@ def create_aircraft_3d_file(recorder_file, reports_dir, outfilepath): aircraft_3d_model.write_file(aircraft_3d_template_filepath, outfilepath) -def _get_interactive_plot_sources(data_by_varname_and_phase, x_varname, y_varname, phase): +def _get_interactive_plot_sources( + data_by_varname_and_phase, x_varname, y_varname, phase): x = data_by_varname_and_phase[x_varname][phase] y = data_by_varname_and_phase[y_varname][phase] if len(x) > 0 and len(x) == len(y): @@ -652,7 +669,8 @@ def create_optimization_history_plot(case_recorder, df): # as users select variables to be plotted legend = Legend(items=[], location=(-50, -5), border_line_width=0) - # make the legend items in Python. Pass them to JavaScript where they can be added to the Legend + # make the legend items in Python. Pass them to JavaScript where they can + # be added to the Legend legend_items = [] for variable_name in variable_names: units = case_recorder.problem_metadata['variables'][variable_name]['units'] @@ -664,8 +682,8 @@ def create_optimization_history_plot(case_recorder, df): # make the list of variables with checkboxes data_source = ColumnDataSource( - data=dict(options=variable_names, checked=[False]*len(variable_names))) - # Create a Div to act as a scrollable container + data=dict(options=variable_names, checked=[False] * len(variable_names))) + # Create a Div to act as a scrollable container variable_scroll_box = Div( styles={ 'overflow-y': 'scroll', @@ -685,12 +703,12 @@ def create_optimization_history_plot(case_recorder, df): legend=legend, legend_items=legend_items), code=""" - // Three things happen in this code. + // Three things happen in this code. // 1. turn on/off the plot lines // 2. show the legend items for the items being plotted // 3. show the y axes for each of the lines being plotted // The incoming Legend is empty. The items are passed in separately - + // 1. Plots // turn off or on the line plot for the clicked on variable const checkedIndex = cb_obj.index; @@ -699,14 +717,14 @@ def create_optimization_history_plot(case_recorder, df): renderers[data_source.data['options'][checkedIndex]].visible = isChecked; // 2. Legend - // empty the Legend items and then add in the ones for the variables that are checked + // empty the Legend items and then add in the ones for the variables that are checked legend.items = []; for (let i =0; i < legend_items.length; i++){ if ( data_source.data['checked'][i] ) { legend.items.push(legend_items[i]); } } - + // 3. Y axes // first hide all of them for (let i =0; i < legend_items.length; i++){ @@ -729,24 +747,26 @@ def create_optimization_history_plot(case_recorder, df): put_on_left_side = ! put_on_left_side ; } } - data_source.change.emit(); + data_source.change.emit(); """) # CustomJS callback for the variable filtering - filter_variables_callback = CustomJS(args=dict(data_source=data_source, - variable_scroll_box=variable_scroll_box, - variable_checkbox_callback=variable_checkbox_callback), - code=""" - + filter_variables_callback = CustomJS( + args=dict( + data_source=data_source, + variable_scroll_box=variable_scroll_box, + variable_checkbox_callback=variable_checkbox_callback), + code=""" + const filter_text = cb_obj.value.toLowerCase(); const all_options = data_source.data['options']; const checked_states = data_source.data['checked']; - + // Filter options - const filtered_options = all_options.filter(option => + const filtered_options = all_options.filter(option => option.toLowerCase().includes(filter_text) ); - + // Update the scroll box content let checkboxes_html = ''; filtered_options.forEach((label) => { @@ -765,13 +785,16 @@ def create_optimization_history_plot(case_recorder, df): filter_variables_text_box.js_on_change('value', filter_variables_callback) # Initial population of the scroll box - initial_html = ''.join(f""" + initial_html = ''.join( + f""" - """ for i, variable_name in enumerate(variable_names)) + """ + for i, variable_name in enumerate(variable_names) + ) variable_scroll_box.text = initial_html # Arrange the layout using Panel @@ -783,7 +806,8 @@ def create_optimization_history_plot(case_recorder, df): # The main script that generates all the tabs in the dashboard -def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_background=False): +def dashboard(script_name, problem_recorder, driver_recorder, + port, run_in_background=False): """ Generate the dashboard app display. @@ -798,27 +822,29 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg port : int HTTP port used for the dashboard webapp. If 0, use any free port """ - if "reports/" not in script_name: - reports_dir = f"reports/{script_name}" - else: - reports_dir = script_name + reports_dir = f"{script_name}_out/reports/" + out_dir = f"{script_name}_out/" - if not pathlib.Path(reports_dir).is_dir(): + if not Path(reports_dir).is_dir(): raise ValueError( - f"The script name, '{script_name}', does not have a reports folder associated with it. " - f"The directory '{reports_dir}' does not exist." + f"The script name, '{script_name}', does not have a reports folder " + f"associated with it. The directory '{reports_dir}' does not exist." ) - if not os.path.isfile(problem_recorder): + problem_recorder_path = Path(out_dir) / problem_recorder + driver_recorder_path = Path(out_dir) / driver_recorder + + if not os.path.isfile(problem_recorder_path): issue_warning( - f"Given Problem case recorder file {problem_recorder} does not exist.") + f"Given Problem case recorder file {problem_recorder_path} does not exist.") # TODO - use lists and functions to do this with a lot less code ####### Model Tab ####### model_tabs_list = [] # Debug Input List - input_list_pane = create_report_frame("text", "input_list.txt", ''' + input_list_pane = create_report_frame( + "text", Path(reports_dir) / "input_list.txt", ''' A plain text display of the model inputs. Recommended for beginners. Only created if Settings.VERBOSITY is set to at least 2 in the input deck. The variables are listed in a tree structure. There are three columns. The left column is a list of variable names, the middle column is the value, and the right column is the @@ -829,7 +855,8 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg model_tabs_list.append(("Debug Input List", input_list_pane)) # Debug Output List - output_list_pane = create_report_frame("text", "output_list.txt", ''' + output_list_pane = create_report_frame( + "text", Path(reports_dir) / "output_list.txt", ''' A plain text display of the model outputs. Recommended for beginners. Only created if Settings.VERBOSITY is set to at least 2 in the input deck. The variables are listed in a tree structure. There are three columns. The left column is a list of variable names, the middle column is the value, and the right column is the @@ -841,11 +868,13 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg # Inputs inputs_pane = create_report_frame( - "html", f"{reports_dir}/inputs.html", "Detailed report on the model inputs.") + "html", + Path(reports_dir) / "inputs.html", + "Detailed report on the model inputs.") model_tabs_list.append(("Inputs", inputs_pane)) # N2 - n2_pane = create_report_frame("html", f"{reports_dir}/n2.html", ''' + n2_pane = create_report_frame("html", Path(reports_dir) / "n2.html", ''' The N2 diagram, sometimes referred to as an eXtended Design Structure Matrix (XDSM), is a powerful tool for understanding your model in OpenMDAO. It is an N-squared diagram in the shape of a matrix representing functional or physical interfaces between system elements. @@ -855,7 +884,7 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg # Trajectory Linkage traj_linkage_report_pane = create_report_frame( - "html", f"{reports_dir}/traj_linkage_report.html", ''' + "html", Path(reports_dir) / "traj_linkage_report.html", ''' This is a Dymos linkage report in a customized N2 diagram. It provides a report detailing how phases are linked together via constraint or connection. The diagram clearly shows how mission phases are linked. It can be used to identify errant linkages between fixed quantities. @@ -865,7 +894,7 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg # Driver scaling driver_scaling_report_pane = create_report_frame( - "html", f"{reports_dir}/driver_scaling_report.html", ''' + "html", Path(reports_dir) / "driver_scaling_report.html", ''' This report is a summary of driver scaling information. After all design variables, objectives, and constraints are declared and the problem has been set up, this report presents all the design variables and constraints in all phases as well as the objectives. It also shows Jacobian information showing responses with respect to @@ -886,77 +915,81 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg optimization_tabs_list.append(("Optimization History", opt_history_pane)) # IPOPT report - if os.path.isfile(f"{reports_dir}/IPOPT.out"): - ipopt_pane = create_report_frame("text", f"{reports_dir}/IPOPT.out", ''' + if os.path.isfile(Path(reports_dir) / "IPOPT.out"): + ipopt_pane = create_report_frame("text", Path(reports_dir) / "IPOPT.out", ''' This report is generated by the IPOPT optimizer. ''') optimization_tabs_list.append(("IPOPT Output", ipopt_pane)) # Optimization report - opt_report_pane = create_report_frame("html", f"{reports_dir}/opt_report.html", ''' + opt_report_pane = create_report_frame( + "html", Path(reports_dir) / "opt_report.html", ''' This report is an OpenMDAO optimization report. All values are in unscaled, physical units. On the top is a summary of the optimization, followed by the objective, design variables, constraints, and optimizer settings. This report is important when dissecting optimal results produced by Aviary.''') optimization_tabs_list.append(("Summary", opt_report_pane)) # PyOpt report - if os.path.isfile(f"{reports_dir}/pyopt_solution.out"): + if os.path.isfile(Path(reports_dir) / "pyopt_solution.out"): pyopt_solution_pane = create_report_frame( - "text", f"{reports_dir}/pyopt_solution.txt", ''' + "text", Path(reports_dir) / "pyopt_solution.txt", ''' This report is generated by the pyOptSparse optimizer. ''' ) optimization_tabs_list.append(("PyOpt Solution", pyopt_solution_pane)) # SNOPT report - if os.path.isfile(f"{reports_dir}/SNOPT_print.out"): - snopt_pane = create_report_frame("text", f"{reports_dir}/SNOPT_print.out", ''' + if os.path.isfile(Path(reports_dir) / "SNOPT_print.out"): + snopt_pane = create_report_frame( + "text", Path(reports_dir) / "SNOPT_print.out", ''' This report is generated by the SNOPT optimizer. ''') optimization_tabs_list.append(("SNOPT Output", snopt_pane)) # SNOPT summary - if os.path.isfile(f"{reports_dir}/SNOPT_summary.out"): - snopt_summary_pane = create_report_frame("text", f"{reports_dir}/SNOPT_summary.out", ''' + if os.path.isfile(Path(reports_dir) / "SNOPT_summary.out"): + snopt_summary_pane = create_report_frame( + "text", Path(reports_dir) / "SNOPT_summary.out", ''' This is a report generated by the SNOPT optimizer that summarizes the optimization results.''') optimization_tabs_list.append(("SNOPT Summary", snopt_summary_pane)) # Coloring report coloring_report_pane = create_report_frame( - "html", f"{reports_dir}/total_coloring.html", "The report shows metadata associated with the creation of the coloring." - ) + "html", Path(reports_dir) / "total_coloring.html", + "The report shows metadata associated with the creation of the coloring.") optimization_tabs_list.append(("Total Coloring", coloring_report_pane)) ####### Results Tab ####### results_tabs_list = [] # Aircraft 3d model display - if problem_recorder: - if os.path.isfile(problem_recorder): + if problem_recorder_path: + if os.path.isfile(problem_recorder_path): try: + aircraft_3d_file = Path(reports_dir) / "aircraft_3d.html" create_aircraft_3d_file( - problem_recorder, reports_dir, f"{reports_dir}/aircraft_3d.html" + problem_recorder_path, reports_dir, aircraft_3d_file ) aircraft_3d_pane = create_report_frame( - "html", f"{reports_dir}/aircraft_3d.html", + "html", aircraft_3d_file, "3D model view of designed aircraft." ) except Exception as e: aircraft_3d_pane = create_report_frame( - "simple_message", f"Unable to create aircraft 3D model display due to error: {e}", - "3D model view of designed aircraft." - ) + "simple_message", + f"Unable to create aircraft 3D model display due to error: {e}", + "3D model view of designed aircraft.") results_tabs_list.append(("Aircraft 3d model", aircraft_3d_pane)) # Make the Aviary variables table pane - if os.path.isfile(problem_recorder): + if os.path.isfile(problem_recorder_path): # Make dir reports/script_name/aviary_vars if needed - aviary_vars_dir = pathlib.Path(f"reports/{script_name}/aviary_vars") + aviary_vars_dir = Path(reports_dir) / "aviary_vars" aviary_vars_dir.mkdir(parents=True, exist_ok=True) # copy index.html file to reports/script_name/aviary_vars/index.html - aviary_dir = pathlib.Path(importlib.util.find_spec("aviary").origin).parent + aviary_dir = Path(importlib.util.find_spec("aviary").origin).parent shutil.copy( aviary_dir.joinpath("visualization/assets/aviary_vars/index.html"), @@ -968,35 +1001,38 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg ) # copy script.js file to reports/script_name/aviary_vars/index.html. # mod the script.js file to point at the json file - # create the json file and put it in reports/script_name/aviary_vars/aviary_vars.json + # create the json file and put it in + # reports/script_name/aviary_vars/aviary_vars.json try: create_aviary_variables_table_data_nested( - script_name, problem_recorder + script_name, problem_recorder_path ) # create the json file aviary_vars_pane = create_report_frame( - "html", f"{reports_dir}/aviary_vars/index.html", + "html", Path(reports_dir) / "aviary_vars/index.html", "Table showing Aviary variables" ) results_tabs_list.append(("Aviary Variables", aviary_vars_pane)) except Exception as e: issue_warning( - f'Unable to create Aviary Variables tab in dashboard due to the error: {e}' - ) + f'Unable to create Aviary Variables tab in dashboard due to the error: {e}') # Mission Summary mission_summary_pane = create_report_frame( - "markdown", f"{reports_dir}/mission_summary.md", "A report of mission results from an Aviary problem") + "markdown", Path(reports_dir) / "mission_summary.md", + "A report of mission results from an Aviary problem") results_tabs_list.append(("Mission Summary", mission_summary_pane)) # Run status pane - status_pane = create_table_pane_from_json(f"{reports_dir}/status.json") + status_pane = create_table_pane_from_json( + Path(reports_dir) / "status.json", + "A high level overview of the status of the run") results_tabs_list.append(("Run status pane", status_pane)) run_status_pane_tab_number = len(results_tabs_list) - 1 # Timeseries Mission Output Report mission_timeseries_pane = create_csv_frame( - f"{reports_dir}/mission_timeseries_data.csv", ''' + Path(reports_dir) / "mission_timeseries_data.csv", ''' The outputs of the aircraft trajectory. Any value that is included in the timeseries data is included in this report. This data is useful for post-processing, especially those used for acoustic analysis. @@ -1007,7 +1043,7 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg # Trajectory results traj_results_report_pane = create_report_frame( - "html", f"{reports_dir}/traj_results_report.html", ''' + "html", Path(reports_dir) / "traj_results_report.html", ''' This is one of the most important reports produced by Aviary. It will help you visualize and understand the optimal trajectory produced by Aviary. Users should play with it and try to grasp all possible features. @@ -1022,17 +1058,21 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg ) # Interactive XY plot of mission variables - if problem_recorder: - if os.path.exists(problem_recorder): - cr = om.CaseReader(problem_recorder) + if problem_recorder_path: + if os.path.exists(problem_recorder_path): + cr = om.CaseReader(problem_recorder_path) # determine what trajectories there are - traj_nodes = [n for n in _meta_tree_subsys_iter( - cr.problem_metadata['tree'], cls='dymos.trajectory.trajectory:Trajectory')] + traj_nodes = [ + n + for n in _meta_tree_subsys_iter( + cr.problem_metadata['tree'], + cls='dymos.trajectory.trajectory:Trajectory')] if len(traj_nodes) == 0: - raise ValueError("No trajectories available in case recorder file for use " - "in generating interactive XY plot of mission variables") + raise ValueError( + "No trajectories available in case recorder file for use " + "in generating interactive XY plot of mission variables") traj_name = traj_nodes[0]["name"] if len(traj_nodes) > 1: issue_warning("More than one trajectory found in problem case recorder file. Only using " @@ -1089,8 +1129,8 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg # need to create ColumnDataSource for each phase sources = {} for phase in phases: - x, y = _get_interactive_plot_sources(data_by_varname_and_phase, - x_varname_default, y_varname_default, phase) + x, y = _get_interactive_plot_sources( + data_by_varname_and_phase, x_varname_default, y_varname_default, phase) sources[phase] = ColumnDataSource(data=dict( x=x, y=y)) @@ -1123,7 +1163,8 @@ def dashboard(script_name, problem_recorder, driver_recorder, port, run_in_backg # Make the Legend legend = Legend(items=legend_data, location='center', label_text_font_size='8pt') - # so users can click on the dot in the legend to turn off/on that phase in the plot + # so users can click on the dot in the legend to turn off/on that phase in + # the plot legend.click_policy = "hide" p.add_layout(legend, 'right') @@ -1161,29 +1202,34 @@ def update_plot(x_varname, y_varname): ) else: interactive_mission_var_plot_pane = pn.pane.Markdown( - f"# Recorder file '{problem_recorder}' not found.") + f"# Recorder file '{problem_recorder_path}' not found.") interactive_mission_var_plot_pane_with_doc = pn.Column( - pn.pane.HTML(f"

Plot of mission variables allowing user to select X and Y plot values.

", - styles={'text-align': documentation_text_align}), - interactive_mission_var_plot_pane - ) + pn.pane.HTML( + f"

Plot of mission variables allowing user to select X and Y plot values.

", + styles={ + 'text-align': documentation_text_align}), + interactive_mission_var_plot_pane) results_tabs_list.append( - ("Interactive Mission Variable Plot", interactive_mission_var_plot_pane_with_doc) - ) + ("Interactive Mission Variable Plot", + interactive_mission_var_plot_pane_with_doc)) ####### Subsystems Tab ####### subsystem_tabs_list = [] # Look through subsystems directory for markdown files - # The subsystems report tab shows selected results for every major subsystem in the Aviary problem + # The subsystems report tab shows selected results for every major + # subsystem in the Aviary problem - for md_file in sorted(pathlib.Path(f"{reports_dir}subsystems").glob("*.md"), key=str): - subsystems_pane = create_report_frame("markdown", str( - md_file), + for md_file in sorted(Path(f"{reports_dir}subsystems").glob("*.md"), key=str): + subsystems_pane = create_report_frame( + "markdown", str(md_file), f''' + The subsystems report tab shows selected results for every major subsystem in the Aviary problem. - This report is for the {md_file.stem} subsystem. Reports available currently are mass, geometry, and propulsion. + This report is for the + {md_file.stem} + subsystem. Reports available currently are mass, geometry, and propulsion. ''') subsystem_tabs_list.append((md_file.stem, subsystems_pane)) @@ -1222,14 +1268,14 @@ def update_plot(x_varname, y_varname): def save_dashboard(event): print(f"Saving dashboard files to {script_name}.zip") - shutil.make_archive(script_name, "zip", f"reports/{script_name}") + shutil.make_archive(script_name, "zip", f"{script_name}_out") save_dashboard_button.on_click(save_dashboard) tabs.active = 0 # make the Results tab active initially # get status of run for display in the header of each page - status_string_for_header = get_run_status(f"{reports_dir}/status.json") + status_string_for_header = get_run_status(Path(reports_dir) / "status.json") template = pn.template.FastListTemplate( title=f"Aviary Dashboard for {script_name}: {status_string_for_header}", @@ -1257,7 +1303,7 @@ def save_dashboard(event): if run_in_background: show = False - assets_dir = pathlib.Path( + assets_dir = Path( importlib.util.find_spec("aviary").origin ).parent.joinpath("visualization/assets/") home_dir = "."