def finalize_sub_segments(segment, state): from SUAVE.Analyses.Mission.Segments.Conditions import Conditions for tag, sub_segment in segment.segments.items(): sub_segment.finalize(state.segments[tag]) state.segments[tag].initials = Conditions()
def finalize_sub_segments(segment, state): """ Sets the conditions in each sub segment for a mission Assumptions: N/A Inputs: N/A Outputs: N/A Properties Used: N/A """ from SUAVE.Analyses.Mission.Segments.Conditions import Conditions for tag, sub_segment in segment.segments.items(): sub_segment.finalize(state.segments[tag]) state.segments[tag].initials = Conditions()
def compute_values(self,altitude,temperature_deviation=0.0,var_gamma=False): """Computes atmospheric values. Assumptions: US 1976 Standard Atmosphere Source: U.S. Standard Atmosphere, 1976, U.S. Government Printing Office, Washington, D.C., 1976 Inputs: altitude [m] temperature_deviation [K] Output: atmo_data. pressure [Pa] temperature [K] speed_of_sound [m/s] dynamic_viscosity [kg/(m*s)] kinematic_viscosity [m^2/s] thermal_conductivity [W/(m*K)] prandtl_number [-] Properties Used: self. fluid_properties.gas_specific_constant [J/(kg*K)] planet.sea_level_gravity [m/s^2] planet.mean_radius [m] breaks. altitude [m] temperature [K] pressure [Pa] """ # unpack zs = altitude gas = self.fluid_properties planet = self.planet grav = self.planet.sea_level_gravity Rad = self.planet.mean_radius R = gas.gas_specific_constant delta_isa = temperature_deviation # check properties if not gas == Air(): warn('US Standard Atmosphere not using Air fluid properties') if not planet == Earth(): warn('US Standard Atmosphere not using Earth planet properties') # convert input if necessary zs = atleast_2d_col(zs) # get model altitude bounds zmin = self.breaks.altitude[0] zmax = self.breaks.altitude[-1] # convert geometric to geopotential altitude zs = zs/(1 + zs/Rad) # check ranges if np.amin(zs) < zmin: print("Warning: altitude requested below minimum for this atmospheric model; returning values for h = -2.0 km") zs[zs < zmin] = zmin if np.amax(zs) > zmax: print("Warning: altitude requested above maximum for this atmospheric model; returning values for h = 86.0 km") zs[zs > zmax] = zmax # initialize return data zeros = np.zeros_like(zs) p = zeros * 0.0 T = zeros * 0.0 rho = zeros * 0.0 a = zeros * 0.0 mu = zeros * 0.0 z0 = zeros * 0.0 T0 = zeros * 0.0 p0 = zeros * 0.0 alpha = zeros * 0.0 # populate the altitude breaks # this uses >= and <= to capture both edges and because values should be the same at the edges for i in range( len(self.breaks.altitude)-1 ): i_inside = (zs >= self.breaks.altitude[i]) & (zs <= self.breaks.altitude[i+1]) z0[ i_inside ] = self.breaks.altitude[i] T0[ i_inside ] = self.breaks.temperature[i] p0[ i_inside ] = self.breaks.pressure[i] alpha[ i_inside ] = -(self.breaks.temperature[i+1] - self.breaks.temperature[i])/ \ (self.breaks.altitude[i+1] - self.breaks.altitude[i]) # interpolate the breaks dz = zs-z0 i_isoth = (alpha == 0.) i_adiab = (alpha != 0.) p[i_isoth] = p0[i_isoth] * np.exp(-1.*dz[i_isoth]*grav/(R*T0[i_isoth])) p[i_adiab] = p0[i_adiab] * ( (1.-alpha[i_adiab]*dz[i_adiab]/T0[i_adiab]) **(1.*grav/(alpha[i_adiab]*R)) ) T = T0 - dz*alpha + delta_isa rho = gas.compute_density(T,p) a = gas.compute_speed_of_sound(T,p,var_gamma) mu = gas.compute_absolute_viscosity(T) K = gas.compute_thermal_conductivity(T) Pr = gas.compute_prandtl_number(T) atmo_data = Conditions() atmo_data.expand_rows(zs.shape[0]) atmo_data.pressure = p atmo_data.temperature = T atmo_data.density = rho atmo_data.speed_of_sound = a atmo_data.dynamic_viscosity = mu atmo_data.kinematic_viscosity = mu/rho atmo_data.thermal_conductivity = K atmo_data.prandtl_number = Pr return atmo_data
def compute_values(self,altitude,temperature_deviation = 0): """ Computes values from the International Standard Atmosphere Inputs: altitude : geometric altitude (elevation) (m) can be a float, list or 1D array of floats temperature_deviation : delta_isa Outputs: list of conditions - pressure : static pressure (Pa) temperature : static temperature (K) density : density (kg/m^3) speed_of_sound : speed of sound (m/s) dynamic_viscosity : dynamic_viscosity (kg/m-s) Example: atmosphere = SUAVE.Attributes.Atmospheres.Earth.USStandard1976() atmosphere.ComputeValues(1000).pressure """ # unpack zs = altitude gas = self.fluid_properties planet = self.planet grav = self.planet.sea_level_gravity Rad = self.planet.mean_radius gamma = gas.gas_specific_constant delta_isa = temperature_deviation # check properties if not gas == Air(): warn('US Standard Atmosphere not using Air fluid properties') if not planet == Earth(): warn('US Standard Atmosphere not using Earth planet properties') # convert input if necessary zs = atleast_2d_col(zs) # get model altitude bounds zmin = self.breaks.altitude[0] zmax = self.breaks.altitude[-1] # convert geometric to geopotential altitude zs = zs/(1 + zs/Rad) # check ranges if np.amin(zs) < zmin: print "Warning: altitude requested below minimum for this atmospheric model; returning values for h = -2.0 km" zs[zs < zmin] = zmin if np.amax(zs) > zmax: print "Warning: altitude requested above maximum for this atmospheric model; returning values for h = 86.0 km" zs[zs > zmax] = zmax # initialize return data zeros = np.zeros_like(zs) p = zeros * 0.0 T = zeros * 0.0 rho = zeros * 0.0 a = zeros * 0.0 mew = zeros * 0.0 z0 = zeros * 0.0 T0 = zeros * 0.0 p0 = zeros * 0.0 alpha = zeros * 0.0 # populate the altitude breaks # this uses >= and <= to capture both edges and because values should be the same at the edges for i in range( len(self.breaks.altitude)-1 ): i_inside = (zs >= self.breaks.altitude[i]) & (zs <= self.breaks.altitude[i+1]) z0[ i_inside ] = self.breaks.altitude[i] T0[ i_inside ] = self.breaks.temperature[i] p0[ i_inside ] = self.breaks.pressure[i] alpha[ i_inside ] = -(self.breaks.temperature[i+1] - self.breaks.temperature[i])/ \ (self.breaks.altitude[i+1] - self.breaks.altitude[i]) # interpolate the breaks dz = zs-z0 i_isoth = (alpha == 0.) i_adiab = (alpha != 0.) p[i_isoth] = p0[i_isoth] * np.exp(-1.*dz[i_isoth]*grav/(gamma*T0[i_isoth])) p[i_adiab] = p0[i_adiab] * ( (1.-alpha[i_adiab]*dz[i_adiab]/T0[i_adiab]) **(1.*grav/(alpha[i_adiab]*gamma)) ) T = T0 - dz*alpha + delta_isa rho = gas.compute_density(T,p) a = gas.compute_speed_of_sound(T) mew = gas.compute_absolute_viscosity(T) atmo_data = Conditions() atmo_data.expand_rows(zs.shape[0]) atmo_data.pressure = p atmo_data.temperature = T atmo_data.density = rho atmo_data.speed_of_sound = a atmo_data.dynamic_viscosity = mew return atmo_data
def compute_values(self,altitude,temperature=288.15): """Computes atmospheric values. Assumptions: Constant temperature atmosphere Source: U.S. Standard Atmosphere, 1976, U.S. Government Printing Office, Washington, D.C., 1976 Inputs: altitude [m] temperature [K] Outputs: atmo_data. pressure [Pa] temperature [K] speed_of_sound [m/s] dynamic_viscosity [kg/(m*s)] Properties Used: self. fluid_properties.gas_specific_constant [J/(kg*K)] planet.sea_level_gravity [m/s^2] planet.mean_radius [m] breaks. altitude [m] pressure [Pa] """ # unpack zs = altitude gas = self.fluid_properties planet = self.planet grav = self.planet.sea_level_gravity Rad = self.planet.mean_radius R = gas.gas_specific_constant # check properties if not gas == Air(): warn('Constant_Temperature Atmosphere not using Air fluid properties') if not planet == Earth(): warn('Constant_Temperature Atmosphere not using Earth planet properties') # convert input if necessary zs = atleast_2d_col(zs) # get model altitude bounds zmin = self.breaks.altitude[0] zmax = self.breaks.altitude[-1] # convert geometric to geopotential altitude zs = zs/(1 + zs/Rad) # check ranges if np.amin(zs) < zmin: print("Warning: altitude requested below minimum for this atmospheric model; returning values for h = -2.0 km") zs[zs < zmin] = zmin if np.amax(zs) > zmax: print("Warning: altitude requested above maximum for this atmospheric model; returning values for h = 86.0 km") zs[zs > zmax] = zmax # initialize return data zeros = np.zeros_like(zs) p = zeros * 0.0 T = zeros * 0.0 rho = zeros * 0.0 a = zeros * 0.0 mu = zeros * 0.0 z0 = zeros * 0.0 T0 = zeros * 0.0 p0 = zeros * 0.0 alpha = zeros * 0.0 # populate the altitude breaks # this uses >= and <= to capture both edges and because values should be the same at the edges for i in range( len(self.breaks.altitude)-1 ): i_inside = (zs >= self.breaks.altitude[i]) & (zs <= self.breaks.altitude[i+1]) z0[ i_inside ] = self.breaks.altitude[i] T0[ i_inside ] = temperature p0[ i_inside ] = self.breaks.pressure[i] self.breaks.temperature[i+1]=temperature alpha[ i_inside ] = -(temperature - temperature)/ \ (self.breaks.altitude[i+1] - self.breaks.altitude[i]) # interpolate the breaks dz = zs-z0 i_isoth = (alpha == 0.) p = p0* np.exp(-1.*dz*grav/(R*T0)) T = temperature rho = gas.compute_density(T,p) a = gas.compute_speed_of_sound(T) mu = gas.compute_absolute_viscosity(T) atmo_data = Conditions() atmo_data.expand_rows(zs.shape[0]) atmo_data.pressure = p atmo_data.temperature = T atmo_data.density = rho atmo_data.speed_of_sound = a atmo_data.dynamic_viscosity = mu return atmo_data
def compute_values(self,altitude,temperature=288.15): """Computes atmospheric values. Assumptions: Constant temperature atmosphere Source: U.S. Standard Atmosphere, 1976, U.S. Government Printing Office, Washington, D.C., 1976 Inputs: altitude [m] temperature [K] Outputs: atmo_data. pressure [Pa] temperature [K] speed_of_sound [m/s] dynamic_viscosity [kg/(m*s)] Properties Used: self. fluid_properties.gas_specific_constant [J/(kg*K)] planet.sea_level_gravity [m/s^2] planet.mean_radius [m] breaks. altitude [m] pressure [Pa] """ # unpack zs = altitude gas = self.fluid_properties planet = self.planet grav = self.planet.sea_level_gravity Rad = self.planet.mean_radius R = gas.gas_specific_constant # check properties if not gas == Air(): warn('Constant_Temperature Atmosphere not using Air fluid properties') if not planet == Earth(): warn('Constant_Temperature Atmosphere not using Earth planet properties') # convert input if necessary zs = atleast_2d_col(zs) # get model altitude bounds zmin = self.breaks.altitude[0] zmax = self.breaks.altitude[-1] # convert geometric to geopotential altitude zs = zs/(1 + zs/Rad) # check ranges if np.amin(zs) < zmin: print "Warning: altitude requested below minimum for this atmospheric model; returning values for h = -2.0 km" zs[zs < zmin] = zmin if np.amax(zs) > zmax: print "Warning: altitude requested above maximum for this atmospheric model; returning values for h = 86.0 km" zs[zs > zmax] = zmax # initialize return data zeros = np.zeros_like(zs) p = zeros * 0.0 T = zeros * 0.0 rho = zeros * 0.0 a = zeros * 0.0 mu = zeros * 0.0 z0 = zeros * 0.0 T0 = zeros * 0.0 p0 = zeros * 0.0 alpha = zeros * 0.0 # populate the altitude breaks # this uses >= and <= to capture both edges and because values should be the same at the edges for i in range( len(self.breaks.altitude)-1 ): i_inside = (zs >= self.breaks.altitude[i]) & (zs <= self.breaks.altitude[i+1]) z0[ i_inside ] = self.breaks.altitude[i] T0[ i_inside ] = temperature p0[ i_inside ] = self.breaks.pressure[i] self.breaks.temperature[i+1]=temperature alpha[ i_inside ] = -(temperature - temperature)/ \ (self.breaks.altitude[i+1] - self.breaks.altitude[i]) # interpolate the breaks dz = zs-z0 i_isoth = (alpha == 0.) p = p0* np.exp(-1.*dz*grav/(R*T0)) T = temperature rho = gas.compute_density(T,p) a = gas.compute_speed_of_sound(T) mu = gas.compute_absolute_viscosity(T) atmo_data = Conditions() atmo_data.expand_rows(zs.shape[0]) atmo_data.pressure = p atmo_data.temperature = T atmo_data.density = rho atmo_data.speed_of_sound = a atmo_data.dynamic_viscosity = mu return atmo_data
def evaluate_thrust(self, state): """ Calculate thrust given the current state of the vehicle Assumptions: None Source: N/A Inputs: state [state()] Outputs: results.thrust_force_vector [newtons] results.vehicle_mass_rate [kg/s] conditions.noise.sources.turbofan: core: exit_static_temperature exit_static_pressure exit_stagnation_temperature exit_stagnation_pressure exit_velocity fan: exit_static_temperature exit_static_pressure exit_stagnation_temperature exit_stagnation_pressure exit_velocity Properties Used: Defaulted values """ #Unpack conditions = state.conditions ram = self.ram inlet_nozzle = self.inlet_nozzle low_pressure_compressor = self.low_pressure_compressor high_pressure_compressor = self.high_pressure_compressor fan = self.fan combustor = self.combustor high_pressure_turbine = self.high_pressure_turbine low_pressure_turbine = self.low_pressure_turbine core_nozzle = self.core_nozzle fan_nozzle = self.fan_nozzle thrust = self.thrust bypass_ratio = self.bypass_ratio number_of_engines = self.number_of_engines #Creating the network by manually linking the different components #set the working fluid to determine the fluid properties ram.inputs.working_fluid = self.working_fluid #Flow through the ram , this computes the necessary flow quantities and stores it into conditions ram(conditions) #link inlet nozzle to ram inlet_nozzle.inputs.stagnation_temperature = ram.outputs.stagnation_temperature inlet_nozzle.inputs.stagnation_pressure = ram.outputs.stagnation_pressure #Flow through the inlet nozzle inlet_nozzle(conditions) #--link low pressure compressor to the inlet nozzle low_pressure_compressor.inputs.stagnation_temperature = inlet_nozzle.outputs.stagnation_temperature low_pressure_compressor.inputs.stagnation_pressure = inlet_nozzle.outputs.stagnation_pressure #Flow through the low pressure compressor low_pressure_compressor(conditions) #link the high pressure compressor to the low pressure compressor high_pressure_compressor.inputs.stagnation_temperature = low_pressure_compressor.outputs.stagnation_temperature high_pressure_compressor.inputs.stagnation_pressure = low_pressure_compressor.outputs.stagnation_pressure #Flow through the high pressure compressor high_pressure_compressor(conditions) #Link the fan to the inlet nozzle fan.inputs.stagnation_temperature = inlet_nozzle.outputs.stagnation_temperature fan.inputs.stagnation_pressure = inlet_nozzle.outputs.stagnation_pressure #flow through the fan fan(conditions) #link the combustor to the high pressure compressor combustor.inputs.stagnation_temperature = high_pressure_compressor.outputs.stagnation_temperature combustor.inputs.stagnation_pressure = high_pressure_compressor.outputs.stagnation_pressure #flow through the high pressor comprresor combustor(conditions) # link the shaft power output to the low pressure compressor try: shaft_power = self.Shaft_Power_Off_Take shaft_power.inputs.mdhc = thrust.compressor_nondimensional_massflow shaft_power.inputs.Tref = thrust.reference_temperature shaft_power.inputs.Pref = thrust.reference_pressure shaft_power.inputs.total_temperature_reference = low_pressure_compressor.outputs.stagnation_temperature shaft_power.inputs.total_pressure_reference = low_pressure_compressor.outputs.stagnation_pressure shaft_power(conditions) except: pass #link the high pressure turbine to the combustor high_pressure_turbine.inputs.stagnation_temperature = combustor.outputs.stagnation_temperature high_pressure_turbine.inputs.stagnation_pressure = combustor.outputs.stagnation_pressure high_pressure_turbine.inputs.fuel_to_air_ratio = combustor.outputs.fuel_to_air_ratio #link the high pressuer turbine to the high pressure compressor high_pressure_turbine.inputs.compressor = high_pressure_compressor.outputs #link the high pressure turbine to the fan high_pressure_turbine.inputs.fan = fan.outputs high_pressure_turbine.inputs.bypass_ratio = 0.0 #set to zero to ensure that fan not linked here #flow through the high pressure turbine high_pressure_turbine(conditions) #link the low pressure turbine to the high pressure turbine low_pressure_turbine.inputs.stagnation_temperature = high_pressure_turbine.outputs.stagnation_temperature low_pressure_turbine.inputs.stagnation_pressure = high_pressure_turbine.outputs.stagnation_pressure #link the low pressure turbine to the low_pressure_compresor low_pressure_turbine.inputs.compressor = low_pressure_compressor.outputs #link the low pressure turbine to the combustor low_pressure_turbine.inputs.fuel_to_air_ratio = combustor.outputs.fuel_to_air_ratio #link the low pressure turbine to the fan low_pressure_turbine.inputs.fan = fan.outputs # link the low pressure turbine to the shaft power, if needed try: low_pressure_turbine.inputs.shaft_power_off_take = shaft_power.outputs except: pass #get the bypass ratio from the thrust component low_pressure_turbine.inputs.bypass_ratio = bypass_ratio #flow through the low pressure turbine low_pressure_turbine(conditions) #link the core nozzle to the low pressure turbine core_nozzle.inputs.stagnation_temperature = low_pressure_turbine.outputs.stagnation_temperature core_nozzle.inputs.stagnation_pressure = low_pressure_turbine.outputs.stagnation_pressure #flow through the core nozzle core_nozzle(conditions) #link the dan nozzle to the fan fan_nozzle.inputs.stagnation_temperature = fan.outputs.stagnation_temperature fan_nozzle.inputs.stagnation_pressure = fan.outputs.stagnation_pressure # flow through the fan nozzle fan_nozzle(conditions) # compute the thrust using the thrust component #link the thrust component to the fan nozzle thrust.inputs.fan_exit_velocity = fan_nozzle.outputs.velocity thrust.inputs.fan_area_ratio = fan_nozzle.outputs.area_ratio thrust.inputs.fan_nozzle = fan_nozzle.outputs #link the thrust component to the core nozzle thrust.inputs.core_exit_velocity = core_nozzle.outputs.velocity thrust.inputs.core_area_ratio = core_nozzle.outputs.area_ratio thrust.inputs.core_nozzle = core_nozzle.outputs #link the thrust component to the combustor thrust.inputs.fuel_to_air_ratio = combustor.outputs.fuel_to_air_ratio #link the thrust component to the low pressure compressor thrust.inputs.total_temperature_reference = low_pressure_compressor.outputs.stagnation_temperature thrust.inputs.total_pressure_reference = low_pressure_compressor.outputs.stagnation_pressure thrust.inputs.number_of_engines = number_of_engines thrust.inputs.bypass_ratio = bypass_ratio thrust.inputs.flow_through_core = 1. / ( 1. + bypass_ratio ) #scaled constant to turn on core thrust computation thrust.inputs.flow_through_fan = bypass_ratio / ( 1. + bypass_ratio ) #scaled constant to turn on fan thrust computation #compute the thrust thrust(conditions) #getting the network outputs from the thrust outputs F = thrust.outputs.thrust * [1, 0, 0] mdot = thrust.outputs.fuel_flow_rate output_power = thrust.outputs.power F_vec = conditions.ones_row(3) * 0.0 F_vec[:, 0] = F[:, 0] F = F_vec results = Data() results.thrust_force_vector = F results.vehicle_mass_rate = mdot # store data core_outputs = Data( exit_static_temperature=core_nozzle.outputs.static_temperature, exit_static_pressure=core_nozzle.outputs.static_pressure, exit_stagnation_temperature=core_nozzle.outputs. stagnation_temperature, exit_stagnation_pressure=core_nozzle.outputs.static_pressure, exit_velocity=core_nozzle.outputs.velocity) fan_outputs = Data( exit_static_temperature=fan_nozzle.outputs.static_temperature, exit_static_pressure=fan_nozzle.outputs.static_pressure, exit_stagnation_temperature=fan_nozzle.outputs. stagnation_temperature, exit_stagnation_pressure=fan_nozzle.outputs.static_pressure, exit_velocity=fan_nozzle.outputs.velocity) conditions.noise.sources.turbofan = Conditions() conditions.noise.sources.turbofan.fan = fan_outputs conditions.noise.sources.turbofan.core = core_outputs return results
def evaluate_thrust(self, state): """ Calculate thrust given the current state of the vehicle Assumptions: None Source: N/A Inputs: state [state()] Outputs: results.thrust_force_vector [newtons] results.vehicle_mass_rate [kg/s] results.power [Watts] conditions.noise.sources.ducted_fan: fan: exit_static_temperature exit_static_pressure exit_stagnation_temperature exit_stagnation_pressure exit_velocity Properties Used: Defaulted values """ #Unpack conditions = state.conditions ram = self.ram inlet_nozzle = self.inlet_nozzle fan = self.fan fan_nozzle = self.fan_nozzle thrust = self.thrust #Creating the network by manually linking the different components #set the working fluid to determine the fluid properties ram.inputs.working_fluid = self.working_fluid #Flow through the ram , this computes the necessary flow quantities and stores it into conditions ram(conditions) #link inlet nozzle to ram inlet_nozzle.inputs.stagnation_temperature = ram.outputs.stagnation_temperature inlet_nozzle.inputs.stagnation_pressure = ram.outputs.stagnation_pressure #Flow through the inlet nozzle inlet_nozzle(conditions) #Link the fan to the inlet nozzle fan.inputs.stagnation_temperature = inlet_nozzle.outputs.stagnation_temperature fan.inputs.stagnation_pressure = inlet_nozzle.outputs.stagnation_pressure #flow through the fan fan(conditions) #link the fan nozzle to the fan fan_nozzle.inputs.stagnation_temperature = fan.outputs.stagnation_temperature fan_nozzle.inputs.stagnation_pressure = fan.outputs.stagnation_pressure thrust.inputs.fuel_to_air_ratio = 0. # flow through the fan nozzle fan_nozzle(conditions) # compute the thrust using the thrust component #link the thrust component to the fan nozzle thrust.inputs.fan_exit_velocity = fan_nozzle.outputs.velocity thrust.inputs.fan_area_ratio = fan_nozzle.outputs.area_ratio thrust.inputs.fan_nozzle = fan_nozzle.outputs thrust.inputs.bypass_ratio = self.bypass_ratio #0.0 #compute the thrust thrust(conditions) #obtain the network outputs from the thrust outputs u0 = conditions.freestream.velocity u8 = fan_nozzle.outputs.velocity propulsive_efficiency = 2. / (1 + u8 / u0) F = thrust.outputs.thrust * [1, 0, 0] mdot = thrust.outputs.fuel_flow_rate Isp = thrust.outputs.specific_impulse output_power = thrust.outputs.power F_vec = conditions.ones_row(3) * 0.0 F_vec[:, 0] = F[:, 0] F = F_vec #pack outputs results = Data() results.thrust_force_vector = F results.vehicle_mass_rate = mdot results.power = np.divide(output_power[:, 0], propulsive_efficiency[:, 0]) # store data results_conditions = Data fan_outputs = results_conditions( exit_static_temperature=fan_nozzle.outputs.static_temperature, exit_static_pressure=fan_nozzle.outputs.static_pressure, exit_stagnation_temperature=fan_nozzle.outputs. stagnation_temperature, exit_stagnation_pressure=fan_nozzle.outputs.static_pressure, exit_velocity=fan_nozzle.outputs.velocity) conditions.noise.sources.ducted_fan = Conditions() conditions.noise.sources.ducted_fan.fan = fan_outputs return results