<commit_before># -*- coding: utf-8 -*-
"""
- dynamics of a flap with two actuators in different positions
- can take in to account initial strain
- calculates necessary spring stiffness for a given linear actuator length
  and for defined positions for the actuators ends.

Will have:
- coupling with Edwin matlab code
- coupling with Aeropy
Created on Wed Feb 17 13:10:30 2016

@author: <NAME>
"""
import math
from scipy.optimize import newton

class actuator():
    """
    Actuator object where inputs:
    - -(n): is a dictionary with keys 'x' and 'y', the coordinates of 
      the forwards end in the global coordinate system (origin at the
      leading edge)
    - +(p): is a dictionary with keys 'x' and 'y', the coordinates of 
      the afterwards end in the global coordinate system (origin at the
      leading edge)
    - J: is a dictionary with keys 'x' and 'y', the coordinates of 
      the joint in the global coordinate system (origin at the
      leading edge)        
    - material: linear or SMA
    """
    #
    def __init__(self, positions, J, area = None, zero_stress_length = None,
                 eps_0 = None, k = None, material = 'linear'):
        """
        Initiate class and it's basic atributes:
        - x_n and y_n: are the x & y coordinates of the forwards end in the
          local coordinate system (origin at the joint). n stands for
          negative
        - x_p and y_p: are the x & y coordinates of the afterwards end in the
          local coordinate system (origin at the joint). p stand for 
          positive
        - eps_0: inital strain (epsilon), if not defined, it is zero
        - k: linear spring elastic coefficient
        """
        #Storing inputs in local coordinate system
        self.x_n= positions['x-'] - J['x']
        self.y_n = positions['y-'] - J['y']
        self.x_p = positions['x+'] - J['x']
        self.y_p = positions['y+'] - J['y']
        self.x_J = J['x']
        self.y_J = J['y']
        self.material = material
        
        # Projections of original wire length r
        self.r_1_0 = self.x_p - self.x_n
        self.r_2_0 = self.y_p - self.y_n
        self.length_r_0 = math.sqrt(self.r_1_0**2 + self.r_2_0**2)    
        
        # Initializing current wire length r
        self.r_1 = self.r_1_0
        self.r_2 = self.r_2_0
        self.length_r = self.length_r_0
        
        #define initial values for r, theta and force
        self.theta = 0
        self.F = 0.
        #Cross section area
        self.area = area
        self.sigma = None
        
        #In case zero_stress_length is not defined and initial strain is
        #known, calculate the zero stress length. If defined, calculate
        #the initial strain
        
        if zero_stress_length == None and eps_0 != None:
            self.eps_0 = eps_0
            self.eps = self.eps_0
            self.zero_stress_length = self.length_r_0/(1 + self.eps)
        elif zero_stress_length != None and eps_0 == None:
            self.zero_stress_length = zero_stress_length
            self.eps_0 = self.length_r/self.zero_stress_length - 1.
            self.eps = self.eps_0            
        
        if material == 'linear':
            self.k = k
    def calculate_theta(self, theta_0 = 0.):
        """
        Calculate angle for given deformation epsilon.
        """
        def diff_eq(theta):
            sin = math.sin(theta)
            cos = math.cos(theta)
            
            diff = (2.*self.x_p*cos - 2.*self.y_p*sin)*(self.x_p*sin + \
                    self.y_p*cos - self.y_n) - (2.*self.x_p*sin + \
                    2.*self.y_p*cos)*(self.x_p*cos - self.x_n - self.y_p*sin) 
            
            return diff
        
        def eq(theta):
            eta = (self.eps - self.eps_0) + 1.
            sin = math.sin(theta)
            cos = math.cos(theta)
            
            r_1 = self.x_p*cos - self.y_p*sin - self.x_n
            r_2 = self.y_p*cos + self.x_p*sin - self.y_n

            return r_1**2 + r_2**2 - (eta*self.length_r_0)**2

        self.theta = newton(eq, theta_0, diff_eq, maxiter = 200)
        return self.theta
        
    def update(self):
        """If vector length r or theta is changed, new coordinates are 
        calculated"""
        self.r_1 = self.x_p*math.cos(self.theta) - \
                   self.y_p*math.sin(self.theta) - self.x_n
        self.r_2 = self.y_p*math.cos(self.theta) + \
                   self.x_p*math.sin(self.theta) - self.y_n
        self.length_r = math.sqrt(self.r_1**2 + self.r_2**2)
        self.eps = self.length_r/self.zero_stress_length - 1. 
     
    def calculate_force(self, source = 'strain'):
        
        if source == 'strain':
            if self.material == 'linear':
                self.F = self.k*self.eps*self.length_r
            elif self.material == 'SMA':
                print "Put Edwin code here"
        #Calculate force from stress and cross section
        elif source == 'sigma':
            self.F = self.area * self.sigma
                
    def calculate_torque(self):
        """Calculate torque given the actuator force: r \times F (where a is 
        global coordinates)"""

        #calculate components of force vector        
        F_1 = - self.F*self.r_1/self.length_r
        F_2 = - self.F*self.r_2/self.length_r
#        print x_n, y_n
        
        #calculate torque
        self.torque = (self.x_p*math.cos(self.theta) - \
                       self.y_p*math.sin(self.theta))*F_2 - \
                      (self.y_p*math.cos(self.theta) + \
                       self.x_p*math.sin(self.theta))*F_1    
        return self.torque
    def plot_actuator(self):
        if self.material == 'linear':
            colour = 'b'
        elif self.material == 'SMA':
            colour = 'r'
        plt.figure(1)
        plt.axes().set_aspect('equal')
        plt.scatter([self.x_n + self.x_J, self.x_p + self.x_J], 
                    [self.y_n + self.y_J, self.y_p + self.y_J], 
                    c=colour)
        plt.scatter([self.x_J],[self.y_J], c = 'g')
        plt.plot([self.x_n + self.x_J, self.x_p + self.x_J], 
                 [self.y_n + self.y_J, self.y_p + self.y_J],
                 colour)
#    def calculate_initial(self, tension = "sigmaf"):
#        """Calculate initial displacement for SMA and linear"""
#        if self.material == "linear":
#            if tension == "sigmaf":
#                self.eps = self.area * self.sigmaf *(self.)
if __name__ == '__main__':
    import matplotlib.pyplot as plt
    
    chord = 0.6175

#==============================================================================
# Design variables
#==============================================================================
    #Hole positioning
    J = {'x':0.25, 'y':0.}
    sma = {'x-': J['x'], 'y-': -0.02, 'x+': 0.1225 + J['x'], 'y+': 0.0135 }
    linear = {'x-': J['x'], 'y-': 0.032, 'x+': 0.146 + J['x'], 'y+': -0.0135}

    #SMA Pre-stress
    sigma_o = 300e6
#==============================================================================
# Design constants
#==============================================================================
    #Areas
    area_l = 0.001
    area_s = math.pi*0.00025**2
    
    #original bias spring length<commit_msg>modified update function to the winglet problem<commit_after># -*- coding: utf-8 -*-
"""
- dynamics of a flap with two actuators in different positions
- can take in to account initial strain
- calculates necessary spring stiffness for a given linear actuator length
  and for defined positions for the actuators ends.

Will have:
- coupling with Edwin matlab code
- coupling with Aeropy
Created on Wed Feb 17 13:10:30 2016

@author: <NAME>
"""
import math
from scipy.optimize import newton

class actuator():
    """
    Actuator object where inputs:
    - -(n): is a dictionary with keys 'x' and 'y', the coordinates of 
      the forwards end in the global coordinate system (origin at the
      leading edge)
    - +(p): is a dictionary with keys 'x' and 'y', the coordinates of 
      the afterwards end in the global coordinate system (origin at the
      leading edge)
    - J: is a dictionary with keys 'x' and 'y', the coordinates of 
      the joint in the global coordinate system (origin at the
      leading edge)        
    - material: linear or SMA
    """
    #
    def __init__(self, positions, J, area = None, zero_stress_length = None,
                 eps_0 = None, k = None, material = 'linear'):
        """
        Initiate class and it's basic atributes:
        - x_n and y_n: are the x & y coordinates of the forwards end in the
          local coordinate system (origin at the joint). n stands for
          negative
        - x_p and y_p: are the x & y coordinates of the afterwards end in the
          local coordinate system (origin at the joint). p stand for 
          positive
        - eps_0: inital strain (epsilon), if not defined, it is zero
        - k: linear spring elastic coefficient
        """
        #Storing inputs in local coordinate system
        self.x_n= positions['x-'] - J['x']
        self.y_n = positions['y-'] - J['y']
        self.x_p = positions['x+'] - J['x']
        self.y_p = positions['y+'] - J['y']
        self.x_J = J['x']
        self.y_J = J['y']
        self.Radius_J = J['Radius']
        self.material = material
        
        # Projections of original wire length r
        self.r_1_0 = self.x_p - self.x_n
        self.r_2_0 = self.y_p - self.y_n
        self.length_r_0 = math.sqrt(self.r_1_0**2 + self.r_2_0**2)    
        
        # Initializing current wire length r
        self.r_1 = self.r_1_0
        self.r_2 = self.r_2_0
        self.length_r = self.length_r_0
        
        #define initial values for r, theta and force
        self.theta = 0
        self.F = 0.
        #Cross section area
        self.area = area
        self.sigma = None
        
        #In case zero_stress_length is not defined and initial strain is
        #known, calculate the zero stress length. If defined, calculate
        #the initial strain
        
        if zero_stress_length == None and eps_0 != None:
            self.eps_0 = eps_0
            self.eps = self.eps_0
            self.zero_stress_length = self.length_r_0/(1 + self.eps)
        elif zero_stress_length != None and eps_0 == None:
            self.zero_stress_length = zero_stress_length
            self.eps_0 = self.length_r/self.zero_stress_length - 1.
            self.eps = self.eps_0            
        
        if material == 'linear':
            self.k = k
    def calculate_theta(self, theta_0 = 0.):
        """
        Calculate angle for given deformation epsilon.
        """
        def diff_eq(theta):
            sin = math.sin(theta)
            cos = math.cos(theta)
            
            diff = (2.*self.x_p*cos - 2.*self.y_p*sin)*(self.x_p*sin + \
                    self.y_p*cos - self.y_n) - (2.*self.x_p*sin + \
                    2.*self.y_p*cos)*(self.x_p*cos - self.x_n - self.y_p*sin) 
            
            return diff
        
        def eq(theta):
            eta = (self.eps - self.eps_0) + 1.
            sin = math.sin(theta)
            cos = math.cos(theta)
            
            r_1 = self.x_p*cos - self.y_p*sin - self.x_n
            r_2 = self.y_p*cos + self.x_p*sin - self.y_n

            return r_1**2 + r_2**2 - (eta*self.length_r_0)**2

        self.theta = newton(eq, theta_0, diff_eq, maxiter = 200)
        return self.theta
        
    def update(self,theta): 
        """If vector length r or theta is changed, new coordinates are 
        calculated"""
        self.eps = math.radians(theta)*self.Radius_J
        self.r_1 = self.x_n - self.x_p + self.eps
        self.r_2 = self.x_n - self.x_p - self.eps         
     
    def calculate_force(self, source = 'strain'):
        
        if source == 'strain':
            if self.material == 'linear':
                self.F = self.k*self.eps*self.length_r
            elif self.material == 'SMA':
                print "Put Edwin code here"
        #Calculate force from stress and cross section
        elif source == 'sigma':
            self.F = self.area * self.sigma
                
    def calculate_torque(self):
        """Calculate torque given the actuator force: r \times F (where a is 
        global coordinates)"""

        #calculate components of force vector        
        F_1 = - self.F*self.r_1/self.length_r
        F_2 = - self.F*self.r_2/self.length_r
#        print x_n, y_n
        
        #calculate torque
        self.torque = (self.x_p*math.cos(self.theta) - \
                       self.y_p*math.sin(self.theta))*F_2 - \
                      (self.y_p*math.cos(self.theta) + \
                       self.x_p*math.sin(self.theta))*F_1    
        return self.torque
    def plot_actuator(self):
        if self.material == 'linear':
            colour = 'b'
        elif self.material == 'SMA':
            colour = 'r'
        plt.figure(1)
        plt.axes().set_aspect('equal')
        plt.scatter([self.x_n + self.x_J, self.x_p + self.x_J], 
                    [self.y_n + self.y_J, self.y_p + self.y_J], 
                    c=colour)
        plt.scatter([self.x_J],[self.y_J], c = 'g')
        plt.plot([self.x_n + self.x_J, self.x_p + self.x_J], 
                 [self.y_n + self.y_J, self.y_p + self.y_J],
                 colour)
#    def calculate_initial(self, tension = "sigmaf"):
#        """Calculate initial displacement for SMA and linear"""
#        if self.material == "linear":
#            if tension == "sigmaf":
#                self.eps = self.area * self.sigmaf *(self.)
if __name__ == '__main__':
    import matplotlib.pyplot as plt
    
    chord = 0.6175

#==============================================================================
# Design variables
#==============================================================================
    #Hole positioning
    J = {'x':0.25, 'y':0, 'Radius':0.01}
    sma = {'x-': J['x'], 'y-': -0.02, 'x+': 0.1225 + J['x'], 'y+': 0.0135 }
    linear = {'x-': J['x'], 'y-': 0.032, 'x+': 0.146 + J['x'], 'y+': -0.0135}
    R = 0.1

    #SMA Pre-stress
    sigma_o = 300e6
#==============================================================================
# Design constants
#==============================================================================
    #Areas
    area_l = 0.001
    area_s = math.pi*0.00025**2
    
    #original bias spring length
{'fraction_non_alphanumeric': 0.15532574974146846, 'fraction_numerical': 0.017786970010341262, 'mean_word_length': 1.8787457828934313, 'pattern_counts': {'":': 4, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4485978', 'n_tokens_mistral': 4743, 'n_tokens_neox': 4460, 'n_words': 1238}