diff --git a/aviary/subsystems/aerodynamics/aero_common.py b/aviary/subsystems/aerodynamics/aero_common.py index e87858525..6b007ba3c 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_PER_UNIT_LENGTH = 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_PER_UNIT_LENGTH, 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_PER_UNIT_LENGTH, + [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_PER_UNIT_LENGTH] = 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_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 1e516e96a..e02794e48 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_PER_UNIT_LENGTH, + meta_data=_MetaData, + historical_name={'GASP': None, 'FLOPS': None, 'LEAPS1': None}, + units='1/ft', + desc='Reynolds number per unit length 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 26f8a22b4..fc3982e51 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_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'