Skip to content

Referências da API

valtervg13 edited this page Jun 30, 2022 · 13 revisions

Modulos

ComponentDesign

Explicações

Gears

O modulo gears é resposavel por...

classe SpurAGMA

    SpurAGMA(self,F,P_t,N_p,N_g,
             poisson_p,poisson_g,E_p,E_g,
             Q_v, n_p, n_g, N_cyc,
             H_Bp,H_Bg,
             N_c=9999,r_c=None,a_0 = 1.25,b_0=1,rho_a0=0.25,x_0 = 0,
             phi_n=20,psi=0,
             delta_s_n=0.024,x=0,
             load = "tip", orientation = 'external',
             coroamento = False, detrimento_superficie = False, 
             engrenamento = 'aberto',montagem_ajustada=False,tratamento = 'None',
             fonte_potencia = 'uniforme', choque_maquina = 'uniforme',
             trust = 99.99, temperatura = 20):

Modela engrenagens cilíndricas de dentes retos e helicoidais conforme metodologia da AGMA.

  • Parameters
    • F : float Largura de face em mm.
    • P_t : float Passo transversal em mm.
    • N_p : int N° de dentes do Pinhão.
    • N_g : int N° de dentes da Coroa.
    • poisson_p : float Coeficiente de Poisson do Material do Pinhão.
    • poisson_g : float Coeficiente de Poisson do Material da Coroa.
    • E_p : float Módulo de Young em GPa do Material do Pinhão.
    • E_g : float Módulo de Young em GPa do Material da Coroa.
    • Q_v : float Número de qualidade.
    • n_p : TYPE DESCRIPTION.
    • n_g : TYPE DESCRIPTION.
    • N_cyc : int Número de ciclos para vida em fadiga.
    • H_Bp : float Dureza Brinnel do pinhão.
    • H_Bg : float Dureza Brinnel da Coroa.
    • N_c : int, optional Número de dentes da cremalheira de fabricação. The default is 9999.
    • r_c : float, optional Raio nominal da cremalheria de fabricação. The default is None.
    • a_0 : float, optional Adendo admensional da cremalheira de fabricação. The default is 1.25.
    • b_0 : float, optional Dedendo adimensional da cremalheira de fabricação. The default is 1.
    • rho_a0 : TYPE, optional Raio de adoçamento da cremalheira de fabricação. The default is 0.25.
    • x_0 :float, optional Folga adimensional de "backlash" da cremalheira de fabricação. The default is 0.
    • phi_n : float, optional Angulo de pressão em deg. The default is 20.
    • psi : float, optional Angulo de hélice em deg. The default is 0.
    • delta_s_n : float, optional Parametro de modificação do dente. The default is 0.024.
    • x : float, optional Modificador de adendo do dente. The default is 0.
    • load : str, optional
    • Ponto de carregamento do dente: 'tip' para ponta ou 'HPSTC' para o ponto mais alto de contato em um único dente. The default is "tip".
    • orientation : str, optional Tipo de engrenagem. 'internal' para internas e 'external' para externas. The default is 'external'.
    • coroamento : bol, optional Define se há uso de coroamento nos dentes. The default is False.
    • detrimento_superficie : bol, optional Define se há presenseça de detrimento superfiical. The default is False.
    • engrenamento : str, optional Define o tipo de engrenamento. -1 ou 'aberto': engranamento aberto; -2 ou 'fecahdo comercial': Unidades fechadas comerciais; -3 ou 'fechado preciso': Unidades fechadas de precisão; -4 ou 'fechado extra-preciso': Unidades fechadas extra-precisas. O padrão é 'aberto'.
    • montagem_ajustada: bool, optional Define o tipo de mntagem. O padrão é Falso.
    • tratamento : str, optional Define o tipo de tratamento superficial. The default is 'None'.
    • fonte_potencia : str, optional Define o nível de choque esperado na fonte. The default is 'uniforme'.
    • choque_maquina : str, optional Define o nível de choque esperado na máquina. The default is 'uniforme'.
    • trust : float, optional Define o nível de confialbilidade adotado. The default is 99.99.
    • temperatura : float, optional Temperatura de operação em °C. The default is 20.

Metodo SpurAGMA.bending_stress_g

    SpurAGMA.bending_stress_g(self,W_t):

Tensão de flexão na coroa

  • Parameters ----------
    • W_t : float Carga transversal em N.
  • Returns -------
    • sigma : float Tensão em Pa.

Metodo SpurAGMA.bending_stress_p

     SpurAGMA.bending_stress_p(self,W_t)

Tensão de flexão no pinhão

  • Parameters

    • W_t : float Carga transversal em N.
  • Returns

    • sigma : float Tensão em Pa.

Metodo SpurAGMA.contact_stress_p

     SpurAGMA.contact_stress_p(self,W_t):

Tensão de contato no pinhão

  • Parameters

    • W_t : float Carga transversal em N.
  • Returns -------

    • sigma : float Tensão em Pa.

Metodo SpurAGMA.max_bending_g

     SpurAGMA.max_bending_g(self,S_t,S_F):

Máxima tensão de flexão na coroa

  • Parameters ----------

    • S_t : float Limite de resistência à flexão.
    • S_F :float Fator de segurança.
  • ** Returns** -------

      • max_sigma : float Tensão em Pa.

Metodo SpurAGMA.max_bending_p

     SpurAGMA.max_bending_p(self,S_t,S_F):

Máxima tensão de flexão admissível no pinhão

  • Parameters

    • S_t : float Limite de resistência à flexão.
    • S_F : float Fator de segurança.
  • Returns -------

    • max_sigma : float Tensão em Pa.

Metodo SpurAGMA.max_contact_g

      SpurAGMA.max_contact_g(self,S_c,S_F):

Máxima tensão de contato admissível na coroa

  • Parameters ----------

    • S_t : float Limite de resistência ao contato.
    • S_F : float Fator de segurança.
  • Returns -------

    • max_sigma : float Tensão em Pa.

Metodo SpurAGMA.max_contact_p

         SpurAGMA.max_contact_p(self,S_c,S_F):

Máxima tensão de contato admissível no pinhão

  • Parameters ----------

    • S_t : float Limite de resistência ao contato.
    • S_F :float Fator de segurança.
  • Returns -------

    • max_sigma : float Tensão em Pa.

Método SpurAGMA.safety_bending_p

        safety_bending_p(self,S_t,W_t)

Fator de segurança contra flexão do pinhão.

  • Parameters

    • S_t : Float Tensão máxima de flexão admissível em MPa.
    • W_t : float Carga transversal no dente em N.
  • Returns -------

    • S_F : float Fator de Segurança a Flexão do Pinhão.

Método SpurAGMA.safety_contact_p

    safety_contact_p(self,S_c,W_t)

Fator de segurança contra flexão do pinhão.

  • Parameters

      * **S_c** : Float
          Tensão máxima de contato admissível em MPa.
      * **W_t** : float
          Carga transversal no dente em N.
    
      * **Returns**
      -------
      S_F : float
          Fator de Segurança ao Contato do Pinhão.
    

def report_agma(self,precision=2,latex=False):

def report_stress(self,S_t,S_c,W_t,precision=2,latex=False): """

    Parameters
    ----------
    S_t : TYPE
        DESCRIPTION.
    S_c : TYPE
        DESCRIPTION.
    W_t : TYPE
        DESCRIPTION.
    precision : TYPE, optional
        DESCRIPTION. The default is 2.
    latex : TYPE, optional
        DESCRIPTION. The default is False.

    Returns
    -------
    params_dt: DataFrame or String
        Dataframe com os dados das tensões.

def report_dims(self,precision=2,latex=False):

class WormAGMA():

def init(self, nw:float, dw:float, dc:float, Nw:int, Nc:int, px:float, lambd:float, casting_method:str = 'molde', **threadkwargs):

    """
        Define os parâmetros de projeto para dimensionamento de pinhões 
        sem-fim de acorod com a metodologia da AGMA.

        Parameters
        ----------
        nw : float
            Rotação do pinhão sem-fim em RPM.
        dw : float
            Diametro nominal do pinhão sem-fim em mm.
        dc : float
            Diametro nominal da coroa sem-fim em mm.
        Nw : int
            N° de dentes do pinhão sem-fim em mm.
        Nc : int
            N° de dentes da coroa sem-fim em mm.
        px: float
            passo axial do pinhão em mm
        lambd : float
            Ângulo de avanço em deg.
        C : float
            Distância entre centros em mm.
        casting_method : str
            Tipo de fundição utilizado no pinhão.
            Opções: molde; resfriamento; centrifugo. O padrão é 'molde'
        **threadkwargs: kwargs
            Dados de adendo (kw: a) e dedendo (kw: b) e folga (kw: c) do 
            dente do pinhão. Somente nescessário se px < 4.06 mm. Por 
            padrão adota os valores padronizados para um angulo de pressão 
            de 20° de filente único.

        Returns
        -------
        None.

def Wadm(self,E=303,unit='N',FS=1.5): """ Calcula a força tangencial admissível no dente da coroa (componente mais crítico) a partir do método AGMA, corrigido pela razão entre os módulo de elasticidade do material adotado e a liga de bronze adotada pela AGMA para o dimensionamento de ssitemas de engrenamento sem-fim.

    Parameters
    ----------
    
    E : float
        Módulo de Young do material em MPa. O padrão é 303, idêntico à liga
        de aluínio-bronze considerada para os cálculos padrões da AGMA.
    unit : str, optional
        Define a unidade desejada da força no output. The default is 'N'.
    FS : float, optional
        Fator de segurança para contabilizar parâmetros não previstos nos 
        efeitos da mudança de material. The default is 1.5.

    Returns
    -------
    float
        Força tangecial admissível na unidade específicada.

def get_params(self): """ Gera dicionário com os parâmetros de correção do método AGMA.

    Returns
    -------
    params_dict : dict
        Dicionário com os parâmetros de correção do método AGMA.

    """
    
    params_dict = {'C_s':self.Cs,
                   'C_m':self.Cm,
                   'C_v':self.Cv,
                   'Vs':self.Vs
                   }
    
    
    return params_dict

def get_dims(self): """ Gera dicionário com os parâmetros dimensionais do engrenamento

    Returns
    -------
    params_dict : dict
        Dicionário com os parâmetros dimensionais do engrenamento.

    """
    params_dict = {'a':self.a,
                   'b':self.b,
                   'c':self.c,
                   'lambda':self.lambd,
                   'Pn':self.Pn,
                   'Pt':self.Pt}
    
    
    return params_dict

Screws

O modulo Screws é responsavel por...

class PowerScrew():

def init(self, thread, F, p, nt, dm, f, dc = 0, fc = 0 ): """ Parameters ---------- thread : TYPE DESCRIPTION. F : int, float Carga externa. dm : int, float Diametro médio da rosca. p : int, float passo axial. nt: int. Número de filetes de rosca engajados. f : int, float coeficiente de atrito.

    """

def nofriction(self): """ Calcula o torque sem fricção no parafuso.

    Returns
    -------
    float
        Torque sem atrito do parafuso.

    """
    return (self.F*self.l)/(2*np.pi)

def raise_torque(self): """ Calcula o torque para levantar uma carga externa

    Returns
    -------
    Tr : float
        Torque para levantar a carga.

    """

        Tr = ((self.F*self.dm)/2)*((self.l+self.dm*np.pi*self.f/np.cos(self.alpha))/(np.pi*self.dm-self.f*self.l/np.cos(self.alpha))) + (self.F*self.fc*self.dc)/2 #Nm, Torque para subir o parafuso (descer a prensa)
        
        return Tr

def raise_efficiency(self):

    T = self.raise_torque()
    T0 = self.nofriction()
    return T0/T

def lower_torque(self): """ Calcula o torque para abaixar uma carga externa

    -------
    Tl : float
        Torque para descer a carga.

    """

        Tl = ((self.F*self.dm)/2)*((self.dm*np.pi*self.f/np.cos(self.alpha)-self.l)/(np.pi*self.dm+self.f*self.l/np.cos(self.alpha))) + (self.F*self.fc*self.dc)/2 #Nm, Torque para subir o parafuso (descer a prensa)
        
        return Tl

def lower_efficiency(self):

    T = self.lower_torque()
    T0 = self.nofriction()
    return T0/T

def stress_tensor(self, raise_load = True, wheight_threads = False): """

    Parameters
    ----------
    raise_load : bool, optional
        Quandro True, inidca que o torque analisado é de subir a carga. The default is True.
    wheight_threads : bol, optional
        Quando True, indica que o partilhamento de cargas não é igual, de modo que a força no pimeiro 
        filete é 0,38*F. The default is False.

    Returns
    -------
    S : numpy array
        Tensor de tensões na raiz do parafuso.

    """
    if wheight_threads is True:
        F = 0.38*self.F
        nt = 1
    
    else:
        F = self.F
        nt = self.nt
    
    alpha = self.alpha
    dr = self.dr
    p = self.p
    
    t = p/2 * (1+np.tan(alpha))
    
    if raise_load is True:
        T = self.raise_torque()
    else:
        T = self.lower_torque()
        
    sig_xx = (3*F)/(np.pi*dr*t*nt)
    sig_yy = (4*F)/(np.pi*dr**2)
    sig_zz = 0
    
    tau_xy = 0
    tau_xz = 0
    tau_yz = (16*T)/(np.pi*dr**3)
    
    S = np.array([[sig_xx,tau_xy,tau_xz],
                  [tau_xy,sig_yy,tau_yz],
                  [tau_xz,tau_yz,sig_zz]]
                 )

    return S

Shafts

O modulo Shafts é responsavel por...

def pitch_min_d(theta_max,L,E,F_H=[(0,0)],F_V=[(0,0)],M_H=[(0,0)],M_V=[(0,0)],FS=1,placement=1): """

Parameters
----------
theta_max : Float
    Máxima inclinação em radianos.
L : FLoat
    Distância entre mancais em mm.
E : Float
    Módulo de elasticidade em GPa.
F_H : List of tuples, optional
    Em cada item, a primeira entrada é Força horizontal em N e a segunda é a 
    Distância entre Força e Mancal Esquerdo. The default is [(0,0)].
F_V : List of tuples, optional
    Em cada item, a primeira entrada é Força verrtical  em N e a segunda é a 
    Distância entre Força e Mancal Esquerdo. The default is [(0,0)].
M_H : List of tuples, optional
    Em cada item, a primeira entrada o Momento horizontal em Nm e a segunda é a 
    Distância entre o momento e Mancal Esquerdo. The default is [(0,0)].
M_V : List of tuples, optional
    Em cada item, a primeira entrada é o Momento vertical em Nm e a segunda é a 
    Distância entre o momento e Mancal Esquerdo. The default is [(0,0)].
FS : float, optional
    Fator de segurança. The default is 1.
placement : int, optional
    Configuração das Cargas e Mancais
     -1: Cargas Centralizadas entre Mancais, inclui momentos centralizados
     -2: Cargas Sobressaltantes, a frente do mancal direito
     -0: Definido em cada carga, deve-se adiconar à F_V e F_H
      uma terceira entrada equivalente à configuração. 
      Ex: F_V = [(100,0.5,1),(200,1,2)]. The default is 1.

Returns
-------
d_l : Float
    Diametro esquerdo em mm.
d_r : Float
    Diametro direito em mm.

"""


E = E*1e9 #Converte GPa em Pa

def ab(array,plc=placement): if plc == 1: a_list = np.array([item[1] for item in array]) b_list = np.array([L-a for a in a_list])

        a_list = a_list*1e-3
        b_list = b_list*1e-3
        return a_list,b_list
    
    elif plc == 2:
        a_list = np.array([item[1]-L for item in array])
        b_list = np.array([0 for a in a_list])
        
        a_list = a_list*1e-3
        b_list = b_list*1e-3
        return a_list,b_list
    
    elif plc == 0:
        a_list = []
        b_list = []
        
        for item in array:
            if array != [(0,0)]:

                x = item[1]
                plc = item[2]
                
                if plc == 1:
                    a_list.append(x)
                    b_list.append(L-x)
                    
                elif plc == 2:
                    a_list.append(x-L)
                    b_list.append(0)
            else:
                a_list.append(0)
                b_list.append(0)
                
        a_list = np.array(a_list)
        b_list = np.array(b_list)
        
        a_list = a_list*1e-3
        b_list = b_list*1e-3
        
        return a_list,b_list
            


F_H_list = np.array([F[0] for F in F_H])
a_FH, b_FH  = ab(F_H)


F_V_list = np.array([F[0] for F in F_V])
a_FV,b_FV = ab(F_V)

M_H_list = np.array([M[0] for M in M_H])
a_MH,b_MH = ab(M_H)

M_V_list = np.array([M[0] for M in M_V])
a_MV,b_MV = ab(M_V)

H_sum_l = 0
V_sum_l = 0

H_sum_r = 0
V_sum_r = 0

#Somatorio de Forças em H
L = L*1e-3 #Converte mm em m

for i,(F,b,a) in enumerate(zip(F_H_list,b_FH,a_FH)):
    if placement == 0:
        plc = F_H[i][2]
    else:
        plc = placement
    if plc == 1:
        H_sum_l += F*b*(b**2-L**2)
        H_sum_r += F*a*(L**2-a**2)
    elif plc == 2:
        H_sum_l += F*a*L**2
        H_sum_r += F*a*3*L**2


#Acréscimo dos Momentos
H_sum_l += np.sum(M_H_list*(3*a_MH**2-6*a_MH*L+2*L**2))
H_sum_r += np.sum(M_H_list*(3*a_MH**2-L**2))

#Somatorio de Forças em V
for i,(F,b,a) in enumerate(zip(F_V_list,b_FV,a_FV)):
    if placement == 0:
        plc = F_V[i][2]
    else:
        plc = placement
    if plc == 1:
        V_sum_l += F*b*(b**2-L**2)
        V_sum_r += F*a*(L**2-a**2)
    elif plc == 2:
        V_sum_l += F*a*L**2
        V_sum_r += F*a*3*L**2
        
#Acréscimo dos Momentos
V_sum_l += np.sum(M_V_list*(3*a_MV**2-6*a_MV*L+2*L**2))
V_sum_r += np.sum(M_V_list*(3*a_MV**2-L**2))


d_l = 1e3*(((32*FS)/
            (3*np.pi*E*L*theta_max)
            )*np.sqrt(H_sum_l**2+V_sum_l**2)
           )**0.25

d_r = 1e3*(((32*FS)/
            (3*np.pi*E*L*theta_max)
            )*np.sqrt(H_sum_r**2+V_sum_r**2)
           )**0.25
    
return d_l,d_r

def tensao_cisalhante(K_fs,T_a,T_m,d): #Shigley Ch. 7-4 eq. 7-4 tau_a = K_fs * (16T_a)/(np.pid3) tau_m = K_fs * (16T_m)/(np.pid3) return tau_a,tau_m def tensao_normal(K_f,M_a,M_m,d): #Shigley Ch. 7-4 eq. 7-3 sigma_a = K_f * (32M_a)/(np.pid3) sigma_m = K_f * (32M_m)/(np.pid3) return sigma_a,sigma_m def tensao_vm(K_f,K_fs,M_a,M_m,T_a,T_m,d,full_output = True): #Shigley Ch. 7-4 eq. 7-5, 7-6 tau_a,tau_m = tensao_cisalhante(K_fs,T_a,T_m,d) sig_a,sig_m = tensao_normal(K_f,M_a,M_m,d)

sig_VMa = (sig_a**2+3*tau_a**2)**0.5
sig_VMm = (sig_m**2+3*tau_m**2)**0.5

if full_output == True:
    tension_state_a = [sig_a,tau_a]
    tension_state_m = [sig_m,tau_m]
    return sig_VMa,sig_VMm,tension_state_a,tension_state_m
else:
    return sig_VMa,sig_VMm

def fatigue_nf(K_f,K_fs,T_a,T_m,M_a,M_m,d,S_y,S_ut,S_e,criteria = 'gerber',full_output = True): #Shigley Ch. 7-4 eq. 7-7 a 7-13

if full_output == True:
    sig_a,sig_m,tension_state_a,tension_state_m = tensao_vm(K_f,K_fs,M_a,M_m,T_a,T_m,d,full_output=True)
    
else:
    sig_a,sig_m,tension_state_a,tension_state_m = tensao_vm(K_f,K_fs,M_a,M_m,T_a,T_m,d,full_output=True) 

crit_dic = {"goodman" : fatigue.goodman_mod(S_ut = S_ut, S_e = S_e, mode ='n', sig_a = sig_a, sig_m = sig_m),
            "gerber" : fatigue.gerber(sig_a = sig_a, sig_m = sig_m, S_e = S_e, S_ut = S_ut),
            "asme" : fatigue.ASME(sig_a = sig_a, sig_m = sig_m, S_e = S_e, S_y = S_y),
            "soderberg" : fatigue.soderberg(S_y = S_y,S_e = S_e, mode='n', sig_a = sig_a, sig_m = sig_m)}

sig_max = np.sqrt((tension_state_a[0]+tension_state_m[0])**2+3*(tension_state_a[1]+tension_state_m[1])**2)
n_y = S_y/sig_max #Shigley Ch. 7-4 eq. 7-16 

if full_output == True:
    return {"n_f":crit_dic.get(criteria.lower()),'n_yeld' : n_y,
            'sig_vm_a' : sig_a, 'sig_vm_m' : sig_m, 'sig_vm_max' : sig_max,
            'sig_a, tau_a' : tension_state_a, 'sig_m, tau_m' : tension_state_m}
else:
    return crit_dic.get(criteria.lower()),n_y

def fatigue_d(K_f,K_fs,T_a,T_m,M_a,M_m,n,S_y,S_ut,S_e,criteria = 'gerber',full_output = True):

crit_dic = {"goodman" : ((16*n/np.pi)*((1/S_e)*((4*(K_f*M_a)**2+3*(K_fs*T_a)**2))**0.5
                                +(1/S_ut)*(4*(K_f*M_m)**2+3*(K_f*T_m)**2)**0.5))**(1/3),
            
            "gerber" : (((8*n*np.sqrt(4*(K_f*M_a)**2+3*(K_fs*T_a)**2))/(np.pi*S_e))*
                        ( 1 + (1+((2*np.sqrt(4*(K_f*M_m)**2+3*(K_fs*T_m)**2)*S_e)/
                                  (np.sqrt(4*(K_f*M_a)**2+3*(K_fs*T_a)**2)*S_ut)
                                  )**2
                               )**0.5
                         )
                        )**(1/3),                    
            
            "asme" : ((16*n/np.pi)*(4*(K_f*M_a/S_e)**2+3*(K_fs*T_a/S_e)**2
                                    +4*(K_f*M_m/S_y)**2+3*(K_fs*T_m/S_y)**2)**0.5
                      )**(1/3),
            
            "soderberg" : ((16*n/np.pi)*((1/S_e)*(4*(K_f*M_a)**2+3*(K_fs*T_a)**2)**0.5
                                +(1/S_y)*(4*(K_f*M_m)**2+3*(K_fs*T_m)**2)**0.5)
                           )**(1/3)
            }


return crit_dic.get(criteria.lower())

Dynamic

Explicações

Fatigue

class Fatigue():

def init(self): return def resitencia_fadiga(Sut, Se_cfg, Load, SecType, SecDim, Finish, Trust, Temp=20, Other=1, print_tables = True, full_output = False ): """

    Parameters
    ----------
    Sut : float
        Limite de resitência à tração em MPa.
    Se_cfg : float ou string
        Configura o valor de Se'. Caso um float seja entrado, representa 
        o valor de Se' em MPa. Caso seja uma string, representa o material
        utilizado para cálculo de Se' a partir de Sut. Se a string for 'aço',
        utiliza-se os valores para o aço. Caso contrário, assume-se alumínio
    Load : str ou int
        Tipo de carregamento sofrido pelo componente. opções:
         -0/'flexao': cargas flexionais
         -1/'axial': cargas axiais
         -3/'torção': cargas torcionais
         -4/'misto': comninação de cargas
    SecType : str ou int
        Formato da seção transversal. opções:
             -0/'retangular'
             -1/'circular': Seção circular sem rotação
             -2/'circular rodando': seção circualr em rotação
    SecDim : tuple
        Dimensões da seção. Para retangulos: (a,b) com "a" largura e "b' a 
        largura. Para circulos (d) com "d" o diâmetro em mm.
    Finish : str ou int
        Acabamento superficial. opções:
             -0/'retificado'
             -1/'usinado'/'estirado a frio'
             -2/'laminado a quente'
             -3/'forjado'
    Trust : float
        Confiabilidade. selecionar entre 99.9999, 99.999, 99.99, 99.9, 99, 
        95, 90'.
    Temp : float, optional
        Temperatura de operação. The default is 20.
    Other : float, optional
        Fatores diversos. The default is 1.
    print_tables : bool, optional
        Imprime as tabelas contendo os valores dos modificadores. The default is True.
    full_output : bool, optional
        Retorna um dicionário com Se e os fatores de correção obtidos.
        The default is False.

    Returns
    -------
    Se: float
        Limie de resitência à fadiga corrigido.
        
    Se_dict: dict, optional (full_output = True)
        Dicionário contendo o valor de Se, Se' e dos fatores de correção

    """
    
    Sut = Sut*1e6
    
    Load = str(Load)
    
    SecDim = tuple(map(lambda x: 1e-3*x,SecDim))
    
    if Se_cfg == "aço":
        if Sut < 1400*10**6:
            Se_line = 0.504*Sut
        else:
            Se_line = 700*1e6
    
    elif type(Se_cfg) is int or float:
        Se_line = Se_cfg*1e6 
        
    else: #Assume-se alumínio
        if Sut < 400*1e6:
            Se_line = 0.4*Sut
        else:
            Se_line = 160*1e6
            
    
    #C_Load (k_c)
    
    if Load.lower() in [0,'flexão','flexao',4,'misto']:
        Cload = 1
    elif Load.lower() in [1,'axial']:
        Cload = 0.85
    elif Load.lower() in (2,'torção','torçao','torcao','torcão'):
        Cload = 0.59

    
    
    #C_size (k_b)
    if Load.lower() in [1,'axial']:
            Csize = 1
            
    else:
        if SecType in [0,'retangular']:
            A95 = 0.05*SecDim[0]*SecDim[1]
            d = np.sqrt(A95/0.0766)

        elif SecType in [1,'circular']:
            A95 = 0.01046*(SecDim[0])**2
            d = np.sqrt(A95/0.0766)
        
        elif SecType in [2,'circular rodando','circular girando','eixo']:
            d = SecDim[0]
            
        if d < 2.79e-3 or d>254e-3:
            Csize = 1
        elif d<51e-3:
            Csize = 1.243*(d*10**3)**(-0.107)
        else:
            Csize = 1.51*(d*10**3)**(-0.157)
    
    #C_surface (k_a)
    if Finish  in [0,'retificado']:
        a=1.58
        b= -0.085
    elif Finish in [1,'usinado','estirado a frio']:
        a=4.51
        b= -0.265
    elif Finish in [2,'laminado a quente']:
        a=57.7
        b= -0.718
    elif Finish == [3,'forjado']:
        a=272
        b= -0.995
        

    Csurface = a*(Sut*1e-6)**(b)

    
    #C_trust (k_e)
    if Trust == 99.9999:
        Ctrust = 0.620
    elif Trust == 99.999:
        Ctrust = 0.659
    elif Trust == 99.99:
        Ctrust = 0.702
    elif Trust == 99.9:
        Ctrust = 0.753
    elif Trust == 99:
        Ctrust = 0.814
    elif Trust == 95:
        Ctrust =0.868
    elif Trust == 90:
        Ctrust =0.897
    else:
        raise ValueError('Enter a valid trust value from 99.9999, 99.999, 99.99, 99.9, 99, 95, 90')
    
    #C_temp(k_d)
    T_F = 9*Temp/5+32 #temperatura em farenheit
    if Temp == 20:
        Ctemp=1
    else: 
        Ctemp = 0.975+0.432e-3*T_F-0.115e-5*T_F**2+0.104e-8*T_F**3-0.595e-12*T_F**4
        
    
    #C_other (k_f)
    
    Cother = Other
    
    
    #Cálculo do Limite de Resistência à Fadiga
    S_e = Se_line*Cload*Csize*Csurface*Ctrust*Cother
    
    if print_tables == True:
        Cols = ['Fator de Correção','Valor','Variáveis','Valores']
        InfoNames = ['Tipo de Carregamento',
                      'Diametro Efetivo',
                      'Acabamento',
                      'a',
                      'b',
                      'Nível de Confiabilidade',
                      'Temperatura [°F]',
                      '-']
        InfoValues = [Load,
                      str('%.1f mm'%(d*10**3)),
                      Finish,
                      f"{a}",
                      f"{b}",
                      str('%s\%%'%(Trust)),
                      f'{T_F:.1f}',
                      "-"]
        Cnames= ['$C_{carregamento} (k_c)$',
                '$C_{tamanho} (k_b)$',
                '$C_{superficie} (k_a)$',
                '{}',
                '{}',
                '$C_{confiabilidade} (k_e)$',
                '$C_{Temperatura} (k_d)$',
                '$C_{outros} (k_f)$}']
        
        Cvalues = [f'{Cload:.3f}',
                   f'{Csize:.3f}',
                   f'{Csurface:.3f}',
                   '{}',
                   '{}',
                   f'{Ctrust:.3f}',
                   f'{Ctemp:.3f}',
                   f'{Cother:.3f}']
        
        print('Tabela de Fatores de Correção: \n\n')
        pd.options.display.float_format = '{:.3f}'.format
        
        
        Cdata = pd.DataFrame(data=np.transpose([Cnames,
                              Cvalues,
                              InfoNames,
                              InfoValues]),
                             columns=[Cols])
        CdataLTX = Cdata.to_latex(index=False,decimal=',',escape=False,multicolumn=True)
        #print(CdataLTX)
        print(Cdata)
        
    if full_output == True:
        return  {'S_e' : S_e*1e-6, 'Se_line' : Se_line*1e-6, 'd': d,
                'C_load' : Cload, 'C_size' : Csize, 'C_surface' : Csurface, 'C_trust' : Ctrust, 'C_temp': Ctemp,'C_other' : Cother}
    else:
        return S_e*1e-6

def S_N(sigma,Sut,Type,Load,SecType,SecDim,Finish,Trust, print_tables = True,full_output = False,*args):

    if Load=="flexão":
        Sm = 0.9*Sut
    else:
        Sm = 0.75*Sut

    Sf_dic = Fatigue.resitencia_fadiga(Sut, Type, Load, SecType, SecDim, Finish, Trust, print_tables = print_tables, full_output=True)
    Se = Sf_dic['Se_line']
    Sf = Sf_dic['S_e']
    d = Sf_dic['d']
    Cload = Sf_dic['C_load']
    Csize = Sf_dic['C_size']
    Csurface = Sf_dic['C_surface']
    Ctrust = Sf_dic['C_trust']
    
    b = (1/(-3))*np.log10(Sm/Sf)
    a = 10**(np.log10(Sm)-3*b)
    
    if print_tables == True:
        StressDic ={}
        
        Snames = ["$S_e'$",'$S_m$','$S_e$','$a$','$b$']
        Svalues = ['%.2f'%(Se*10**(-6)),'%.2f'%(Sm*10**(-6)),'%.2f'%(Sf*10**(-6)),'%.2f'%((a*10**(-6))),'%.4f'%(b)]
        Sunit = ['Mpa','Mpa','Mpa','Mpa','-']
        
        print('Tabela de Tensões: \n\n')
        StressDic['Grandeza']=Snames
        StressDic['Valor']=Svalues
        StressDic['Unidade']=Sunit
        pd.options.display.float_format = '{:,.2f}'.format
        Sdata = pd.DataFrame(StressDic)
        SdataLTX = Sdata.to_latex(index=False,decimal=',',escape=False)
        print(SdataLTX)
        
    N = (sigma/a)**(1/b)
    
    S_e = Sf
    if full_output == True:
        return { 'N' : N, 'a' :a, 'b' : b, 'S_e' : S_e, 
                'C_load' : Cload, 'C_size' : Csize, 'C_surface' : Csurface, 'C_trust' : Ctrust}
    
    else:
        return N

def goodman_mod(S_ut,S_e,mode,**kwargs): if mode == 'n': sig_a = kwargs['sig_a'] sig_m = kwargs['sig_m']

        n = 1/(sig_a/S_e+sig_m/S_ut)
        
        return n
    
    if mode == 'sig_a':
        n = kwargs['n']
        sig_m = kwargs['sig_m']
        
        sig_a = (1/n-sig_m/S_ut)*S_e
        
        return sig_a
        
    if mode == 'sig_m':
        n = kwargs['n']
        sig_a = kwargs['sig_a']
        
        sig_m = (1/n-sig_a/S_e)*S_ut
        
        return sig_m

def soderberg(S_y,S_e,mode,**kwargs,):
return Fatigue.goodman_mod(S_y,S_e,mode = mode,**kwargs) def gerber(sig_a,sig_m,S_e,S_ut):
return (1/2)((S_ut/sig_m)**2)(sig_a/S_e)( (-1 + np.sqrt(1+((2sig_mS_e)/(S_utsig_a))**2))) #sig_m>0 def ASME (sig_a,sig_m,S_e,S_y): return np.sqrt(1/((sig_a/S_e)**2+(sig_m/S_y)**2)) def first_cycle(sig_a,sig_m,S_y, mode = 'n'): if mode == 'n': n = S_y/(sig_a + sig_m)

        return n
    
    elif mode == 'sig_a':
        sig_a = n/S_y -sig_m
        
        return sig_a
    
    elif mode == 'sig_m':
        sig_m = n/S_y-sig_a
        
        return sig_m

Static

Explicações

Loads

O modulo loads é responsavel por...

class Loads():

def init(self): pass class Load(): """

    Parameters
    ----------
    tag : str
        Nome da variável da carga.
    position : array_like.
        Vetro posição em coordenadas cartesianas (x,y,z).
    value : array-like ou str, optional
        Vetor de intensidade da carga. Se `value` contiver uma string,
        considera-se que a componente é uma variável desconhecida. se
        for `None`, todas as componentes são consideradas variáveis. 
        The default is `None`.

    Returns
    -------
    None.

    """

def init(self,tag, position, value=None, load_type = 'F'):

        self.tag = tag
        self.position = np.array(position)
        self.load_type = load_type
        self.isknown = ([True if type(f_i) != str
                         else False
                         for f_i in value
                         ] if value != None
                        else (False,False,False)
                        )
        
        if value == None:
            self.value = np.ones(3)
        else:
            self.value = np.array([f_i if type(f_i) != str
                                   else -1 if '-' in f_i
                                   else 1
                                   for f_i in value
                                   ]
                                  )
        

        self.value_x = self.value[0]
        self.value_y = self.value[1]
        self.value_z = self.value[2]

def set_a(self,a_list): """ Parameters ---------- a_list : list or tuple Lista contendo os coeficientes escalares a serem multiplicados pela magnitude de forma a gerar os momentos causados pela carga. M_x = a_list[0]*F, M_y = a_list[1]*F, M_z = a_list[2]*F.

        Returns
        -------
        None.

        """
        self.a_x = a_list[0]
        self.a_y = a_list[1]
        self.a_z = a_list[2]

def set_value(self,val_list): """

        Parameters
        ----------
        val_list : list or tuple
            Lista contendo os valores de magnitude na forma (). 
            M_x = a_list[0]*F, M_y = a_list[1]*F, M_z = a_list[2]*F.

        Returns
        -------
        None.

        """
        self.isknown = ([True if type(f_i) != str
                         else False
                         for f_i in val_list
                         ])
        
        self.value = np.array([f_i if type(f_i) != str
                               else -1 if '-' in f_i
                               else 1
                               for f_i in val_list
                               ]
                              )
        
        self.value_x = val_list[0]
        self.value_y = val_list[1]
        self.value_z = val_list[2]

def get_values(self,axis=''): axis_dict = {'x':0, 'y':1, 'z':2 }

        idx = []
        for ax in axis:
            if ax not in idx:
                idx.append(axis_dict[ax])
                
        values = [cp.copy(self.value[ax]) for ax in idx]
        
        if len(values) == 1:
            return values[0]
        
        else:
            return values

def get_pos(self,axis=''): axis_dict = {'x':0, 'y':1, 'z':2 }

        idx = []
        for ax in axis:
            if ax not in idx:
                idx.append(axis_dict[ax])
                
        values = [cp.copy(self.position[ax]) for ax in idx]
        
        if len(values) == 1:
            return values[0]
        
        else:
            return values

def solve_reactions(loads:Load, load_init = None, coords='ijk', add_equations=[], print_matrix=False, update_loads=False, **kwargs): """ Parameters ---------- loads: Load Carga, conforme definida na classe Load coords : TYPE, optional Indica a orientação das coordenadas de origem através da notação de Einstein, de modo que Se coords = ijk, temos, para a1 = 1e_x e a2 = 1e_y a1 x a2 = a1a2 e_z. Já para ikj têm-se a1 x a2 = -a1*a2 e_z O padrão é 'ijk'.

    Returns
    -------
    Dicionário contendo as reações. Chaves são definidas pela tag de cada 
    objeto "Load" acrescidos de um sufixo "_x","_y","_z" a depender da
    componente.
    """
    
    F_loads = [load for load in loads if load.load_type.lower()=='f']
    M_loads = [load for load in loads if load.load_type.lower()=='m']
    
    #========================================================================
    # MATRIZES DO SISTEMA
    #========================================================================
    
    F = [[],
         [],
         []]
    
    Vars = []
    
    R = [[],
         [],
         []]
    
    M = [[],
         [],
         []]
    
    M_r = [[],
           [],
           []]
    
    #========================================================================
    # OBTENÇÃO DAS DIREÇÕES E SENTIDOS DOS MOMENTOS
    #========================================================================
    for load in loads:
        subs = (f'{coords[0]}{coords[1]}{coords[2]},{coords[1]},{coords[2]}->{coords[0]}'
                  )
        
        levi_civita = np.array([[[int((i - j) * (j - k) * (k - i) / 2)
                                  for k in range(3)
                                  ]
                                 for j in range(3)
                                 ]
                                for i in range(3)
                                ]
                               )
        


        x = load.position
        
        origin = np.ones(3)
        i = np.array([1,0,0])
        j = np.array([0,1,0])
        k = np.array([0,0,1])
        
        
        a_i = np.einsum(subs,levi_civita,x,i)
        a_j = np.einsum(subs,levi_civita,x,j)
        a_k = np.einsum(subs,levi_civita,x,k)
        
        a_list = [a_i,
                  a_j,
                  a_k]
        load.set_a(a_list)
        
        tag_sufix = ['_x','_y','_z']
        for n in range(3):
            if load.load_type.lower() == 'f':
                if load.isknown[n]:
                    for m in range(3):
                        if m==n:
                            F[m].append(load.value[n])
                        else:
                            F[m].append(0)
                
                        M[m].append(a_list[n][m]*load.value[n])
                else:
                    for m in range(3):
                        if m==n:
                            Vars.append(load.tag+tag_sufix[n])
                            R[m].append(load.value[n])

                        else:
                            R[m].append(0)  
                        
                        M_r[m].append(a_list[n][m]*load.value[n])
                        
            if load.load_type.lower() == 'm':
                if load.isknown[n]:
                    for m in range(3):
                        if m==n:
                            F[m].append(0)
                            M[m].append(load.value[n])
                        else:
                            F[m].append(0)
                            M[m].append(0)
                else:
                    for m in range(3):
                        if m==n:
                            Vars.append(load.tag+tag_sufix[n])
                            R[m].append(0)
                            M_r[m].append(load.value[n])
                        else:
                            M_r[m].append(0)
                            R[m].append(0)
    
    var_len = len(Vars)
    
    #======================================================================
    # MATRIZ DE FUNÇÕES
    #======================================================================
    
    #Checagem da dependencia linear
    
    exp_matrix = [[] for n in range(6)]
    
    for n in range(3):
        exp_matrix[n] = [*R[n],sum(F[n])]
        exp_matrix[n+3] = [*M_r[n],sum(M[n])]
    
    exp_matrix = np.array(exp_matrix)
    
    
    lin_dep = []
    for n in range(6):
        if all([exp_matrix[n,k]==0 
                for k in range(exp_matrix.shape[1])
                ]
               ):
            lin_dep.append(n)
            
        else:
            for m in range(6):
                if n != m:
                    inner_product = np.inner(exp_matrix[n,:],
                                             exp_matrix[m,:]
                                             )
                    norm_n = np.linalg.norm(exp_matrix[n,:])
                    norm_m = np.linalg.norm(exp_matrix[m,:])
        
                    if np.abs(np.abs(inner_product) - np.abs(norm_n * norm_m)) < 1E-4: #inequação de Cauchy
                        lin_dep.append(m)
    
    
    R = [R[n] 
         for n in range(3)
         if n not in lin_dep 
         ]
    
    F = [F[n] 
         for n in range(3)
         if n not in lin_dep 
         ]
    
    
    M_r = [M_r[n] 
           for n in range(3)
           if n+3 not in lin_dep 
           ]
    
    M = [M[n] 
         for n in range(3)
         if n+3 not in lin_dep 
         ]

def equations(R_0):

        R_eval = np.matmul(np.array(R),R_0)
        M_reval = np.matmul(np.array(M_r),R_0)
        
        
        F_eq = [R_eval[n]+sum(F[n]) for n in range(len(R_eval))]
        M_eq = [M_reval[n]+sum(M[n]) for n in range(len(M_reval))]
        
        
        add_eval = [func(R_0) for func in add_equations]
        
        eq_list = [*F_eq,
                   *M_eq]
            
        if add_eval != []:
            for eq_eval in add_eval: 
                eq_list.append(eq_eval)
            
        return eq_list
    
    R_0 = (np.ones(var_len) 
           if load_init == None
           else load_init
           )
    if print_matrix:
        
        precision = kwargs.pop('precision',2)
                    
        print(f"""

Matriz do sistema:

{bmatrix(np.array([*R,*M_r]), precision=precision) }{bmatrix(np.transpose([Vars]),precision=precision) } = {bmatrix(np.transpose(*np.sum(F,axis=1),*np.sum(M,axis=1)), precision=precision)}

""")

    Roots = fsolve(equations,R_0)

    
    root_dict = dict([(Vars[n],Roots[n]) 
                      for n in range(var_len)
                      ]
                     )
    
    if update_loads == True:
        for root in list(root_dict.keys()):
            axis = {'x':0,
                    'y':1,
                    'z':2}
                    
            tag,ax = root.split('_')
            idx = axis[ax]

            update_val = [0,0,0]
            
            for load in loads:
                if tag == load.tag: 
                    for i in range(3):
                        if i==idx:
                            update_val[i] = root_dict[f'{tag}_{ax}']
                        else:
                            update_val[i] = load.value[i]

                    load.set_value(update_val)

            
            

    
    return root_dict

def solve_internal(*loads:Load, axis='x', pos_shift = (0,0), l_divs=500, **graph_kwargs ): """

    Parameters
    ----------
    *loads : Load
        Cargas externas.
    axis : TYPE, optional
        DESCRIPTION. The default is 'x'.
    pos_shift : TYPE, optional
        DESCRIPTION. The default is (0,0).
    #axis : TYPE, optional
        axis=x -> pos=(y,z), axis=y -> pos=(z,x), axis=z -> pos=(x,y). The default is (0,0).
    axis : TYPE, optional
        DESCRIPTION. The default is y -> pos=(z,x).
    axis : TYPE, optional
        DESCRIPTION. The default is z -> pos=(x,y)                       l_divs=500.
    **graph_kwargs : keyword arguments
        Argumentos adicionais para criação de gráficos e impressão de resultados.
            -F_graphs: str
             string contendo "x", "y" e/ou "z". Gráficos dos esforços internos serão plotados.
            -M_graphs: str
             string contendo "x", "y" e/ou "z". Gráficos dos momentos internos serão plotados.
            -print_reactions: bool
            Imprime no console as reações em cada ponto de aplicação das forças
            -pckl: str
            Salva os gráficos como arquivos editáveis. pckl deve conter o caminho com nome e
            extensão do arquivo

    Returns
    -------
    dict
        Dicionário contendo as forças internas em cada seção.
    dict
        Dicionário contendo os momentos internos em cada seção
    list
        Lista de indices das repostas internas nos pontos de aplicação das forças

    """
    
    axis_dict = {'x':0,
                 'y':1,
                 'z':2}
    
    ax = axis_dict[axis]
    
    n_load = len(loads)
    
    
    sort_loads = sorted(loads,key = lambda load: load.position[ax])
    l_section = [load.position[ax] for load in sort_loads]
    
    l_range = []
    for k in range(n_load):

        if l_section[k] != l_section[-1]:
            l_inner =  np.linspace(l_section[k],
                                   l_section[k+1],
                                   l_divs
                                   )
            for l in l_inner:
                l_range.append(l)
        else:
            l_range.append(l_section[k])

def remove_dups(List):

        return list(map(float,
                        list(dict.fromkeys(map(str,
                                               List)
                                           )
                                 )
                        )
                    )
    
    l_range = np.array(remove_dups(l_range))
    
    
    F_roots = {axis: [],
               'R_x': [],
               'R_y': [],
               'R_z': []
               }
    M_roots = {axis: [],
               'Mr_x': [],
               'Mr_y': [],
               'Mr_z': []
               }
    
    for k in range(len(l_range)):
        
        pos = [0,0,0]
        pos[ax] = l_range[k]
        if ax == 0:
            pos[1] = pos_shift[0]
            pos[2] = pos_shift[1]
        elif ax == 1:
            pos[2] = pos_shift[0]
            pos[0] = pos_shift[1]
        else:
            pos[0] = pos_shift[0]
            pos[1] = pos_shift[1]

        
        R_int = Loads.Load(f'R{k}',
                           position=pos)
      
        M_int = Loads.Load(f'Mr{k}',
                           position=pos,
                           load_type='M')
        
        load_list = [*[load 
                       for load in loads 
                       if load.position[ax] <= l_range[k]
                       ],
                     R_int,
                     M_int
                     ]

        node_solution = Loads.solve_reactions(*load_list)
        
        F_roots[axis].append(l_range[k])
        F_roots['R_x'].append(node_solution[f'R{k}_x'])
        F_roots['R_y'].append(node_solution[f'R{k}_y'])
        F_roots['R_z'].append(node_solution[f'R{k}_z'])

        
        M_roots[axis].append(l_range[k])
        M_roots['Mr_x'].append(node_solution[f'Mr{k}_x'])
        M_roots['Mr_y'].append(node_solution[f'Mr{k}_y'])
        M_roots['Mr_z'].append(node_solution[f'Mr{k}_z'])
        
    #==================================================================
    # PLOTAGEM DE DIAGRAMAS
    #==================================================================
    
    F_graphs = graph_kwargs.pop('F_graphs','')
    units = graph_kwargs.pop('units',{'distance':'m',
                                      'force':'N',
                                      'torque':'Nm'})
    
    pckl_dict = graph_kwargs.pop('pckl',None)
    
    if pckl_dict is not None:
        pckl_title = pckl_dict['title']
        pckl_path = pckl_dict['path']
        pckl_tag = pckl_dict.pop('tag','')
        
        

    F_idx = []

    for graph_axis in ['x','y','z']:
        graph_label = ('$N$' 
                       if graph_axis == axis
                       else f'$V_{graph_axis}$'
                       )
        
        x_label = f'{graph_axis} [{units["distance"]}]'
        y_label = (f'N: Esforço normal [{units["force"]}]' 
                   if graph_axis == axis
                   else f'$V_{graph_axis}$: Esforço Cortante em {graph_axis}'
                   )
        
        l = np.array(F_roots[axis])
        F = np.array(F_roots[f'R_{graph_axis}'])
        
        l_ticks = l_section
        f_indexes = np.where([l_value in l_ticks for l_value in l])[0]
        f_ticks = [F[i] for i in f_indexes]
        
        F_idx.append(f_indexes)

        if graph_axis in F_graphs:                

            fig = plt.figure(figsize=(9,6))
            plt.rc('font',**{'family':'serif','serif':['Times New Roman']})
            ax = fig.gca()
            ax.plot(l,F,'b-.',label=graph_label)
            ax.legend([graph_label])
            plt.fill_between(l,F,color='blue',**{'alpha':0.2})
            ax.set_xlim(0,np.max(l)+0.005*np.max(l))
            ax.set_xlabel(x_label)
            ax.set_ylabel(y_label)
            plt.xticks(l_ticks,[f'{tick:.2f}' for tick in l_ticks])
            plt.yticks(f_ticks,[f'{tick:.2f}' for tick in f_ticks])
            plt.grid()
            
            if pckl_dict is None:
                plt.show()
                
            else:
                pckl_file = f'{pckl_path}/{pckl_title}_{graph_label}_{pckl_tag}.txt'
                
                
                with open(pckl_file,'wb') as file:
                    pc.dump(fig,file)
            
            
    M_graphs = graph_kwargs.pop('M_graphs','')
    
    M_idx = []

    for graph_axis in ['x','y','z']:
        graph_label = ('$T$' 
                       if graph_axis == axis
                       else f'$Mf_{graph_axis}$'
                       )
        
        x_label = f'{graph_axis} [{units["distance"]}]'
        y_label = (f'T: Torque [{units["torque"]}]' 
                   if graph_axis == axis
                   else f'$Mf_{graph_axis}$: Momento fletor em {graph_axis}'
                   )
        
        l = np.array(M_roots[axis])
        M = np.array(M_roots[f'Mr_{graph_axis}'])
        
        l_ticks = l_section
        m_indexes = np.where([l_value in l_ticks for l_value in l])[0]
        m_ticks = [M[i] for i in m_indexes]
        
        M_idx.append(m_indexes)
        
        if graph_axis in  M_graphs:
                
                fig = plt.figure(figsize=(9,6))
                plt.rc('font',**{'family':'serif','serif':['Times New Roman']})
                ax = fig.gca()
                ax.plot(l,M,'b-.',label=graph_label)
                ax.legend([graph_label])
                plt.fill_between(l,M,color='blue',**{'alpha':0.2})
                ax.set_xlim(0,np.max(l)+0.005*np.max(l))
                ax.set_xlabel(x_label)
                ax.set_ylabel(y_label)
                plt.xticks(l_ticks,[f'{tick:.2f}' for tick in l_ticks])
                plt.yticks(m_ticks,[f'{tick:.2f}' for tick in m_ticks])
                plt.grid()
                
                if pckl_dict is None:
                    plt.show()
                    
                else:
                    pckl_file = f'{pckl_path}/{pckl_title}_{graph_label}_{pckl_tag}.txt'
                    
                    with open(pckl_file,'wb') as file:
                        pc.dump(fig,file)
            
    
    indexes = {'F_idx': list(map(int,F_idx[0])),
               'M_idx': list(map(int,M_idx[0]))
               }
    
    
    print_reactions = graph_kwargs.pop('print_reactions',False)
    if print_reactions == True:
        print('\nEsforços Internos')
        for R in ['R_x','R_y','R_z']:
            if R.split('_')[1] in F_graphs:
                print('\n')
                for i in indexes['F_idx']:
                    x = F_roots[axis][i]
                    
                    if i!=0:
                        print(f'{R}({axis}={x} "->") = {F_roots[R][i-1]:.3f} {units["force"]}')
                        
                    print(f'{R}({axis}={x} "<-") = {F_roots[R][i]:.3f} {units["force"]}')

        for Mr in ['Mr_x','Mr_y','Mr_z']:
            if Mr.split('_')[1] in M_graphs:
                print('\n')
                for i in indexes['M_idx']:
                    x = M_roots[axis][i]
                    
                    if i!=0:
                        print(f'{Mr}({axis}={x} "->") = {M_roots[Mr][i-1]:.3f} {units["torque"]}')
                        
                    print(f'{Mr}({axis}={x} "<-") = {M_roots[Mr][i]:.3f} {units["torque"]}')

    
    return F_roots,M_roots,indexes

Stress

O modulo Stress é responsável por...

class Stress():

def init(self): return class Section():

def init(self,section_type,*dims): self.type = section_type self.dims = list(dims)

def rectangle(b,h): return {'A': bh, 'I_x': (bh3)/12, 'I_y': (b3*h)/12, 'I_xy': 0 }

def circle(D): return {'A': np.piD**2/4, 'I_x': np.piD4/64, 'I_y': np.pi*D4/64, 'I_xy': 0, 'J': np.pi*D**4/32 }

def hollow_circle(D,d): return {'A': np.pi*(D2-d2)/4, 'I_x': np.pi*(D4-d4)/64, 'I_y': np.pi*(D4-d4)/64, 'I_xy': 0, 'J': np .pi*(D4-d4)/32 }

        if len(dims) == 1:
            self.dims.append(0)
            
        self.property_dict = {'rectangle': rectangle(self.dims[0],self.dims[1]),
                              'circle': circle(self.dims[0]),
                              'hollow_circle': hollow_circle(self.dims[0],self.dims[1])
                              }

def properties(self): match_key = ('rectangle' if self.type in (1,'1','square','r','rectangle') else 'circle' if self.type in (2,'2','circle','round','r','c') else 'hollow_circle' if self.type in (3,'3','hollow_circle','hc') else 'circle' )

        return self.property_dict[match_key]

def get_stress(section:Section, pos, normal='x', full_output = False, **loads): """

    Parameters
    ----------
    section : Section
        DESCRIPTION.
    pos : TYPE
        DESCRIPTION.
    normal : TYPE, optional
        DESCRIPTION. The default is 'x'.
    **loads : keyword arguments
        Cargas internas na seção:
            - N: Normal
            - V_y: Cisalhante no sentido y
            - V_z: Cisalhante no sentido z
            - T: Torque normal
            - Mf_y: Momento fletor no sentido y
            - Mf_z: Momento fletor no sentido y

    Returns
    -------
    S : TYPE
        Tensor das tensões. Nunca considera tensões no plano yz, apenas xy e xz.

    """
    axis_dict = {'x':0,
                 'y':1,
                 'z':2}
    
    local_axis = {'x': {'x_0': 'x',
                        'y_0': 'y',
                        'z_0': 'z'},
                  'y': {'x_0': 'y',
                        'y_0': 'z',
                        'z_0': 'x'},
                  'z': {'x_0': 'z',
                        'y_0': 'y',
                        'z_0': 'x'},
                  }
    
         
    pos_y = pos[0]
    pos_z = pos[1]   
    
    
    x = axis_dict[local_axis[normal]['x_0']] #x indica a orientação *local*
    y = axis_dict[local_axis[normal]['y_0']] #y indica a orientação *local*
    z = axis_dict[local_axis[normal]['z_0']] #z indica a orientação *local*
            
    sect_props = section.properties()
    
    A = sect_props['A']
    I_z = sect_props['I_x'] 
    I_y = sect_props['I_y'] 
    I_zy = sect_props['I_xy']
    J = sect_props['J']
    

    for key,val in loads.items():
        if type(val) not in [tuple,list,np.array]:
            loads[key] = [0,0,0]
            if key in ['N','T']:
                loads[key][x] = val
            elif key in ['V_y','Mf_y']:
                loads[key][y] = val
            elif key in ['V_z','Mf_z']:
                loads[key][z] = val

  

    N = loads.pop('N',[0,0,0])
    V_y = loads.pop('V_y',[0,0,0])
    V_z = loads.pop('V_x',[0,0,0])

    
    T = loads.pop('T',[0,0,0])
    Mf_y = loads.pop('Mf_y',[0,0,0])
    Mf_z = loads.pop('Mf_z',[0,0,0])
    

    sig_tension = N[x]/A
    sig_flex_y = -Mf_z[z]*pos_y/I_y
    sig_flex_z = Mf_y[y]*pos_z/I_z
    

    sig_xx = sig_tension + sig_flex_y + sig_flex_z
    
    
    rho = np.sqrt(pos_z**2+pos_y**2)
    
    theta = (np.arctan(pos_y/pos_z) if pos_z != 0
             else 0 if pos_y == 0
             else np.pi/2 if pos_y//pos_y == 1
             else 3*np.pi/2
             )
    rho_dir = np.array((0,np.cos(theta),np.sin(theta)))
    T_dir = np.zeros(3)
    T_dir[x] = (T[x]//T[x] if T[x] != 0
                else 1)
    tau_dir = np.cross(T_dir,rho_dir)
    
    tau_torsion = -T[x]*rho/J
    tau_torsion_xy = tau_dir[y]*tau_torsion
    tau_torsion_xz = tau_dir[z]*tau_torsion
    

    
    if section.type in (2,'2','circle','round','c'):
        R = section.dims[0]/2
        tau_shear_xy = 4*(V_y[y]*(R**2-pos_y**2))/(3*np.pi*R**4)
        tau_shear_xz = 4*(V_z[z]*(R**2-pos_z**2))/(3*np.pi*R**4)
    
    elif section.type in (3,'3','hollow_circle','hc'):
        R = section.dims[0]/2
        tau_shear_xy = (2*V_y[y]/A if pos_y==0
                       else 0 if pos_y==R
                       else V_y[y]/A) 
        tau_shear_xz = (2*V_z[z]/A if pos_z==0
                       else 0 if pos_z==R
                       else V_z[z]/A)
        
    else:
        a,b = section.dims[0:2]
        tau_shear_xy = V_y[y]/(2*I_y)*(b**2-pos_y**2)
        tau_shear_xz = V_z[z]/(2*I_z)*(a**2-pos_z**2)
        
    tau_xy = tau_torsion_xy+tau_shear_xy
    tau_xz = tau_torsion_xz+tau_shear_xz
    
    S = np.zeros((3,3))
    
    S[x,x] = sig_xx 
    S[x,y] = tau_xy
    S[y,x] = tau_xy
    S[x,z] = tau_xz
    S[z,x] = tau_xz
    
    stress_dict = {'sig_normal': sig_xx,
                   'sig_flex': (sig_flex_y,sig_flex_z),
                   'tau_torsion': (tau_torsion_xy,tau_shear_xz),
                   'tau_shear': (tau_shear_xy,tau_shear_xz)
                   }
    
    if full_output == True:
        return S,stress_dict
    
    else:
        return S

def VonMisses(S):

    sig_x = S[0,0]
    sig_y = S[1,1]
    sig_z = S[2,2]
    
    tau_xy = S[0,1]
    tau_xz = S[0,2]
    tau_yz = S[1,2]


    sig_vm = (1/np.sqrt(2))*np.sqrt((sig_x-sig_y)**2
                                    +(sig_y-sig_z)**2
                                    +(sig_z-sig_x)**2 
                                    +6*(tau_xy**2+tau_xz**2+tau_yz**2)
                                    )

    return sig_vm

Units

Explicações

Units

def SI(value:float, input_unit:str, output_unit:str): """ Converte unidades do SI

Parameters
----------
value : float
    Valor a ser convertido.
input_unit : str
    Unidade da entrada. Ex: mm2, GPa, cm3.
output_unit : str
    Unidade da saída.

Returns
-------
float
    Valor convertido da unidade de entrada para a unidade de saída.

"""
if input_unit=='mm' or output_unit=='mm':
    si_unit = 'm'
    
else:
    si_unit=''
    for char in input_unit:
        if char in output_unit:
            si_unit+=char

if input_unit != si_unit:
    
    if 'mm' in input_unit:
        input_split = input_unit.split('mm')
        input_prefix = 'm'
        input_power = (1 if input_split[1] == ''
                       else float(input_split[1])
                       )
    else:
        input_split = input_unit.split(si_unit)
       
        if len(input_split) < 2:
            input_prefix = input_split[0]
            input_power = 1
        else:
            print(input_split)
            input_prefix = input_split[0]
            input_power = (1 if input_split[1] == ''
                           else float(input_split[1])
                           )
   
    input_rate = prefix[input_prefix]**input_power

else:
    input_rate = 1


if output_unit != si_unit:
    
    if 'mm' in output_unit:
        output_split = output_unit.split('mm')
        output_prefix = 'm'
        output_power = (1 if output_split[1] == ''
                       else float(output_split[1])
                       )
     
    else:
        output_split = output_unit.split(si_unit)
       
        if len(output_split) < 2:
            output_prefix = output_split[0]
            output_power = 1
        else:
            output_prefix = output_split[0]
            output_power = (1 if output_split[1] == ''
                           else float(output_split[1])
                           )
       
    output_rate = prefix[output_prefix]**output_power
       


else:
    output_rate = 1
    

rate = input_rate/output_rate

return rate*value

def rad_velocity(n:float,input_unit:str,output_unit:str): """ Converte velocidades radiais de RPM para rad/s e vice versa

Parameters
----------
n : float
    velocidade radial.
input_unit : str
    unidade de entrada, pode ser 'RPM' ou 'rad/s'.
output_unit : str
    unidade de saída, pode ser 'RPM' ou 'rad/s'.

Returns
-------
float
    velocidade radial convertida.

"""

if input_unit == output_unit:
    return n

elif input_unit.lower() == "rpm" and output_unit=='rad/s':
    omega = n*2*np.pi/60


elif input_unit == "rad/s" and output_unit.lower() == "rpm":
    omega = 60*n/(2*np.pi)

return omega

def m2ft(x:float,metric_unit:str='m', imperial_unit:str='ft'): """ Converte comprimento métrico para pés.

Parameters
----------
x : float
    valor a ser convertido.
metric_unit : str, optional
    Unidade métrica adotada. permite utilizar valores diretamente em 
    unidades como mm, dm, km e outras. The default is 'm'.

Returns
-------
float
    Valor convertido para unidade imperial especificada.

"""
x = SI(x,metric_unit,'m')
imp_rate = 3.28084/imperial[imperial_unit]

return x * imp_rate

def ft2m(x:float, metric_unit:str='m', imperial_unit:str='ft'): """ Converte pés para comprimento métrico.

Parameters
----------
x : float
    valor a ser convertido.
metric_unit : str, optional
    Unidade métrica adotada. permite utilizar valores diretamente em 
    unidades como mm, dm, km e outras. The default is 'm'.

Returns
-------
float
    Valor convertido para unidade métrica específicada.

"""
imp_rate = 3.28084*imperial[imperial_unit] 

m = x/imp_rate

return SI(m,'m',metric_unit)

def N2lbf(x:float, metric_unit:str='N'):

x = SI(x,metric_unit,'N')
imp_rate = 1/4.448

return x*imp_rate

Clone this wiki locally