Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
f3a72ad
broke out US standard Atmosphere raw data into its own file. New data…
ehariton Dec 8, 2025
cff5eab
added options isa_delta_T_Kelvin and data_source, removed computation…
ehariton Dec 9, 2025
7e84114
added unit conversion to _build_akima_coefs
ehariton Dec 9, 2025
e14d024
successfully generating akimas from _build_akima_coefs, moved atm_dat…
ehariton Dec 9, 2025
52fac6c
calculated akimas for all raw data
ehariton Dec 9, 2025
2dffa1c
added peroperly interpolated altitude data to each atmosphere model b…
ehariton Dec 9, 2025
c5ff59d
fixed error in density calcs thanks to Jess for spotting that. update…
ehariton Dec 9, 2025
9e2b4ea
half started test_atmosphere and USatm1976TestCase1, it needs more work
ehariton Dec 9, 2025
0296736
moved library option load from init to setup because options dont hav…
ehariton Dec 10, 2025
ffa7825
revised user guide to atmosphere model and added testing section to a…
ehariton Dec 15, 2025
838c505
updated notes on atmosphere origins as well as added those notes into…
ehariton Dec 16, 2025
736c993
tweaking documentation and notes
ehariton Dec 16, 2025
6030e83
updated doc wording
ehariton Dec 16, 2025
c29ff8b
small wording changes to test
ehariton Dec 16, 2025
8aa488b
merge main
ehariton Dec 17, 2025
9a2c888
merge main
ehariton Jan 5, 2026
1e52575
removed unused constants
ehariton Jan 5, 2026
f308e0f
half way through checking corrected pressure based on inHg32 vs inHg6…
ehariton Jan 5, 2026
ca9d89a
found small 0.00009 value error on tropical data, re-computed akima-s…
ehariton Jan 5, 2026
92b28ed
spacing
ehariton Jan 5, 2026
26d248c
fixed typo in value
ehariton Jan 5, 2026
90d618c
added note on usage of MIL_STD_210A atmosphere models for transient m…
ehariton Jan 5, 2026
603b92c
note spacing
ehariton Jan 5, 2026
f0c2b94
typos
ehariton Jan 5, 2026
64af4b7
removed StandardAtm1976.py because no longer needed
ehariton Jan 5, 2026
3ec7454
added back source data for standard atmosphere
ehariton Jan 5, 2026
8473e65
ruff formatting on two files
ehariton Jan 5, 2026
6bc73bf
added dsos_dh akima calculation and akima spline info the mil spec`
ehariton Jan 5, 2026
a8b176d
added akima for dsos_dh for USatm1975 comp
ehariton Jan 5, 2026
8d44865
lint
ehariton Jan 5, 2026
7d7a094
linting on the whole repo
ehariton Jan 5, 2026
87e9792
added default units to landing_ode. commented out inHg60 pressure tes…
ehariton Jan 6, 2026
a2d732b
cleared output cells on docs
ehariton Jan 6, 2026
d105713
added inHg60 tests back in
ehariton Jan 6, 2026
5f3353e
added geodetic test to atmosphere, failing one tests on dsos_dh wrt h
ehariton Jan 6, 2026
c162208
added tests for geodetic cases
ehariton Jan 7, 2026
758544b
all added tests passing
ehariton Jan 7, 2026
b33f673
formatting
ehariton Jan 7, 2026
1ab3e8e
added figures and removed extrapolated data from raw mil-spec data se…
ehariton Jan 7, 2026
13c21f6
recompoted akima tables based on non-extrapolated source data
ehariton Jan 7, 2026
839a18c
updated default if name == main behavior of atmosphere model
ehariton Jan 7, 2026
05c5b8a
added user guide to toc and removed references to padding MILSPEC tables
ehariton Jan 7, 2026
2aba740
changed values for tests that relied on amosphere model input as long…
ehariton Jan 7, 2026
d159fab
small value adjustments based on tests failing
ehariton Jan 7, 2026
1f35483
small values changes
ehariton Jan 7, 2026
05f6243
multiple tiny values fixes
ehariton Jan 7, 2026
f8cda9e
small value check tweaks
ehariton Jan 7, 2026
70dd0ba
small values tweaks due to atmosphere update which changes some of th…
ehariton Jan 8, 2026
1b9e315
small value changes in test_reports
ehariton Jan 8, 2026
46c0a21
small numerical updates based on new values from atmosphere model
ehariton Jan 8, 2026
a3586ab
lint
ehariton Jan 8, 2026
50bb1f9
merge main
ehariton Jan 8, 2026
12577c3
Merge branch 'main' into atm2
Kenneth-T-Moore Jan 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions aviary/docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ parts:
sections:
- file: user_guide/aerodynamics
- file: user_guide/external_aero
- file: user_guide/atmosphere
- file: user_guide/propulsion
sections:
- file: user_guide/creating_a_turboprop_engine.ipynb
Expand Down
174 changes: 174 additions & 0 deletions aviary/docs/user_guide/atmosphere.ipynb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a mention of the actual names of the standards Aviary uses for its atmospheres, and what they do? I.E. 1976 standard for a general-purpose average atmosphere + the milspec for various climates

Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"tags": [
"remove-cell"
]
},
"outputs": [],
"source": [
"# Testing Cell\n",
"from aviary.subsystems.atmosphere.atmosphere import AtmosphereComp\n",
"from aviary.subsystems.atmosphere.StandardAtm1976 import atm_data\n",
"from aviary.subsystems.atmosphere.MIL_SPEC_210A_Cold import atm_data\n",
"from aviary.subsystems.atmosphere.MIL_SPEC_210A_Hot import atm_data\n",
"from aviary.subsystems.atmosphere.MIL_SPEC_210A_Polar import atm_data\n",
"from aviary.subsystems.atmosphere.MIL_SPEC_210A_Tropical import atm_data\n",
"import openmdao.api as om"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Atmosphere Subsystem\n",
"Aviary has several built-in atmosphere models that support the Aerodynamics calculations, by providing temperature, pressure, speed of sound, and viscosity based on an input altitude. There are two different atmosphere models implemented in Aviary, one coming from the 1976 standard atmosphere tables and the other coming from the publically released MIL-SPEC-210A tables. The standard 1976 tables are the default option and represent the typical conditions experienced at a given altitude. However, it is important to note that \"the atmosphere has never, and will never be, standard\". All of the atmosphere models are approximations. The MIL-SPEC-210A tables represent extreme atmospheres in tropical, arctic (polar winter), extreme hot, and extreme cold climates. \n",
"\n",
"# Comparison between Different Models\n",
"A few graphs comparing the different models have been included so the user can visually understand the different atmosphere models.\n",
"![images/Atmosphere_Profile_Temp.png](images/Atmosphere_Profile_Temp.png)\n",
"![images/Atmosphere_Profile_Pressure.png](images/Atmosphere_Profile_Pressure.png)\n",
"![images/Atmosphere_Profile_Density.png](images/Atmosphere_Profile_Density.png)\n",
"\n",
"\n",
"# How the Atmosphere Model Works\n",
"Examining `atmosphereComp.py` will show the code on how the atmosphere component is implemented. Generally speaking, akima splines that represent the raw data are loaded into the model during initialization. The akima splines are used to enhances computational speed. During every subsequent call to the atmosphere mode, an input altitude is translated via the akima splines into a temperature, pressure, density and then additional calculations are performed to determine speed of sound, and dynamic viscosity. The raw data and the akima splines of that data are contained in individual files (`StandardAtm1976.py`, `MIL_SPEC_210A_cold.py`, `MIL_SPEC_210A_hot.py`, `MIL_SPEC_210A_polar.py`, `MIL_SPEC_210A_tropical.py`). "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# User options reference for AtmosphereComp and AtmosphereGroup\n",
"There are some critical options you can pass to atmosphere that you should know about. These options will allow you to change which source data you use, swap between geocentric or geodetic altitude inputs, and add a temperature offset. Changing the source data swaps the akima splines used to calculate temperature, pressure, and density as a function of altitude. \n",
"\n",
"All the options and their defaults and functions are shown below."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"om.show_options_table('aviary.subsystems.atmosphere.atmosphere.AtmosphereComp')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Temperature Offset Options\n",
"Adding a temperature offset can enable simulation with especially hot or cold days which is useful in acoustic certification of aircraft. When inputting a temperature offset as an option, the temperature throughout the entire altitude regime is shifted up or down by this ammount. The pressure is assumed to remain constant. This is a simplification we must adhere to because we do not have any additional pressure data or assumptions to build upon. Density is then recalculated as an offset from the source data. This is important because that source data may differ from the ideal gas equations used to calculate density. This is the case for the MIL-SPEC-210A data."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# US 1976 Atmosphere Notes\n",
"The US 1976 atmospheres source information and notes are as follows:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from aviary.subsystems.atmosphere.StandardAtm1976 import DATA_ORIGIN_NOTE\n",
"\n",
"print(DATA_ORIGIN_NOTE)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# MIL-SPEC-210A Atmosphere Notes\n",
"The MIL-SPEC-210A atmospheres (including hot/cold/tropical/polar) source information and notes are as follows:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from aviary.subsystems.atmosphere.MIL_SPEC_210A_Tropical import DATA_ORIGIN_NOTE\n",
"\n",
"print(DATA_ORIGIN_NOTE)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Adding your own Atmosphere Model\n",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is developer guide atmosphere info. I'm starting to think we need to completely re-organize how we organize the docs anyway though, splitting up the subsystems into different places doesn't seem useful...

"If you desire to add your own atmosphere model you can do this one of two ways. Either create a new `AtmosphereComp.py` from scratch, or by importing a new set of raw data and using the current `atmosphereComp.py` to read it in and process it. This will include first saving your new raw data set in a new file and then creating a new set of akima splines for that data and also saving them in the same file. After that, `AtmosphereComp.py` can read in the akima's and run as normal. This walkthrough will help you perform the latter option. Start by creating a new file to hold your raw atmosphere model and the eventual akima splines. \n",
"\n",
"## Create a new Atmosphere file\n",
"You will need to make a new file to hold the raw data of your atmosphere model and the akima splines. This file should be titled after your atmosphere model, i.e. `StandardAtm1976` or `MIL_SPEC_210A_Cold`. \n",
"Save that file inside of the `aviary/subsystems/atmosphere` folder.\n",
"You will need to make a new `_raw_data` dictionary inside your new file. Look at the example `_raw_data` contained in `StandardAtm1976` for reference. \n",
"\n",
"## Converting Raw data Proper Units\n",
"From here on our we need to be especially mindful of units. We are going to use a non-openmdao helper function `_build_akima_coefs` to help create the akima coefficients. \n",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"From here on our we need to be especially mindful of units. We are going to use a non-openmdao helper function `_build_akima_coefs` to help create the akima coefficients. \n",
"From here on our we need to be especially mindful of units. We are going to use a helper function `_build_akima_coefs` to help create the akima coefficients. \n",

I don't think specifying non-openmdao adds any useful info. It's also not a dymos, numpy, pyoptsparse, etc. helper function so why single out OM?

"We only need to build the akima coefficients once and we do it so that the atmosphere model is very fast. The atmosphere model will need the following information: (Altitude, Temperature, Pressure, Density). If you don't have one of those values that's ok, typically given Altitude, Temperature, and some assumption of the pressure at sea level, all other values can be calculated based on ideal gas assumptions. \n",
"\n",
"Your units inside of `_raw_data` should be one of the following: \n",
"English: [altitude (ft, ), temperature (degF), pressure (inHg at 60degF), density (lbm/ft**3)]\n",
"Altitude can be in either in geodetic or deocentric\n",
"Pressure will only translate properly if given in inHg at 60degF. However, many data sets use inHg at 30degF. \n",
"\n",
"SI Units: [altitude (m), temperature (degK), pressure (millibar), density (kg/m^3)]\n",
"Altitude can be in either in geodetic or deocentric\n",
"\n",
"If your units do not match either English or SI as designated above, you will need to modify the `_build_akima_coefs` function to properly translate your raw data and their units.\n",
"\n",
"## Processing new Akima Splines\n",
"Next, open up `atmosphereComp.py`, you will notice that at the bottom of the file there is an call to `_build_akima_coefs` method and above that there is the `_raw_data` import location. Change the import location to point to your new `_raw_data` file and change the units to be either SI or English, depending on your raw data. Then execute `python atmosphereComp.py`, this will call the `_build_akima_coefs` to build the akima splines using your raw data. Copy those splines into your new atmosphere file you made a few steps earlier and save the file. \n",
"\n",
"## Import the Processed Data\n",
"Next we will need to import these akima splines into `AtmosphereComp()` i.e.\n",
"\n",
"`from NEW_DATA_FILE import atm_data as new_data`\n",
"\n",
"Next, you will need to edit the `Setup()` method of `AtmosphereComp()` to add in your new file as a valid option. In the `self.options.declare('data_source')` call, enter the new name for your model in the `values=new_name` field i.e.:\n",
"\n",
"`self.options.declare('data_source', values=('new_data', 'USatm1976', 'tropical', 'polar', 'hot', 'cold'), default='USatm1976')`\n",
"\n",
"Lastly below the options declarations there is a section of code that loads the atmosphere model based on the user selected options. Add a new line there to properly load youre new file:\n",
"\n",
"`elif self.options['data_source'] == 'new_name': self.source_data = new_data`\n",
"\n",
"## Test Your Model\n",
"Now that you have your model loaded and ready to go, use the manual test at the bottom of `atmosphere.py` to test inputting a few altitude values into your model and inspect the resulting output of temperature, pressure, density, speed of sound, and dynamic viscosity. "
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.12"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions aviary/interface/test/test_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ def test_timeseries_report(self):
'0.0',
'8.333333333333337',
'1.0',
'21108.418300418845',
'21108.341035874902',
'0.0',
'-10492.593707324704',
'-10492.721631142893',
'0.2',
'0.0001354166666666668',
'79560.101698',
'12.350271989430475',
'0.565484286063171',
'28478.788920867584',
'68.05737270077049',
'12.349371130670201',
'0.5654905755095957',
'28479.14295846102',
'68.0522432380756',
]
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def test_case1(self):
assert_check_partials(partial_data, atol=1e-12, rtol=1e-12)

tol = 1e-6
assert_near_equal(prob[Mission.Landing.GROUND_DISTANCE], 6331.781, tol)
assert_near_equal(prob[Mission.Landing.GROUND_DISTANCE], 6332.4878059, tol)
assert_near_equal(prob[Mission.Landing.INITIAL_VELOCITY], 134.9752, tol)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_case1(self):
assert_check_partials(partial_data, atol=1e-12, rtol=1e-12)

tol = 1e-6
assert_near_equal(prob[Mission.Takeoff.GROUND_DISTANCE], 2811.442, tol)
assert_near_equal(prob[Mission.Takeoff.GROUND_DISTANCE], 2811.50257923, tol)


if __name__ == '__main__':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def test_case1(self):
tol = 1e-5

assert_near_equal(
self.prob[Mission.Landing.GROUND_DISTANCE], 6407.19354429, tol
self.prob[Mission.Landing.GROUND_DISTANCE], 6407.65299289, tol
) # not actual value
# not actual value
assert_near_equal(self.prob[Mission.Landing.INITIAL_VELOCITY], 136.22914933, tol)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,10 +188,10 @@ def test_case1(self):
tol = 1e-5

assert_near_equal(
self.prob[Mission.Takeoff.GROUND_DISTANCE], 6637.58951504, tol
self.prob[Mission.Takeoff.GROUND_DISTANCE], 6637.65645404, tol
) # ft (not actual value)
assert_near_equal(
self.prob[Mission.Takeoff.FINAL_VELOCITY], 88.49655173, tol
self.prob[Mission.Takeoff.FINAL_VELOCITY], 88.50175527, tol
) # m/s (not actual value)
assert_near_equal(
self.prob[Mission.Takeoff.FINAL_MASS], 180623.0, tol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,14 @@ def _test_unsteady_flight_conditions(self, ground_roll=False, input_speed_type=S

p.model.add_subsystem(
name='atmosphere',
subsys=Atmosphere(num_nodes=nn, output_dsos_dh=True),
subsys=Atmosphere(num_nodes=nn),
promotes_inputs=[Dynamic.Mission.ALTITUDE],
promotes_outputs=[
Dynamic.Atmosphere.DENSITY,
Dynamic.Atmosphere.SPEED_OF_SOUND,
Dynamic.Atmosphere.TEMPERATURE,
Dynamic.Atmosphere.STATIC_PRESSURE,
'viscosity',
'drhos_dh',
'dsos_dh',
],
)
Expand Down
3 changes: 1 addition & 2 deletions aviary/mission/solved_two_dof/ode/unsteady_solved_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,14 @@ def setup(self):

self.add_subsystem(
name='atmosphere',
subsys=Atmosphere(num_nodes=nn, output_dsos_dh=True),
subsys=Atmosphere(num_nodes=nn),
promotes_inputs=[Dynamic.Mission.ALTITUDE],
promotes_outputs=[
Dynamic.Atmosphere.DENSITY,
Dynamic.Atmosphere.SPEED_OF_SOUND,
Dynamic.Atmosphere.TEMPERATURE,
Dynamic.Atmosphere.STATIC_PRESSURE,
'viscosity',
'drhos_dh',
'dsos_dh',
],
)
Expand Down
1 change: 1 addition & 0 deletions aviary/mission/two_dof/ode/landing_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def setup(self):
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')
self.set_input_defaults(Dynamic.Mission.ALTITUDE, units='ft')

# Throttle Idle
num_engine_types = len(aviary_options.get_val(Aircraft.Engine.NUM_ENGINES))
Expand Down
4 changes: 2 additions & 2 deletions aviary/mission/two_dof/ode/test/test_accel_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ def test_accel(self):
testvals = {
Dynamic.Vehicle.LIFT: [174974, 174878],
Dynamic.Vehicle.Propulsion.FUEL_FLOW_RATE_NEGATIVE_TOTAL: [
-13264.82336817,
-13567.23449581,
-13264.88347472,
-13567.32077887,
], # lbm/h
}
check_prob_outputs(self.prob, testvals, rtol=1e-6)
Expand Down
6 changes: 3 additions & 3 deletions aviary/mission/two_dof/ode/test/test_ascent_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ def test_ascent_partials(self):
tol = tol = 1e-6
assert_near_equal(
self.prob[Dynamic.Mission.VELOCITY_RATE],
np.array([642141.32322003, 642141.32322003]),
np.array([642156.99315828, 642156.99315828]),
tol,
)
assert_near_equal(
self.prob[Dynamic.Mission.FLIGHT_PATH_ANGLE_RATE],
np.array([2260.644, 2260.644]),
np.array([2260.37849562, 2260.37849562]),
tol,
)
assert_near_equal(self.prob[Dynamic.Mission.ALTITUDE_RATE], np.array([0.0, 0.0]), tol)
Expand All @@ -66,7 +66,7 @@ def test_ascent_partials(self):
assert_near_equal(self.prob['angle_of_attack_rate'], np.array([0.0, 0.0]), tol)
assert_near_equal(self.prob['normal_force'], np.array([0.0, 0.0]), tol)
assert_near_equal(self.prob['fuselage_pitch'], np.array([0.0, 0.0]), tol)
assert_near_equal(self.prob['load_factor'], np.array([11850.494, 11850.494]), tol)
assert_near_equal(self.prob['load_factor'], np.array([11849.10281268, 11849.10281268]), tol)

partial_data = self.prob.check_partials(
out_stream=None, method='cs', excludes=['*params*', '*aero*']
Expand Down
18 changes: 9 additions & 9 deletions aviary/mission/two_dof/ode/test/test_breguet_cruise_ode.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ 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, 923.16791306]), tol)
assert_near_equal(self.prob['time'], np.array([0, 8277.67602647]), tol)
assert_near_equal(self.prob[Dynamic.Mission.DISTANCE], np.array([0.0, 923.39168758]), tol)
assert_near_equal(self.prob['time'], np.array([0, 8280.30660691]), tol)
assert_near_equal(
self.prob[Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS],
np.array([3.8817684, 4.899673]),
np.array([3.88465429, 4.90288541]),
tol,
)
assert_near_equal(
self.prob[Dynamic.Mission.ALTITUDE_RATE_MAX],
np.array([-17.17989089, -16.16198629]),
np.array([-17.17541759, -16.15718646]),
tol,
)

Expand Down Expand Up @@ -119,21 +119,21 @@ def test_electric_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, 66.31948625]), tol)
assert_near_equal(self.prob['time'], np.array([0, 594.66020611]), tol)
assert_near_equal(self.prob[Dynamic.Mission.DISTANCE], np.array([0.0, 66.37436515]), tol)
assert_near_equal(self.prob['time'], np.array([0, 595.19714299]), tol)
assert_near_equal(
self.prob[Dynamic.Mission.SPECIFIC_ENERGY_RATE_EXCESS],
np.array([3.88939674, 4.90776872]),
np.array([3.89228205, 4.91098053]),
tol,
)
assert_near_equal(
self.prob[Dynamic.Mission.ALTITUDE_RATE_MAX],
np.array([-17.17226255, -16.15389057]),
np.array([-17.16778983, -16.14909135]),
tol,
)
assert_near_equal(
self.prob[Dynamic.Vehicle.Propulsion.ELECTRIC_POWER_IN_TOTAL],
np.array([4.46078513, 4.15465068]),
np.array([4.45946124, 4.15324496]),
tol,
)

Expand Down
Loading
Loading