From d69afd32aa62ae59fce1dd50907ac5c3ffa22268 Mon Sep 17 00:00:00 2001 From: Irian Ordaz Date: Wed, 18 Feb 2026 10:07:31 -0500 Subject: [PATCH 1/4] Add Reynolds number calculation to support higher order aero analysis tools --- aviary/subsystems/aerodynamics/aero_common.py | 58 +++++++++++++++++++ aviary/variable_info/variable_meta_data.py | 12 +++- aviary/variable_info/variables.py | 1 + 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/aviary/subsystems/aerodynamics/aero_common.py b/aviary/subsystems/aerodynamics/aero_common.py index e878585254..278a4fc798 100644 --- a/aviary/subsystems/aerodynamics/aero_common.py +++ b/aviary/subsystems/aerodynamics/aero_common.py @@ -1,6 +1,7 @@ import numpy as np import openmdao.api as om +from aviary.constants import GRAV_ENGLISH_FLOPS from aviary.variable_info.functions import add_aviary_input, add_aviary_output from aviary.variable_info.variables import Dynamic @@ -53,3 +54,60 @@ def compute_partials(self, inputs, partials): partials[Dynamic.Atmosphere.DYNAMIC_PRESSURE, Dynamic.Atmosphere.STATIC_PRESSURE] = ( 0.5 * gamma * M**2 ) + + +class ReynoldsNumber(om.ExplicitComponent): + """ + Compute Reynolds number as + Dynamic.Mission.REYNOLDS_NUMBER = speed of sound * Mach * density / dynamic viscosity. + """ + + def initialize(self): + self.options.declare('num_nodes', types=int) + + def setup(self): + nn = self.options['num_nodes'] + + add_aviary_input(self, Dynamic.Atmosphere.DENSITY, shape=nn, units='lbm/ft**3') + + add_aviary_input(self, Dynamic.Atmosphere.DYNAMIC_VISCOSITY, shape=nn, units='lbf*s/ft**2') + + add_aviary_input(self, Dynamic.Atmosphere.MACH, shape=nn, units='unitless') + + add_aviary_input(self, Dynamic.Atmosphere.SPEED_OF_SOUND, shape=nn, units='ft/s') + + add_aviary_output(self, Dynamic.Mission.REYNOLDS_NUMBER, shape=nn, units='1/ft') + + def setup_partials(self): + nn = self.options['num_nodes'] + + rows_cols = np.arange(nn) + + self.declare_partials( + Dynamic.Mission.REYNOLDS_NUMBER, + [Dynamic.Atmosphere.DENSITY, + Dynamic.Atmosphere.DYNAMIC_VISCOSITY, + Dynamic.Atmosphere.MACH, + Dynamic.Atmosphere.SPEED_OF_SOUND], + rows=rows_cols, + cols=rows_cols, + ) + + def compute(self, inputs, outputs): + M = inputs[Dynamic.Atmosphere.MACH] + a = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] + mu = inputs[Dynamic.Atmosphere.DYNAMIC_VISCOSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] + + outputs[Dynamic.Mission.REYNOLDS_NUMBER] = a * M * rho / mu / GRAV_ENGLISH_FLOPS + + def compute_partials(self, inputs, partials): + M = inputs[Dynamic.Atmosphere.MACH] + a = inputs[Dynamic.Atmosphere.SPEED_OF_SOUND] + mu = inputs[Dynamic.Atmosphere.DYNAMIC_VISCOSITY] + rho = inputs[Dynamic.Atmosphere.DENSITY] + + partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.DENSITY] = a * M / mu / GRAV_ENGLISH_FLOPS + partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.DYNAMIC_VISCOSITY] = -a * M * rho / mu**2 / GRAV_ENGLISH_FLOPS + partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.MACH] = a * rho / mu / GRAV_ENGLISH_FLOPS + partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.SPEED_OF_SOUND] = M * rho / mu / GRAV_ENGLISH_FLOPS \ No newline at end of file diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index 1e516e96aa..a1f7856329 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -6589,13 +6589,12 @@ Dynamic.Atmosphere.DYNAMIC_VISCOSITY, meta_data=_MetaData, historical_name={'GASP': 'XKV', 'FLOPS': None, 'LEAPS1': None}, - units='ft**2/s', + units='lbf*s/ft**2', desc="Atmospheric dynamic viscosity at the vehicle's current flight condition", default_value=0.0, multivalue=True, ) - add_meta_data( Dynamic.Atmosphere.KINEMATIC_VISCOSITY, meta_data=_MetaData, @@ -6729,6 +6728,15 @@ multivalue=True, ) +add_meta_data( + Dynamic.Mission.REYNOLDS_NUMBER, + meta_data=_MetaData, + historical_name={'GASP': None, 'FLOPS': None, 'LEAPS1': None}, + units='1/ft', + desc='Reynolds number at current flight condition', + multivalue=True, +) + add_meta_data( Dynamic.Mission.SPECIFIC_ENERGY, meta_data=_MetaData, diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 26f8a22b45..1f4fe58912 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -593,6 +593,7 @@ class Mission: DISTANCE_RATE = 'distance_rate' FLIGHT_PATH_ANGLE = 'flight_path_angle' FLIGHT_PATH_ANGLE_RATE = 'flight_path_angle_rate' + REYNOLDS_NUMBER = "reynolds_number" SPECIFIC_ENERGY = 'specific_energy' SPECIFIC_ENERGY_RATE = 'specific_energy_rate' SPECIFIC_ENERGY_RATE_EXCESS = 'specific_energy_rate_excess' From 1704b06db0e51d45b12d5ad567658c60ea5bc7ec Mon Sep 17 00:00:00 2001 From: Irian Ordaz Date: Wed, 18 Feb 2026 11:11:22 -0500 Subject: [PATCH 2/4] Rename variable name --- aviary/subsystems/aerodynamics/aero_common.py | 16 ++++++++-------- aviary/variable_info/variable_meta_data.py | 4 ++-- aviary/variable_info/variables.py | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/aviary/subsystems/aerodynamics/aero_common.py b/aviary/subsystems/aerodynamics/aero_common.py index 278a4fc798..f3e76895eb 100644 --- a/aviary/subsystems/aerodynamics/aero_common.py +++ b/aviary/subsystems/aerodynamics/aero_common.py @@ -59,7 +59,7 @@ def compute_partials(self, inputs, partials): class ReynoldsNumber(om.ExplicitComponent): """ Compute Reynolds number as - Dynamic.Mission.REYNOLDS_NUMBER = speed of sound * Mach * density / dynamic viscosity. + Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH_PER_UNIT_LENGTH = speed of sound * Mach * density / dynamic viscosity. """ def initialize(self): @@ -76,7 +76,7 @@ def setup(self): add_aviary_input(self, Dynamic.Atmosphere.SPEED_OF_SOUND, shape=nn, units='ft/s') - add_aviary_output(self, Dynamic.Mission.REYNOLDS_NUMBER, shape=nn, units='1/ft') + add_aviary_output(self, Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, shape=nn, units='1/ft') def setup_partials(self): nn = self.options['num_nodes'] @@ -84,7 +84,7 @@ def setup_partials(self): rows_cols = np.arange(nn) self.declare_partials( - Dynamic.Mission.REYNOLDS_NUMBER, + Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, [Dynamic.Atmosphere.DENSITY, Dynamic.Atmosphere.DYNAMIC_VISCOSITY, Dynamic.Atmosphere.MACH, @@ -99,7 +99,7 @@ def compute(self, inputs, outputs): mu = inputs[Dynamic.Atmosphere.DYNAMIC_VISCOSITY] rho = inputs[Dynamic.Atmosphere.DENSITY] - outputs[Dynamic.Mission.REYNOLDS_NUMBER] = a * M * rho / mu / GRAV_ENGLISH_FLOPS + outputs[Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH] = a * M * rho / mu / GRAV_ENGLISH_FLOPS def compute_partials(self, inputs, partials): M = inputs[Dynamic.Atmosphere.MACH] @@ -107,7 +107,7 @@ def compute_partials(self, inputs, partials): mu = inputs[Dynamic.Atmosphere.DYNAMIC_VISCOSITY] rho = inputs[Dynamic.Atmosphere.DENSITY] - partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.DENSITY] = a * M / mu / GRAV_ENGLISH_FLOPS - partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.DYNAMIC_VISCOSITY] = -a * M * rho / mu**2 / GRAV_ENGLISH_FLOPS - partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.MACH] = a * rho / mu / GRAV_ENGLISH_FLOPS - partials[Dynamic.Mission.REYNOLDS_NUMBER, Dynamic.Atmosphere.SPEED_OF_SOUND] = M * rho / mu / GRAV_ENGLISH_FLOPS \ No newline at end of file + partials[Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, Dynamic.Atmosphere.DENSITY] = a * M / mu / GRAV_ENGLISH_FLOPS + partials[Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, Dynamic.Atmosphere.DYNAMIC_VISCOSITY] = -a * M * rho / mu**2 / GRAV_ENGLISH_FLOPS + partials[Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, Dynamic.Atmosphere.MACH] = a * rho / mu / GRAV_ENGLISH_FLOPS + partials[Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, Dynamic.Atmosphere.SPEED_OF_SOUND] = M * rho / mu / GRAV_ENGLISH_FLOPS \ No newline at end of file diff --git a/aviary/variable_info/variable_meta_data.py b/aviary/variable_info/variable_meta_data.py index a1f7856329..e02794e482 100644 --- a/aviary/variable_info/variable_meta_data.py +++ b/aviary/variable_info/variable_meta_data.py @@ -6729,11 +6729,11 @@ ) add_meta_data( - Dynamic.Mission.REYNOLDS_NUMBER, + Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH, meta_data=_MetaData, historical_name={'GASP': None, 'FLOPS': None, 'LEAPS1': None}, units='1/ft', - desc='Reynolds number at current flight condition', + desc='Reynolds number per unit length at current flight condition', multivalue=True, ) diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 1f4fe58912..128a227b3c 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -593,7 +593,7 @@ class Mission: DISTANCE_RATE = 'distance_rate' FLIGHT_PATH_ANGLE = 'flight_path_angle' FLIGHT_PATH_ANGLE_RATE = 'flight_path_angle_rate' - REYNOLDS_NUMBER = "reynolds_number" + REYNOLDS_NUMBER_PER_UNIT_LENGTH = "reynolds_number" SPECIFIC_ENERGY = 'specific_energy' SPECIFIC_ENERGY_RATE = 'specific_energy_rate' SPECIFIC_ENERGY_RATE_EXCESS = 'specific_energy_rate_excess' From f57ab27066ec4fd3178cdfd0306f26e33f905188 Mon Sep 17 00:00:00 2001 From: Irian Ordaz Date: Wed, 18 Feb 2026 11:13:56 -0500 Subject: [PATCH 3/4] Fix typo --- aviary/subsystems/aerodynamics/aero_common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/subsystems/aerodynamics/aero_common.py b/aviary/subsystems/aerodynamics/aero_common.py index f3e76895eb..6b007ba3ce 100644 --- a/aviary/subsystems/aerodynamics/aero_common.py +++ b/aviary/subsystems/aerodynamics/aero_common.py @@ -59,7 +59,7 @@ def compute_partials(self, inputs, partials): class ReynoldsNumber(om.ExplicitComponent): """ Compute Reynolds number as - Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH_PER_UNIT_LENGTH = speed of sound * Mach * density / dynamic viscosity. + Dynamic.Mission.REYNOLDS_NUMBER_PER_UNIT_LENGTH = speed of sound * Mach * density / dynamic viscosity. """ def initialize(self): From 88966315006d3d6aec50f79c3e42eeb1b17be73c Mon Sep 17 00:00:00 2001 From: Irian Ordaz Date: Wed, 18 Feb 2026 11:17:28 -0500 Subject: [PATCH 4/4] Update raw string --- aviary/variable_info/variables.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aviary/variable_info/variables.py b/aviary/variable_info/variables.py index 128a227b3c..fc3982e51f 100644 --- a/aviary/variable_info/variables.py +++ b/aviary/variable_info/variables.py @@ -593,7 +593,7 @@ class Mission: DISTANCE_RATE = 'distance_rate' FLIGHT_PATH_ANGLE = 'flight_path_angle' FLIGHT_PATH_ANGLE_RATE = 'flight_path_angle_rate' - REYNOLDS_NUMBER_PER_UNIT_LENGTH = "reynolds_number" + REYNOLDS_NUMBER_PER_UNIT_LENGTH = "reynolds_number_per_unit_length" SPECIFIC_ENERGY = 'specific_energy' SPECIFIC_ENERGY_RATE = 'specific_energy_rate' SPECIFIC_ENERGY_RATE_EXCESS = 'specific_energy_rate_excess'