def initialize_conditions(self, conditions, numerics, initials=None):
        """ Segment.initialize_conditions(conditions)
            update the segment conditions
            pin down as many condition variables as possible in this function
            
            Assumptions:
                --
                
        """

        # sets initial time and mass
        conditions = Aerodynamic_Segment.initialize_conditions(
            self, conditions, numerics, initials)

        # unpack inputs
        alt = self.altitude
        xf = self.distance
        air_speed = self.air_speed
        atmo = self.atmosphere
        planet = self.planet
        t_nondim = numerics.dimensionless_time
        t_initial = conditions.frames.inertial.time[0, 0]

        # check for initial altitude
        if alt is None:
            if not initials: raise AttributeError('altitude not set')
            alt = -1.0 * initials.frames.inertial.position_vector[0, 2]
            self.altitude = alt

        # freestream details
        conditions.freestream.altitude[:, 0] = alt
        conditions = self.compute_atmosphere(conditions, atmo)
        conditions = self.compute_gravity(conditions, planet)

        conditions.frames.inertial.velocity_vector[:, 0] = air_speed
        conditions = self.compute_freestream(conditions)

        # dimensionalize time
        t_final = xf / air_speed + t_initial
        time = t_nondim * (t_final - t_initial) + t_initial
        conditions.frames.inertial.time[:, 0] = time[:, 0]

        # positions (TODO: mamange user initials)
        conditions.frames.inertial.position_vector[:,
                                                   2] = -alt  # z points down

        # update differentials
        numerics = Aerodynamic_Segment.update_differentials(
            self, conditions, numerics)

        # done
        return conditions
 def initialize_conditions(self,conditions,numerics,initials=None):
     """ Segment.initialize_conditions(conditions)
         update the segment conditions
         pin down as many condition variables as possible in this function
         
         Assumptions:
             --
             
     """
     
     # sets initial time and mass
     conditions = Aerodynamic_Segment.initialize_conditions(self,conditions,numerics,initials)
     
     # unpack inputs
     alt       = self.altitude
     xf        = self.distance
     air_speed = self.air_speed
     atmo      = self.atmosphere
     planet    = self.planet
     t_nondim  = numerics.dimensionless_time
     t_initial = conditions.frames.inertial.time[0,0]
     
     # check for initial altitude
     if alt is None:
         if not initials: raise AttributeError('altitude not set')
         alt = -1.0 * initials.frames.inertial.position_vector[0,2]
         self.altitude = alt
     
     # freestream details
     conditions.freestream.altitude[:,0] = alt
     conditions = self.compute_atmosphere(conditions,atmo)
     conditions = self.compute_gravity(conditions,planet)
     
     conditions.frames.inertial.velocity_vector[:,0] = air_speed
     conditions = self.compute_freestream(conditions)
     
     # dimensionalize time
     t_final = xf / air_speed + t_initial
     time =  t_nondim * (t_final-t_initial) + t_initial
     conditions.frames.inertial.time[:,0] = time[:,0]
     
     # positions (TODO: mamange user initials)
     conditions.frames.inertial.position_vector[:,2] = -alt # z points down
     
     # update differentials
     numerics = Aerodynamic_Segment.update_differentials(self,conditions,numerics)
     
     # done
     return conditions
    def update_conditions(self, conditions, numerics, unknowns):
        """ Segment.update_conditions(conditions,numerics,unknowns)
            if needed, updates the conditions given the current free unknowns and numerics
            called once per segment solver iteration
        """

        # unpack unknowns
        throttle = unknowns.controls.throttle
        theta = unknowns.controls.theta
        psi = unknowns.controls.psi

        # apply unknowns
        conditions.propulsion.throttle[:, 0] = throttle[:, 0]
        conditions.frames.body.inertial_rotations[:, 1] = theta[:, 0]
        #conditions.frames.body.inertial_rotations[:,2] = psi[:,0]

        # angle of attack
        # external aerodynamics
        # propulsion
        # weights
        # total forces
        conditions = Aerodynamic_Segment.update_conditions(
            self, conditions, numerics, unknowns)

        return conditions
Пример #4
0
    def update_conditions(self,conditions,numerics,unknowns):
        """ Compute orientation, and force conditions. Modified from
            originial Aerodynamic_Segment to include rolling friction
        """
        # unpack unknowns
        velocity_x   = unknowns.controls.velocity_x
        final_time   = unknowns.finals.time

        #apply unknowns
        conditions.frames.inertial.velocity_vector[1:,0] = velocity_x

        # unpack models
        aero_model = self.config.aerodynamics_model
        prop_model = self.config.propulsion_model

        # freestream conditions
        conditions = self.compute_freestream(conditions)

        # call Aerodynamic_Segment's update_conditions
        conditions = Aerodynamic_Segment.update_conditions(self,conditions,numerics,unknowns)

        # rolling friction
        conditions = self.compute_ground_forces(conditions)

        # total forces
        conditions = self.compute_forces(conditions)	

        return conditions
Пример #5
0
    def update_conditions(self, conditions, numerics, unknowns):
        """ Compute orientation, and force conditions. Modified from
            originial Aerodynamic_Segment to include rolling friction
        """
        # unpack unknowns
        velocity_x = unknowns.controls.velocity_x
        final_time = unknowns.finals.time

        #apply unknowns
        conditions.frames.inertial.velocity_vector[1:, 0] = velocity_x

        # unpack models
        aero_model = self.config.aerodynamics_model
        prop_model = self.config.propulsion_model

        # freestream conditions
        conditions = self.compute_freestream(conditions)

        # call Aerodynamic_Segment's update_conditions
        conditions = Aerodynamic_Segment.update_conditions(
            self, conditions, numerics, unknowns)

        # rolling friction
        conditions = self.compute_ground_forces(conditions)

        # total forces
        conditions = self.compute_forces(conditions)

        return conditions
Пример #6
0
    def initialize_conditions(self, conditions, numerics, initials=None):
        """ Segment.initialize_conditions(conditions,numerics,initials=None)
            update the segment conditions
            pin down as many condition variables as possible in this function

            Inputs:
                conditions - the conditions data dictionary, with initialized
                zero arrays, with number of rows = 
                segment.conditions.n_control_points
                initials - a data dictionary with 1-row column arrays pulled from
                the last row of the previous segment's conditions data, or none
                if no previous segment

            Outputs:
                conditions - the conditions data dictionary, updated with the 
                             values that can be precalculated

            Assumptions:
                --

            Usage Notes:
                may need to inspect segment (self) for user inputs
                will be called before solving the segments free unknowns

        """

        conditions = Aerodynamic_Segment.initialize_conditions(
            self, conditions, numerics, initials)

        # unpack inputs
        v0 = self.velocity_start
        vf = self.velocity_end
        alt = self.altitude
        atmo = self.atmosphere
        planet = self.planet
        conditions.ground.incline[:, 0] = self.ground_incline
        conditions.ground.friction_coefficient[:,
                                               0] = self.friction_coefficient
        N = len(conditions.frames.inertial.velocity_vector[:, 0])

        # avoid having zero velocity since aero and propulsion models need non-zero Reynolds number
        if v0 == 0.0: v0 = 0.01
        if vf == 0.0: vf = 0.01

        # repack
        self.velocity_start = v0
        self.velocity_end = vf

        # pack conditions
        conditions.frames.inertial.velocity_vector[:,
                                                   0] = np.linspace(v0, vf, N)
        conditions.freestream.altitude[:, 0] = alt

        # freestream atmosphereric conditions
        conditions = self.compute_atmosphere(conditions, atmo)
        conditions = self.compute_gravity(conditions, planet)

        # done
        return conditions
Пример #7
0
    def initialize_conditions(self, conditions, numerics, initials=None):
        """ Segment.initialize_conditions(conditions,numerics,initials=None)
            update the segment conditions
            pin down as many condition variables as possible in this function
            
            Inputs:
                conditions - the conditions data dictionary, with initialized zero arrays, 
                             with number of rows = segment.conditions.n_control_points
                initials - a data dictionary with 1-row column arrays pulled from the last row
                           of the previous segment's conditions data, or none if no previous segment
                
            Outputs:
                conditions - the conditions data dictionary, updated with the 
                             values that can be precalculated
            
            Assumptions:
                --
                
            Usage Notes:
                may need to inspect segment (self) for user inputs
                will be called before solving the segments free unknowns
                
        """

        # gets initial mass and time from previous segment
        conditions = Aerodynamic_Segment.initialize_conditions(
            self, conditions, numerics, initials)

        # unpack inputs
        alt0 = self.altitude_start
        altf = self.altitude_end
        atmo = self.atmosphere
        planet = self.planet
        t_nondim = numerics.dimensionless_time

        # check for initial altitude
        if alt0 is None:
            if not initials: raise AttributeError('initial altitude not set')
            alt0 = -1.0 * initials.frames.inertial.position_vector[0, 2]
            self.altitude_start = alt0

        # discretize on altitude
        alt = t_nondim * (altf - alt0) + alt0

        # pack conditions
        conditions.frames.inertial.position_vector[:,
                                                   2] = -alt[:,
                                                             0]  # z points down
        conditions.freestream.altitude[:,
                                       0] = alt[:,
                                                0]  # positive altitude in this context

        # freestream atmosphereric conditions
        conditions = self.compute_atmosphere(conditions, atmo)
        conditions = self.compute_gravity(conditions, planet)

        # done
        return conditions
Пример #8
0
    def initialize_conditions(self,conditions,numerics,initials=None):
        """ Segment.initialize_conditions(conditions,numerics,initials=None)
            update the segment conditions
            pin down as many condition variables as possible in this function

            Inputs:
                conditions - the conditions data dictionary, with initialized
                zero arrays, with number of rows = 
                segment.conditions.n_control_points
                initials - a data dictionary with 1-row column arrays pulled from
                the last row of the previous segment's conditions data, or none
                if no previous segment

            Outputs:
                conditions - the conditions data dictionary, updated with the 
                             values that can be precalculated

            Assumptions:
                --

            Usage Notes:
                may need to inspect segment (self) for user inputs
                will be called before solving the segments free unknowns

        """

        conditions = Aerodynamic_Segment.initialize_conditions(self,conditions,numerics,initials)

        # unpack inputs
        v0       = self.velocity_start
        vf       = self.velocity_end
        alt      = self.altitude
        atmo     = self.atmosphere
        planet   = self.planet
        conditions.ground.incline[:,0]              = self.ground_incline
        conditions.ground.friction_coefficient[:,0] = self.friction_coefficient
        N        = len(conditions.frames.inertial.velocity_vector[:,0])

        # avoid having zero velocity since aero and propulsion models need non-zero Reynolds number
        if v0 == 0.0: v0 = 0.01
        if vf == 0.0: vf = 0.01

        # repack
        self.velocity_start = v0
        self.velocity_end   = vf

        # pack conditions
        conditions.frames.inertial.velocity_vector[:,0] = np.linspace(v0,vf,N)
        conditions.freestream.altitude[:,0]             = alt

        # freestream atmosphereric conditions
        conditions = self.compute_atmosphere(conditions,atmo)
        conditions = self.compute_gravity(conditions,planet)

        # done
        return conditions
Пример #9
0
 def initialize_conditions(self,conditions,numerics,initials=None):
     """ Segment.initialize_conditions(conditions,numerics,initials=None)
         update the segment conditions
         pin down as many condition variables as possible in this function
         
         Inputs:
             conditions - the conditions data dictionary, with initialized zero arrays, 
                          with number of rows = segment.conditions.n_control_points
             initials - a data dictionary with 1-row column arrays pulled from the last row
                        of the previous segment's conditions data, or none if no previous segment
             
         Outputs:
             conditions - the conditions data dictionary, updated with the 
                          values that can be precalculated
         
         Assumptions:
             --
             
         Usage Notes:
             may need to inspect segment (self) for user inputs
             will be called before solving the segments free unknowns
             
     """
     
     # gets initial mass and time from previous segment
     conditions = Aerodynamic_Segment.initialize_conditions(self,conditions,numerics,initials)
     
     # unpack inputs
     alt0     = self.altitude_start 
     altf     = self.altitude_end
     atmo     = self.atmosphere
     planet   = self.planet
     t_nondim = numerics.dimensionless_time
     
     # check for initial altitude
     if alt0 is None:
         if not initials: raise AttributeError('initial altitude not set')
         alt0 = -1.0 * initials.frames.inertial.position_vector[0,2]
         self.altitude_start = alt0
     
     # discretize on altitude
     alt = t_nondim * (altf-alt0) + alt0
     
     # pack conditions
     conditions.frames.inertial.position_vector[:,2] = -alt[:,0] # z points down
     conditions.freestream.altitude[:,0]             =  alt[:,0] # positive altitude in this context
     
     # freestream atmosphereric conditions
     conditions = self.compute_atmosphere(conditions,atmo)
     conditions = self.compute_gravity(conditions,planet)
     
     # done
     return conditions
Пример #10
0
 def post_process(self,conditions,numerics,unknowns):
     
     x0 = conditions.frames.inertial.position_vector[0,0]
     vx = conditions.frames.inertial.velocity_vector[:,0]
     I  = numerics.integrate_time
     
     x = np.dot(I,vx) + x0
     
     conditions.frames.inertial.position_vector[:,0] = x
     
     conditions = Aerodynamic_Segment.post_process(self,conditions,numerics,unknowns)
     
     return conditions
     
Пример #11
0
    def initialize_arrays(self,conditions,numerics,unknowns,residuals):
        """ Modified initialize_arrays method to remove the initial condition from
            unknowns.controls.velocity_x (and the corresponding acceleration residual)
        """

        # run the superclass array initialization
        unknowns, conditions, residuals = \
            Aerodynamic_Segment.initialize_arrays(self, conditions, numerics, unknowns, residuals)

        # modify unknowns and residuals to prevent solver from changing v0
        unknowns.controls.velocity_x      = unknowns.controls.velocity_x[1:,0]
        residuals.controls.acceleration_x = residuals.controls.acceleration_x[1:,0]

        return unknowns, conditions, residuals
Пример #12
0
    def post_process(self, conditions, numerics, unknowns):

        x0 = conditions.frames.inertial.position_vector[0, 0]
        vx = conditions.frames.inertial.velocity_vector[:, 0]
        I = numerics.integrate_time

        x = np.dot(I, vx) + x0

        conditions.frames.inertial.position_vector[:, 0] = x

        conditions = Aerodynamic_Segment.post_process(self, conditions,
                                                      numerics, unknowns)

        return conditions
Пример #13
0
    def initialize_arrays(self, conditions, numerics, unknowns, residuals):
        """ Modified initialize_arrays method to remove the initial condition from
            unknowns.controls.velocity_x (and the corresponding acceleration residual)
        """

        # run the superclass array initialization
        unknowns, conditions, residuals = \
            Aerodynamic_Segment.initialize_arrays(self, conditions, numerics, unknowns, residuals)

        # modify unknowns and residuals to prevent solver from changing v0
        unknowns.controls.velocity_x = unknowns.controls.velocity_x[1:, 0]
        residuals.controls.acceleration_x = residuals.controls.acceleration_x[
            1:, 0]

        return unknowns, conditions, residuals
Пример #14
0
    def compute_forces(self, conditions):

        conditions = Aerodynamic_Segment.compute_forces(self, conditions)

        # unpack forces
        total_aero_forces = conditions.frames.inertial.total_force_vector
        inertial_ground_force_vector = conditions.frames.inertial.ground_force_vector

        # sum of the forces, including friction force
        F = total_aero_forces + inertial_ground_force_vector
        # like a boss

        # pack
        conditions.frames.inertial.total_force_vector[:, :] = F[:, :]

        return conditions
Пример #15
0
    def compute_forces(self,conditions):

        conditions = Aerodynamic_Segment.compute_forces(self,conditions)

        # unpack forces
        total_aero_forces = conditions.frames.inertial.total_force_vector
        inertial_ground_force_vector = conditions.frames.inertial.ground_force_vector

        # sum of the forces, including friction force
        F = total_aero_forces + inertial_ground_force_vector
        # like a boss

        # pack
        conditions.frames.inertial.total_force_vector[:,:] = F[:,:]

        return conditions
Пример #16
0
 def post_process(self,conditions,numerics,unknowns):
     """ Segment.post_process(conditions,numerics,unknowns)
         post processes the conditions after converging the segment solver
         
         Usage Notes - 
             use this to store the unknowns and any other interesting in conditions
                 for later plotting
             for clarity and style, be sure to define any new fields in segment.__defaults__
         
     """
     
     x0 = conditions.frames.inertial.position_vector[0,0]
     vx = conditions.frames.inertial.velocity_vector[:,0]
     I  = numerics.integrate_time
     
     x = np.dot(I,vx) + x0
     
     conditions.frames.inertial.position_vector[:,0] = x
     
     conditions = Aerodynamic_Segment.post_process(self,conditions,numerics,unknowns)
     
     return conditions
 def update_conditions(self,conditions,numerics,unknowns):
     """ Segment.update_conditions(conditions,numerics,unknowns)
         if needed, updates the conditions given the current free unknowns and numerics
         called once per segment solver iteration
     """
     
     # unpack unknowns
     throttle = unknowns.controls.throttle
     theta    = unknowns.controls.theta
     
     # apply unknowns
     conditions.propulsion.throttle[:,0]            = throttle[:,0]
     conditions.frames.body.inertial_rotations[:,1] = theta[:,0]
     
     # angle of attack
     # external aerodynamics
     # propulsion
     # weights
     # total forces
     conditions = Aerodynamic_Segment.update_conditions(self,conditions,numerics,unknowns)
     
     return conditions
 def post_process(self,conditions,numerics,unknowns):
     """ Segment.post_process(conditions,numerics,unknowns)
         post processes the conditions after converging the segment solver
         
         Usage Notes - 
             use this to store the unknowns and any other interesting in conditions
                 for later plotting
             for clarity and style, be sure to define any new fields in segment.__defaults__
         
     """
     
     x0 = conditions.frames.inertial.position_vector[0,0]
     vx = conditions.frames.inertial.velocity_vector[:,0]
     I  = numerics.integrate_time
     
     x = np.dot(I,vx) + x0
     
     conditions.frames.inertial.position_vector[:,0] = x
     
     conditions = Aerodynamic_Segment.post_process(self,conditions,numerics,unknowns)
     
     return conditions
    def initialize_conditions(self,conditions,numerics,initials=None):
        """ Segment.initialize_conditions(conditions)
            update the segment conditions
            pin down as many condition variables as possible in this function
            
            Assumptions:
                --
                
        """
        
        # sets initial time and mass
        conditions = Aerodynamic_Segment.initialize_conditions(self,conditions,numerics,initials)
        
        # unpack inputs
        alt       = self.altitude
        seg_time  = self.time
        air_speed = self.air_speed
        atmo      = self.atmosphere
        planet    = self.planet
        radius    = self.radius
        t_nondim  = numerics.dimensionless_time
        t_initial = conditions.frames.inertial.time[0,0]
        
        # check for initial altitude
        if alt is None:
            if not initials: raise AttributeError('altitude not set')
            alt = -1.0 * initials.frames.inertial.position_vector[0,2]
            self.altitude = alt
        
        # calculate bank angle
        conditions = self.compute_gravity(conditions,planet)  
        ar    = (air_speed**2)/radius # Centripetal acceleration
        g     = conditions.freestream.gravity[:,0] 
        omega = air_speed/radius
        phi   = np.arctan(ar/g)
        
        conditions.frames.body.inertial_rotations[:,0] = phi
        
        # dimensionalize time
        time =  t_nondim * (seg_time) + t_initial
        conditions.frames.inertial.time[:,0] = time[:,0]
        
        angle = np.remainder(time*omega,2*np.pi)
        
        # the acceleration in the inertial frame
        conditions.frames.inertial.acceleration_vector[:,0] = np.sin(angle[:,0])*ar
        conditions.frames.inertial.acceleration_vector[:,1] = np.cos(angle[:,0])*ar
        conditions.frames.inertial.acceleration_vector[:,2] = 0.0*ar
        
        # the velocity in the inertial frame
        conditions.frames.inertial.velocity_vector[:,0] = air_speed*np.cos(angle[:,0])        
        conditions.frames.inertial.velocity_vector[:,1] = air_speed*np.sin(angle[:,0])
        conditions.frames.inertial.velocity_vector[:,2] = air_speed*0.0

        # freestream details
        conditions.freestream.altitude[:,0] = alt
        conditions = self.compute_atmosphere(conditions,atmo)      
        conditions = self.compute_freestream(conditions)
        
        # this is psi
        conditions.frames.body.inertial_rotations[:,2] = angle[:,0]
        
        # positions (TODO: mamange user initials)
        conditions.frames.inertial.position_vector[:,2] = -alt # z points down
        
        # update differentials
        numerics = Aerodynamic_Segment.update_differentials(self,conditions,numerics)
        
        # done
        return conditions
    def initialize_conditions(self, conditions, numerics, initials=None):
        """ Segment.initialize_conditions(conditions)
            update the segment conditions
            pin down as many condition variables as possible in this function
            
            Assumptions:
                --
                
        """

        # sets initial time and mass
        conditions = Aerodynamic_Segment.initialize_conditions(
            self, conditions, numerics, initials)

        # unpack inputs
        alt = self.altitude
        seg_time = self.time
        air_speed = self.air_speed
        atmo = self.atmosphere
        planet = self.planet
        radius = self.radius
        t_nondim = numerics.dimensionless_time
        t_initial = conditions.frames.inertial.time[0, 0]

        # check for initial altitude
        if alt is None:
            if not initials: raise AttributeError('altitude not set')
            alt = -1.0 * initials.frames.inertial.position_vector[0, 2]
            self.altitude = alt

        # calculate bank angle
        conditions = self.compute_gravity(conditions, planet)
        ar = (air_speed**2) / radius  # Centripetal acceleration
        g = conditions.freestream.gravity[:, 0]
        omega = air_speed / radius
        phi = np.arctan(ar / g)

        conditions.frames.body.inertial_rotations[:, 0] = phi

        # dimensionalize time
        time = t_nondim * (seg_time) + t_initial
        conditions.frames.inertial.time[:, 0] = time[:, 0]

        angle = np.remainder(time * omega, 2 * np.pi)

        # the acceleration in the inertial frame
        conditions.frames.inertial.acceleration_vector[:, 0] = np.sin(
            angle[:, 0]) * ar
        conditions.frames.inertial.acceleration_vector[:, 1] = np.cos(
            angle[:, 0]) * ar
        conditions.frames.inertial.acceleration_vector[:, 2] = 0.0 * ar

        # the velocity in the inertial frame
        conditions.frames.inertial.velocity_vector[:, 0] = air_speed * np.cos(
            angle[:, 0])
        conditions.frames.inertial.velocity_vector[:, 1] = air_speed * np.sin(
            angle[:, 0])
        conditions.frames.inertial.velocity_vector[:, 2] = air_speed * 0.0

        # freestream details
        conditions.freestream.altitude[:, 0] = alt
        conditions = self.compute_atmosphere(conditions, atmo)
        conditions = self.compute_freestream(conditions)

        # this is psi
        conditions.frames.body.inertial_rotations[:, 2] = angle[:, 0]

        # positions (TODO: mamange user initials)
        conditions.frames.inertial.position_vector[:,
                                                   2] = -alt  # z points down

        # update differentials
        numerics = Aerodynamic_Segment.update_differentials(
            self, conditions, numerics)

        # done
        return conditions