Skip to content
Extraits de code Groupes Projets
mechanics.py 11,3 ko
Newer Older
  • Learn to ignore specific revisions
  • Nicolas Roisin's avatar
    Nicolas Roisin a validé
    # -*- coding: utf-8 -*-
    """
    Created on Thu Apr  3 10:42:13 2025
    
    @author: nroisin
    """
    import numpy as np
        
    def stress_from_strain(strain_tensor,c11= 165.77,c12= 63.93,c44 = 79.62):
        strain_voigt=np.zeros((1,6))
        strain_shape=np.shape(strain_tensor)
        
        if len(strain_shape)==2:
            if strain_shape[0]==3 and strain_shape[1]==3:
                strain_voigt[0]=strain_tensor[0,0]
                strain_voigt[1]=strain_tensor[1,1]
                strain_voigt[2]=strain_tensor[2,2]
                strain_voigt[3]=strain_tensor[1,2]
                strain_voigt[4]=strain_tensor[0,2]
                strain_voigt[5]=strain_tensor[0,1]
            if strain_shape[0]==1 and strain_shape[1]==6:
                strain_voigt=strain_tensor
        else:
            strain_voigt=np.array([strain_tensor])
        
        compliance_tensor=np.array([[c11,c12,c12,0,0,0],
                                    [c12,c11,c12,0,0,0],
                                    [c12,c12,c11,0,0,0],
                                    [0,0,0,c44,0,0],
                                    [0,0,0,0,c44,0],
                                    [0,0,0,0,0,c44]])
        return compliance_tensor @ strain_tensor
    
    def strain_from_stress(stress_tensor,c11= 165.77,c12= 63.93,c44 = 79.62):
        stress_voigt=np.zeros((1,6))
        stress_shape=np.shape(stress_tensor)
        
        if len(stress_shape)==2:
            if stress_shape[0]==3 and stress_shape[1]==3:
                stress_voigt[0]=stress_tensor[0,0]
                stress_voigt[1]=stress_tensor[1,1]
                stress_voigt[2]=stress_tensor[2,2]
                stress_voigt[3]=stress_tensor[1,2]
                stress_voigt[4]=stress_tensor[0,2]
                stress_voigt[5]=stress_tensor[0,1]
            if stress_shape[0]==1 and stress_shape[1]==6:
                stress_voigt=stress_tensor
        else:
            stress_voigt=np.array([stress_tensor])
        
        compliance_tensor=np.array([[c11,c12,c12,0,0,0],
                                    [c12,c11,c12,0,0,0],
                                    [c12,c12,c11,0,0,0],
                                    [0,0,0,c44,0,0],
                                    [0,0,0,0,c44,0],
                                    [0,0,0,0,0,c44]])
        return np.linalg.inv(compliance_tensor) @ stress_tensor
        
    def straintensor(direction,cristal_plane,N=11,emin=-0.05,emax=0.05,C11=165.77,C12=63.93,C44=79.62, poisson=True)   : 
        # Constants
        retour=np.zeros((3,3,N))
        
        eps=np.linspace(emin,emax,N)
        
        # Initiation
        uniepsilon001=np.zeros((3,3,N))
        uniepsilon110=np.zeros((3,3,N))
        uniepsilon111=np.zeros((3,3,N))
        biepsilon001=np.zeros((3,3,N))
        biepsilon110=np.zeros((3,3,N))
        biepsilon111=np.zeros((3,3,N))
        shear001=np.zeros((3,3,N))
        shear110=np.zeros((3,3,N))
        shear111=np.zeros((3,3,N))
        hydro=np.zeros((3,3,N))    
        # Matrix computation
        # Uniaxial
        if poisson:
          uniepar001=-C12/(C11+C12)*eps
        else:
          uniepar001=0
        
        uniepsilon001[0][0]=uniepar001
        uniepsilon001[0][1]=np.zeros(N)
        uniepsilon001[0][2]=np.zeros(N)
        uniepsilon001[1][0]=np.zeros(N)
        uniepsilon001[1][1]=uniepar001
        uniepsilon001[1][2]=np.zeros(N)
        uniepsilon001[2][0]=np.zeros(N)
        uniepsilon001[2][1]=np.zeros(N)
        uniepsilon001[2][2]=eps
    
        if poisson:    
          uniepar110=- ( 4*C12*C44 ) / ( 2*C11*C44+(C11+2*C12)*(C11-C12) )*eps 
        else:
          uniepar110=0
        
        uniepsilon110[0][0]=0.5*(eps+uniepar110)
        uniepsilon110[0][1]=0.5*(eps-uniepar110)
        uniepsilon110[0][2]=np.zeros(N)
        uniepsilon110[1][0]=0.5*(eps-uniepar110)
        uniepsilon110[1][1]=0.5*(eps+uniepar110)
        uniepsilon110[1][2]=np.zeros(N)
        uniepsilon110[2][0]=np.zeros(N)
        uniepsilon110[2][1]=np.zeros(N)
        uniepsilon110[2][2]=uniepar110
    
        if poisson:     
          uniepar111 = - (C11 + 2*C12 - 2*C44) / (C11 + 2*C12 + 2*C44)*eps
        else:
          uniepar111 = 0
          
        uniepsilon111[0][0] = (eps + 2*uniepar111) / 3
        uniepsilon111[0][1] = (eps - uniepar111) / 3
        uniepsilon111[0][2] = (eps - uniepar111) / 3
        uniepsilon111[1][0] = (eps - uniepar111) / 3
        uniepsilon111[1][1] = (eps + 2*uniepar111) / 3
        uniepsilon111[1][2] = (eps - uniepar111) / 3
        uniepsilon111[2][0] = (eps - uniepar111) / 3
        uniepsilon111[2][1] = (eps - uniepar111) / 3
        uniepsilon111[2][2] = (eps + 2*uniepar111) / 3
        
        # Biaxial
        if poisson:
          bieper001 = -2 * C12 / C11 * eps        
        else:
          bieper001=0
              
        biepsilon001[0][0] = eps
        biepsilon001[0][1] = np.zeros(N)
        biepsilon001[0][2] = np.zeros(N)
        biepsilon001[1][0] = np.zeros(N)
        biepsilon001[1][1] = eps
        biepsilon001[1][2] = np.zeros(N)
        biepsilon001[2][0] = np.zeros(N)
        biepsilon001[2][1] = np.zeros(N)
        biepsilon001[2][2] = bieper001
    
        if poisson:     
          bieper110 = -(C11+3*C12-2*C44)/(C11+C12+2*C44)*eps
        else:
          bieper110 = 0
        
        biepsilon110[0][0] = 0.5*(bieper110+eps)
        biepsilon110[0][1] = 0.5*(bieper110-eps)
        biepsilon110[0][2] = np.zeros(N)
        biepsilon110[1][2] = np.zeros(N)
        biepsilon110[1][1] = 0.5*(bieper110+eps)
        biepsilon110[1][0] = 0.5*(bieper110-eps)
        biepsilon110[2][0] = np.zeros(N)
        biepsilon110[2][1] = np.zeros(N)
        biepsilon110[2][2] = eps
        
        if poisson:     
          bieper111 = -2*(C11+2*C12-2*C44)/(C11+2*C12+4*C44)* eps
        else:
          bieper111=0
        biepsilon111[0][0] = (bieper111+2*eps)/3 
        biepsilon111[0][1] = (bieper111-eps)/3 
        biepsilon111[0][2] = (bieper111-eps)/3 
        biepsilon111[1][0] = (bieper111-eps)/3 
        biepsilon111[1][1] = (bieper111+2*eps)/3 
        biepsilon111[1][2] = (bieper111-eps)/3 
        biepsilon111[2][0] = (bieper111-eps)/3 
        biepsilon111[2][1] = (bieper111-eps)/3 
        biepsilon111[2][2] = (bieper111+2*eps)/3
    
        # Shear
    
        shear001[0][2] = eps
        shear001[2][0] = eps
    
        shear110[0][2] = eps/np.sqrt(2)
        shear110[2][0] = eps/np.sqrt(2)
        shear110[1][2] = eps/np.sqrt(2)
        shear110[2][2] = eps/np.sqrt(2)
    
        shear111[0][1] = eps/np.sqrt(3)
        shear111[0][2] = eps/np.sqrt(3)
        shear111[1][0] = eps/np.sqrt(3)
        shear111[1][2] = eps/np.sqrt(3)
        shear111[2][0] = eps/np.sqrt(3)
        shear111[2][1] = eps/np.sqrt(3)
    
        # hydro
    
        hydro[0][0] = eps/3
        hydro[1][1] = eps/3
        hydro[2][2] = eps/3
        if direction == "uniaxial":
            if cristal_plane == "001":
                retour=uniepsilon001
            elif cristal_plane == "110":
                retour=uniepsilon110         
            elif cristal_plane == "111":
                retour=uniepsilon111      
        elif direction == "biaxial":
            if cristal_plane == "001":
                retour=biepsilon001
            elif cristal_plane == "110":
                retour=biepsilon110         
            elif cristal_plane == "111":
                retour=biepsilon111
        elif direction == "shear":
            if cristal_plane == "001":
                retour=shear001
            elif cristal_plane == "110":
                retour=shear110         
            elif cristal_plane == "111":
                retour=shear111
        elif direction =="hydro" :
                retour = hydro
          
                
        return retour
        
    def straintensor_scalar(direction,cristal_plane,eps=0,C11=16.577,C12=6.393,C44=7.962,poisson=True)   : 
        # Constants
        retour=np.zeros((3,3))
        
        
        # Initiation
        uniepsilon001=np.zeros((3,3))
        uniepsilon110=np.zeros((3,3))
        uniepsilon111=np.zeros((3,3))
        biepsilon001=np.zeros((3,3))
        biepsilon110=np.zeros((3,3))
        biepsilon111=np.zeros((3,3))
        shear001=np.zeros((3,3))
        shear110=np.zeros((3,3))
        shear111=np.zeros((3,3))
        hydro=np.zeros((3,3))    
        # Matrix computation
        # Uniaxial
        if poisson:
          uniepar001=-C12/(C11+C12)*eps
        else:
          uniepar001=0
          
        uniepsilon001[0][0]=uniepar001
        uniepsilon001[0][1]=0
        uniepsilon001[0][2]=0
        uniepsilon001[1][0]=0
        uniepsilon001[1][1]=uniepar001
        uniepsilon001[1][2]=0
        uniepsilon001[2][0]=0
        uniepsilon001[2][1]=0
        uniepsilon001[2][2]=eps
    
        if poisson:
          uniepar110=- ( 4*C12*C44 ) / ( 2*C11*C44+(C11+2*C12)*(C11-C12) )*eps 
        else:
          uniepar110=0
              
    
        uniepsilon110[0][0]=0.5*(eps+uniepar110)
        uniepsilon110[0][1]=0.5*(eps-uniepar110)
        uniepsilon110[0][2]=0
        uniepsilon110[1][0]=0.5*(eps-uniepar110)
        uniepsilon110[1][1]=0.5*(eps+uniepar110)
        uniepsilon110[1][2]=0
        uniepsilon110[2][0]=0
        uniepsilon110[2][1]=0
        uniepsilon110[2][2]=uniepar110
        
        if poisson:
          uniepar111 = - (C11 + 2*C12 - 2*C44) / (C11 + 2*C12 + 2*C44)*eps 
        else:
          uniepar111=0    
    
        uniepsilon111[0][0] = (eps + 2*uniepar111) / 3
        uniepsilon111[0][1] = (eps - uniepar111) / 3
        uniepsilon111[0][2] = (eps - uniepar111) / 3
        uniepsilon111[1][0] = (eps - uniepar111) / 3
        uniepsilon111[1][1] = (eps + 2*uniepar111) / 3
        uniepsilon111[1][2] = (eps - uniepar111) / 3
        uniepsilon111[2][0] = (eps - uniepar111) / 3
        uniepsilon111[2][1] = (eps - uniepar111) / 3
        uniepsilon111[2][2] = (eps + 2*uniepar111) / 3
        
        # Biaxial
        if poisson:
          bieper001 = -2 * C12 / C11 * eps
        else:
          bieper001=0      
        
        
    
        biepsilon001[0][0] = eps
        biepsilon001[0][1] = 0
        biepsilon001[0][2] = 0
        biepsilon001[1][0] = 0
        biepsilon001[1][1] = eps
        biepsilon001[1][2] = 0
        biepsilon001[2][0] = 0
        biepsilon001[2][1] = 0
        biepsilon001[2][2] = bieper001
        
        if poisson:
          bieper110 = -(C11+3*C12-2*C44)/(C11+C12+2*C44)*eps
        else:
          bieper110=0      
            
        
        biepsilon110[0][0] = 0.5*(bieper110+eps)
        biepsilon110[0][1] = 0.5*(bieper110-eps)
        biepsilon110[0][2] = 0
        biepsilon110[1][2] = 0
        biepsilon110[1][1] = 0.5*(bieper110+eps)
        biepsilon110[1][0] = 0.5*(bieper110-eps)
        biepsilon110[2][0] = 0
        biepsilon110[2][1] = 0
        biepsilon110[2][2] = eps
    
        if poisson:
          bieper111 = -2*(C11+2*C12-2*C44)/(C11+2*C12+4*C44)* eps
        else:
          bieper111=0     
              
        
        biepsilon111[0][0] = (bieper111+2*eps)/3 
        biepsilon111[0][1] = (bieper111-eps)/3 
        biepsilon111[0][2] = (bieper111-eps)/3 
        biepsilon111[1][0] = (bieper111-eps)/3 
        biepsilon111[1][1] = (bieper111+2*eps)/3 
        biepsilon111[1][2] = (bieper111-eps)/3 
        biepsilon111[2][0] = (bieper111-eps)/3 
        biepsilon111[2][1] = (bieper111-eps)/3 
        biepsilon111[2][2] = (bieper111+2*eps)/3
    
        # Shear
    
        shear001[0][2] = eps
        shear001[2][0] = eps
    
        shear110[0][2] = eps/np.sqrt(2)
        shear110[2][0] = eps/np.sqrt(2)
        shear110[1][2] = eps/np.sqrt(2)
        shear110[2][2] = eps/np.sqrt(2)
    
        shear111[0][1] = eps/np.sqrt(3)
        shear111[0][2] = eps/np.sqrt(3)
        shear111[1][0] = eps/np.sqrt(3)
        shear111[1][2] = eps/np.sqrt(3)
        shear111[2][0] = eps/np.sqrt(3)
        shear111[2][1] = eps/np.sqrt(3)
    
        # hydro
    
        hydro[0][0] = eps/3
        hydro[1][1] = eps/3
        hydro[2][2] = eps/3
        if direction == "uni":
            if cristal_plane == "001":
                retour=uniepsilon001
            elif cristal_plane == "110":
                retour=uniepsilon110         
            elif cristal_plane == "111":
                retour=uniepsilon111      
        elif direction == "bi":
            if cristal_plane == "001":
                retour=biepsilon001
            elif cristal_plane == "110":
                retour=biepsilon110         
            elif cristal_plane == "111":
                retour=biepsilon111
        elif direction == "shear":
            if cristal_plane == "001":
                retour=shear001
            elif cristal_plane == "110":
                retour=shear110         
            elif cristal_plane == "111":
                retour=shear111
        elif direction =="hydro" :
                retour = hydro
          
                
        return retour