Source code for RCAIDE.Library.Mission.Segments.Climb.Constant_Dynamic_Pressure_Constant_Angle

# RCAIDE/Library/Missions/Segments/Climb/Constant_Dynamic_Pressure_Constant_Angle.py
# 
# 
# Created:  Jul 2023, M. Clarke

# ----------------------------------------------------------------------------------------------------------------------
#  IMPORT
# ----------------------------------------------------------------------------------------------------------------------
# RCAIDE 
import RCAIDE 

# Package imports  
import numpy as np
 
# ----------------------------------------------------------------------------------------------------------------------
#  Initialize Conditions
# ----------------------------------------------------------------------------------------------------------------------
[docs] def initialize_conditions_unpack_unknowns(segment): """Sets the specified conditions which are given for the segment type. Assumptions: Constrant dynamic pressure and constant rate of climb Source: N/A Inputs: segment.climb_angle [radians] segment.dynamic_pressure [pascals] segment.altitude_start [meters] segment.altitude_end [meters] segment.state.numerics.dimensionless.control_points [unitless] conditions.freestream.density [kilograms/meter^3] Outputs: conditions.frames.inertial.velocity_vector [meters/second] conditions.frames.inertial.position_vector [meters] conditions.frames.body.inertial_rotations [radians] Properties Used: N/A """ # unpack climb_angle = segment.climb_angle q = segment.dynamic_pressure alt0 = segment.altitude_start conditions = segment.state.conditions beta = segment.sideslip_angle rho = conditions.freestream.density[:,0] # unpack unknowns alts = conditions.frames.inertial.position_vector[:,2] # Update freestream to get density RCAIDE.Library.Mission.Common.Update.atmosphere(segment) rho = conditions.freestream.density[:,0] # check for initial altitude if alt0 is None: if not segment.state.initials: raise AttributeError('initial altitude not set') alt0 = -1.0 * segment.state.initials.conditions.frames.inertial.position_vector[-1,2] # pack conditions conditions.freestream.altitude[:,0] = -alts # positive altitude in this context # check for initial velocity if q is None: if not segment.state.initials: raise AttributeError('dynamic pressure not set') v_mag = np.linalg.norm(segment.state.initials.conditions.frames.inertial.velocity_vector[-1]) else: # Update freestream to get density RCAIDE.Library.Mission.Common.Update.atmosphere(segment) rho = conditions.freestream.density[:,0] # process velocity vector v_mag = np.sqrt(2*q/rho) v_x = np.cos(beta)*v_mag * np.cos(climb_angle) v_y = np.sin(beta)*v_mag * np.cos(climb_angle) v_z = -v_mag * np.sin(climb_angle) # pack conditions conditions.frames.inertial.velocity_vector[:,0] = v_x conditions.frames.inertial.velocity_vector[:,1] = v_y conditions.frames.inertial.velocity_vector[:,2] = v_z
[docs] def residual_altitude(segment): """Computes the altitude residual Assumptions: No higher order terms. Source: N/A Inputs: segment.state.conditions.frames.inertial.total_force_vector [Newtons] segment.state.conditions.frames.inertial.acceleration_vector [meter/second^2] segment.state.conditions.weights.total_mass [kilogram] segment.state.conditions.freestream.altitude [meter] Outputs: segment.state.residuals.altitude [meters] Properties Used: N/A """ # Unpack results alt_in = segment.state.unknowns.altitude[:,0] alt_out = segment.state.conditions.freestream.altitude[:,0] segment.state.residuals.altitude[:,0] = (alt_in - alt_out)/alt_out[-1] return
# ---------------------------------------------------------------------------------------------------------------------- # Update Differentials # ----------------------------------------------------------------------------------------------------------------------
[docs] def update_differentials(segment): """ On each iteration creates the differentials and integration functions from knowns about the problem. Sets the time at each point. Must return in dimensional time, with t[0] = 0. This is different from the common method as it also includes the scaling of operators. Assumptions: Works with a segment discretized in vertical position, altitude Inputs: state.numerics.dimensionless.control_points [Unitless] state.numerics.dimensionless.differentiate [Unitless] state.numerics.dimensionless.integrate [Unitless] state.conditions.frames.inertial.position_vector [meter] state.conditions.frames.inertial.velocity_vector [meter/second] Outputs: state.conditions.frames.inertial.time [second] """ # unpack numerics = segment.state.numerics conditions = segment.state.conditions x = numerics.dimensionless.control_points D = numerics.dimensionless.differentiate I = numerics.dimensionless.integrate r = segment.state.conditions.frames.inertial.position_vector v = segment.state.conditions.frames.inertial.velocity_vector alt0 = segment.altitude_start altf = segment.altitude_end # check for initial altitude if alt0 is None: if not segment.state.initials: raise AttributeError('initial altitude not set') alt0 = -1.0 * segment.state.initials.conditions.frames.inertial.position_vector[-1,2] dz = altf - alt0 vz = -v[:,2,None] # maintain column array # get overall time step dt = (dz/np.dot(I,vz))[-1] # rescale operators x = x * dt D = D / dt I = I * dt # Calculate the altitudes alt = np.dot(I,vz) + alt0 # pack t_initial = segment.state.conditions.frames.inertial.time[0,0] numerics.time.control_points = x numerics.time.differentiate = D numerics.time.integrate = I conditions.frames.inertial.time[1:,0] = t_initial + x[1:,0] conditions.frames.inertial.position_vector[:,2] = -alt[:,0] conditions.freestream.altitude[:,0] = alt[:,0] return