Comprobación de miembros sujetos a fatiga según FEM 2131/2132 (5)

6 minutos de lectura

Tensión de cortadura

Tras analizar las tensiones de tracción y compresión, el trabajo para comprobar la tensión de cortadura está prácticamente hecho. Primero voy a ver la definición que hace la norma:

Para cada uno de los grupos de E1 a E8 se toma el esfuerzo de fatiga admisible en tensión del caso W0 dividido por 3.

τa=σt of case W03

El proceso de creación de las clases para el cálculo de la tensión de cortadura será similar al empleado con las tensiones de tracción y compresión.

  • En una primera clase llamada DataFrame obtendré los valores básicos para calcular las tensiones admisibles.
  • En una segunda clase llamada Formulae definiré el formulario para el cálculo.
  • Y en un tercera y última clase PermissibleTau obtendré las tensiones admisibles según las diferentes condiciones de cálculo.

La razón de organizar el código de esta manera, como expliqué en el post anterior, es una mezcla de programación defensiva y organización del código con vistas al mantenimiento.

La clase DataFrame contiene la variable de instancia df con los datos de estudio de la fatiga. Los métodos de la clase DataFrame son los getters de las variables del cálculo.

class DataFrame:
    """
    Pandas DataFrame with the data for the calculation of the 
    stresses for fatigue.
    """
    
    def __init__(self, df):
        """
        Asumes df is the pandas DataFrame with the data for the 
        calculation of the stresses for fatigue, get the values 
        of the columns.
        
        Parameters
        ----------
        df : pandas DataFrame ; data for the calculation of the 
                                stresses for fatigue.
        """
        
        self.df = df
        
    def get_df(self):
        """Getter of the DataFrame."""
        
        return self.df.copy()
        
    def get_df_columns(self):
        """Getter of the list wiht the DataFrame columns."""
        
        return list(self.df.columns)
        
    def get_sigma_W0(self):
        """Basic stress for W0 [MPa]."""
        
        return self.df['sigma_W0_[MPa]'].copy()
    
    def get_k_txy(self):
        """Ratio between the extreme stresses tau_xy."""
        
        return self.df['k_txy'].copy()

La segunda clase Formulae hereda de la clase DataFrame los atributos para operar e inicializa las variables de instancia del límite elástico σE y de la tensión de rotura σR.

class Formulae(DataFrame):
    """
    Formulae for de permissible stresses for fatigue with shear 
    loads according to FEM 2131/2132.
    """
    
    def __init__(self, df, sigma_E, sigma_R):
        """
        Asumes df, sigma_E and sigma_R the data for the calculation 
        of the stresses for fatigue, get the permissible stresses 
        for fatigue in case of ratio k ≤ 0 and k > 0 for shear.

        Parameters
        ----------
        df      : pandas DataFrame ; data for the calculation of 
                                     the stresses for fatigue.
        sigma_E : int              ; [MPa] elastic limit of steel.
        sigma_R : int              ; [MPa] ultimate tensile strength 
                                     of steel.
        """
        
        DataFrame.__init__(self, df)
        
        self.sigma_W0 = self.get_sigma_W0()
        self.sigma_E = sigma_E
        self.sigma_R = sigma_R

La norma indica que para calcular la tensión de cortadura se toma la tensión de fatiga admisible en tracción para el caso de W0. Las tensiones de fatiga admisible en tracción están indicadas en el post anterior. Como recordatorio estas son las fórmulas:

  • Si κ0

    σt=σW·532·κ0,66·σE

El código equivalente a la fórmula se recoge en el método tension_stress_k_neg de la clase Formulae.

def tension_stress_k_neg(self, k):
        """
        Permissible stress for k ≤ 0 and tension.
        
        Parameters
        ----------
        k : pandas Serie : ratio between the extreme stresses.
        """
        
        sigma_t = self.sigma_W0 * 5 / (3 - 2 * k)
        sigma_t = sigma_t.where(
            sigma_t <= 0.66 * self.sigma_E,  0.66 * self.sigma_E
            )
        
        return sigma_t
  • Si κ>0

    σt=σ01(1σ0σ+1)·κ0,66·σE

Donde

σ0 = tensión de tracción para κ = 0; se da en la fórmula (1), esto es:

σ0=1,66·σW

σ+1 = tensión de tracción para κ = +1, esto es, la tensión última σR dividida por el coeficiente de seguridad 1,33:

σ+1=0,75·σR

σt está limitada en todo caso a 0,66·σE.

En este caso de la tensión de cortadura, habrá que considerar σW=σW0.

Todo esto traducido a código:

def tension_stress_k_pos(self, k):
        """
        Permissible stress for k > 0 and tension.
        
        Parameters
        ----------
        k : pandas Serie : ratio between the extreme stresses.
        """
        
        sigma_0 = self.tensile_stress_k_0()
        sigma_1 = self.tensile_sttress_k_1()
        sigma_t = sigma_0 / (1 - (1 - sigma_0 / sigma_1) * k)
        sigma_t = sigma_t.where(
            sigma_t <= 0.66 * self.sigma_E,  0.66 * self.sigma_E
            )
        
        return sigma_t
    
    def tensile_stress_k_0(self):
        """Tensile stress for k = 0."""
        
        sigma_0 = 1.66 * self.sigma_W0
        
        return sigma_0
    
    def tensile_sttress_k_1(self):
        """Tensile stress for k = +1."""
        
        sigma_1 = 0.75 * self.sigma_R
        
        return sigma_1

La tercera clase PermissibleTau hereda de la clase Formulae los diferentes atributos y métodos, y como en el caso de las tensiones admisibles a tracción y compresión, obtengo los resultados finales de la tensión admisible a cortante en función de si κ toma un valor positivo o negativo.

class PermissibleTau(Formulae):
    """
    Permissible stresses for fatigue with shear loads according to 
    FEM 2131/2132.
    """
    
    def __init__(self, df, sigma_E, sigma_R):
        """
        Asumes df, sigma_E, sigma_R the data for the calculation of 
        the stresses for fatigue, get the permissible stresses for 
        fatigue in case of ratio k ≤ 0 and k > 0 for shear.

        Parameters
        ----------
        df      : pandas DataFrame ; data for the calculation of 
                                     the stresses for fatigue.
        sigma_W : pandas Serie     ; [MPa] basic stress.
        sigma_E :  int             ; [MPa] elastic limit of steel.
        sigma_R : int              ; [MPa] ultimate tensile strength 
                                     of steel.
        """
        
        Formulae.__init__(self, df, sigma_E, sigma_R)
        
        self.k_txy = self.get_k_txy()
        
    def shear_stress(self):
        """Permissible stress for shear."""
        
        tension_stress_k_neg = self.tension_stress_k_neg(self.k_txy)
        tension_stress_k_pos = self.tension_stress_k_pos(self.k_txy)
        tension_stress = tension_stress_k_neg.where(
            self.k_txy <= 0, tension_stress_k_pos
            )
        shear_stress = tension_stress / 3**(0.5)
        
        return shear_stress

Ya solo queda correr el código.

permissible_stress = PermissibleTau(df, sigma_E, sigma_R)
shear_stress = permissible_stress.shear_stress()
df['tau_a_[MPa]'] = round(shear_stress, 1)
cols = [
    'bar', 'node', 'component_group', 'notch_effect', 'tau_a_[MPa]'
    ]
df[cols]
  bar node component_group notch_effect tau_a_[MPa]
0 1 1 E8 K3 115.5
1 2 2 E8 K3 115.5
2 3 3 E7 K4 91.0
3 4 4 E6 K4 135.3
4 5 5 E7 K2 131.4
5 6 6 E8 K4 94.5
6 7 7 E8 K4 82.5
7 8 8 E8 K4 135.3
8 9 9 E6 K0 93.6
9 10 10 E6 K4 135.3

Para validar los resultados voy a hacer un cálculo manual de las tensiones τa de la barra 3 con el índice 2 del DataFrame.

Grado de acero: S 355

Grupo de la componente: E7

Tensión máxima τxy,max = -6 N/mm²

Tensión mínima τxy,min = 4 N/mm²

(Las tensiones máxima y mínima se definen en términos de valores absolutos).

κ=46=0,667<0

Tensión básica σW=σW0=136,6N/mm²

σt of case W0=σW·532κ=136,6·532(0,667)= =157,62 N/mm²0,66σE=0,66355=234,3N/mm² τa=σt of case W03=157,623=91,00

Como era de esperar, el valor τa=91,00N/mm² coincide con el valor tau_a_[MPa] del índice 2 del DataFrame df. Si no lo hiciera, habría que buscar el error, bien en el código, bien en la comprobación.

He hecho la verificación para un caso donde κ es negativo. Para completar la verificación voy a comprobar un caso donde κ sea positivo.

La fila con el índice 3 con la barra 4 tiene un κ igual a 0,556.

Grupo de la componente: E6

Tensión máxima τxy,max=9N/mm²

Tensión mínima τxy,min=5N/mm²

κ=59=0,556>0

Tensión básica σW=σW0=155,6N/mm²

σ0=1,66 σW=1,66155,6=258,3 N/mm² σ+1=0,75 σR=0,75490=367,5 N/mm² σt of case W0=σ01(1σ0σ+1)κ=258,31(1258,3367,5)0,556= =309,42 N/mm²0,66σE=0,66355=234,3N/mm²

Debe cumplirse la limitación.

σt of case W0=234,3N/mm² τa=σt of case W03=234,33=135,27

El valor τa=135,27N/mm² coincide con el valore tau_a_[MPa] del índice 3 del DataFrame df con los resultados.

Ya solo queda un último paso, la comprobación para las tensiones combinadas σ y τ.

Etiquetas: ,

Actualizado:

Comentar