Example #1
0
def fase_iniciacion(param, sigma, crit, a_i,ac, da, W, MAT):
    """Devuelve los ciclos de la fase de iniciacion de una grieta, conocida
    la tension media desde la superficie hasta la punta de la misma.
    
    INPUTS: param = Fatemi-Socie o Smith-Watson-Topper en un punto 
            sigma = tension x en ese punto
            crit  = parametro a utilizar
            a_i   = (m) tamaño de la grieta de iniciacion
            ac    = plana o eliptica (0 o 0.5)
            da    = paso para realizar los calculos 
            W     = (m) anchura del especimen
            MAT   = indice asignado del material
                  
    OUTPUT: N_i   = ciclos de la fase de iniciacion"""
    
    #Calcula los ciclos totales hasta el fallo
    N_t = ciclos_totales(param, crit, MAT)
    
    #ind_a se utiliza para la propia fase de propagacion por lo 
    #que en la fase de iniciacion no es una variable relevante y puede tomar 
    #cualquier valor
    ind_a = 0
    
    #Calculos los ciclos que necesita la grieta para propagarse
    N_p = fase_propagacion(sigma, ind_a, a_i,ac, da, W, MAT)
    
    #Calculamos los ciclos de iniciacion
    N_i = N_t - N_p
    
    #Si el numero es negativo devuelve 0
    if N_i < 0:
        N_i = 0.0
        
    #Para ciclos muy altos solo se tiene en cuenta la iniciación para evitar 
    #errores que se producen en la integración de la propagación
    if N_t > 1.5e7:
        N_i = N_t
    
    return N_i
Example #2
0
def principal(par,
              W,
              MAT,
              ac,
              exp_max,
              exp_min,
              ruta_exp,
              ruta_curvas=None,
              main_path=""):
    """Estima la vida a fatiga.
    
    INPUTS:  par     = parametro para el modelo de iniciacion
             W       = (m) anchura del especimen        
             MAT     = indice asignado al material
             ac      = propagacion plana o eliptica
             exp_max = nombre del archivo con la tensiones y defs maximas
             exp_min = nombre del archivo con la tensiones y defs minimas
             ruta_curvas = ubicación de las curvas de iniciación
            
    OUTPUTS: resultados.dat = actualiza el archivo de resultados con la
             longitud de iniciacion y los ciclos de iniciacion, propagacion y 
             total para que se produzca el fallo
             a_inic         = longitud de grieta de iniciación
             v_ai_mm        = vector de longitudes de grietas en mm 
             N_t_min        = Ciclos de iniciación
             N_t            = Vector de ciclos totales
             N_p            = Vector de ciclos de propagación   
             N_i            = Vector de ciclos de iniciación
             N_a            = Vector de ciclos de propagación a partir de la iniciación
             exp_id.dat     = archivo con los datos de las curvas de vida"""

    print('Datos Experimentales:\n    {}.dat\n    {}.dat\n'.format(
        exp_max, exp_min))
    #exp_id obtiene a partir del nombre del archivo con los datos un
    #identificador del experimento. Dependiendo del nombre del archivo debe
    #modificarse.
    pattern = r"\d+_\d+_\d+"
    exp_id = re.search(pattern, exp_max).group()

    #Obtenemos las rutas a las carpetas necesarias para los calculos
    # cwd         = os.getcwd()
    # ruta_exp    = cwd + '/datos_experimentales'
    ruta_datos = main_path + '/resultados/datos/{}'.format(par)
    if ruta_curvas is None:
        ruta_curvas = main_path + '/curvas_inic/{}'.format(ac)
        data_interp = np.loadtxt("{}/MAT_{}.dat".format(ruta_curvas, par))
    else:
        data_interp = np.loadtxt(ruta_curvas)

    #Cargamos los datos de las curvas de iniciación del material

    #Separamos las curvas en las variables necesarias
    x_interp = data_interp[0, 1:]  #Eje x de la matriz de interpolación
    y_interp = data_interp[1:, 0]  #Eje y de la matriz de interpolación
    m_N_i = data_interp[1:, 1:]  #Matriz con los ciclos de iniciación

    #Creamos la función de interpolación
    function_interp = interp2d(x_interp,
                               y_interp,
                               m_N_i,
                               kind='quintic',
                               bounds_error=False)

    #Cargamos los datos experimentales y generamos el vector de FS o SWT
    x, sxx_max, s_max, e_max, e_min = lectura_datos(ruta_exp, exp_max, exp_min)
    param = parametro(par, MAT, x, s_max, e_max, e_min)

    a_i_min = round(x[1], 8)  #Tamaño mínimo de longitud de grieta de
    #iniciacion. Redondeamos para evitar errores
    #numericos.
    a_i_max = round(x[-1],
                    8)  #Tamaño máximo de longitud de grieta de iniciacion
    da = a_i_min  #Paso entre longitudes de grietas

    #Creamos el vector de longitudes de grieta de iniciacion

    v_ai = np.arange(a_i_min, a_i_max,
                     da)  #Vector de longitudes de grieta en m
    v_ai_mm = v_ai * 1e3  #Vector de longitudes de grieta en mm

    #Calculamos los ciclos de iniciación, de propagación y totales para cada
    #longitud de grieta de iniciacion
    #Inicializamos los ciclos
    N_i = np.zeros_like(v_ai)
    N_p = np.zeros_like(v_ai)
    N_t = np.zeros_like(v_ai)

    for i, a in enumerate(v_ai):
        ind_a = indice_a(a, x)  #Indice asociado a esa longitud de grieta
        param_med = np.mean(
            param[:ind_a +
                  1])  #Valor medio del parametro para la interpolacion

        #Realizamos la interpolacion para calcular los ciclos de iniciacion
        N_i[i] = function_interp(a, param_med)[0]

        #La interpolacion puede dar valores menores que 0 para ciclos muy bajos
        if N_i[i] < 0:
            N_i[i] = 0

        #Calculamos los ciclos de propagacion
        N_p[i] = fase_propagacion(sxx_max, ind_a, a, ac, da, W, MAT)

        #Ciclos totales
        N_t[i] = N_i[i] + N_p[i]

    #Calculamos el numero de ciclos hasta el fallo y la longitud de iniciación
    #de la grieta, que se producen en el mínimo de la curva de ciclos totales
    N_t_min = np.min(N_t)
    i_N_t_min = np.argmin(N_t)
    N_i_min = N_i[i_N_t_min]
    N_p_min = N_p[i_N_t_min]
    a_inic = v_ai_mm[i_N_t_min]

    #Pintamos la figura con la evolucion de la longitud de grieta y guardamos
    #en un archivo los datos
    ciclos = open(ruta_datos + '/{}.dat'.format(exp_id), 'w')
    ciclos.write('{:<5}\t{:<12}\t{:<12}\t{:<12}\t{:<12}'.format(
        'a_i', 'N_t', 'N_i', 'N_p', 'N_a'))

    N_a = []  #Vector de ciclos con la evolución de la grieta

    for i, ai in enumerate(v_ai):
        #Hasta la longitud de iniciacion crece como los ciclos de iniciacion
        if ai <= a_inic * 1e-3:
            n_a = N_i[i]
            N_a.append(n_a)
        #A partir de la longitud de iniciacion crece de acuerdo con los ciclos
        #de propagacion
        else:
            n_a = N_a[-1] + N_p[i - 1] - N_p[i]
            N_a.append(n_a)
        n_i = N_i[i]
        n_p = N_p[i]

        ciclos.write('\n{:.3f}\t{:.6e}\t{:.6e}\t{:.6e}\t{:.6e}'.format(
            ai * 1e3, n_i + n_p, n_i, n_p, n_a))
    ciclos.close()

    cols = [
        'exp_id', 'param', 'N_t_min', 'N_i_min', 'N_p_min', 'N_i_perc',
        'N_p_perc', 'a_inic(mm)'
    ]
    values = [
        exp_id, par, N_t_min, N_i_min, N_p_min,
        str(float(N_i_min) / N_t_min * 100) + "%",
        str(float(N_p_min) / N_t_min * 100) + "%", a_inic
    ]

    result_dict = dict(zip(cols, values))
    if os.path.isfile(main_path + "/resultados_generales/resultados.xlsx"):
        df = pd.read_excel(main_path + "/resultados_generales/resultados.xlsx")
        if len(df[df["exp_id"] == exp_id][df["param"] == par]) > 0:
            df = df.drop(
                df[df["exp_id"] == exp_id][df["param"] == par].index[0])

        df = df.append(result_dict, ignore_index=True)

    else:
        df = pd.DataFrame([result_dict])

    df.to_excel(main_path + "/resultados_generales/resultados.xlsx",
                index=False)

    print('Longitud de iniciación de la grieta: {} mm'.format(a_inic))
    print('Numero de ciclos hasta el fallo: {}\n'.format(N_t_min))

    return a_inic, v_ai_mm, N_t_min, N_t, N_p, N_i, N_a
Example #3
0
def principal(par, W, MAT, ac, trat, exp_max, exp_min):
    """Estima la vida a fatiga.
    
    INPUTS:  par     = parametro para el modelo de iniciacion
             W       = (m) anchura del especimen        
             MAT     = indice asignado al material
             ac      = propagacion plana o eliptica
             trat    = tratamiento superficial
             exp_max = nombre del archivo con la tensiones y defs maximas
             exp_min = nombre del archivo con la tensiones y defs minimas
            
    OUTPUTS: resultados.dat = actualiza el archivo de resultados con la
             longitud de iniciacion y los ciclos de iniciacion, propagacion y 
             total para que se produzca el fallo
             a_inic         = longitud de grieta de iniciación
             v_ai_mm        = vector de longitudes de grietas en mm 
             N_t_min        = Ciclos de iniciación
             N_t            = Vector de ciclos totales
             N_p            = Vector de ciclos de propagación   
             N_i            = Vector de ciclos de iniciación
             N_a            = Vector de ciclos de propagación a partir de la iniciación
             exp_id.dat     = archivo con los datos de las curvas de vida"""

    print('Datos Experimentales:\n    {}.dat\n    {}.dat\n'.format(
        exp_max, exp_min))
    #exp_id obtiene a partir del nombre del archivo con los datos un
    #identificador del experimento. Dependiendo del nombre del archivo debe
    #modificarse.
    pattern = r"\d+_\d+_\d+"
    exp_id = re.search(pattern, exp_max).group()

    #Obtenemos las rutas a las carpetas necesarias para los calculos
    cwd = os.getcwd()
    ruta_exp = cwd + '/datos_experimentales/{}'.format(trat)
    ruta_curvas = cwd + '/curvas_inic/{}'.format(ac)
    ruta_datos = cwd + '/resultados/{}/datos/{}'.format(trat, par)

    #Cargamos los datos de las curvas de iniciación del material
    data_interp = np.loadtxt("{}/MAT_{}.dat".format(ruta_curvas, par))

    #Separamos las curvas en las variables necesarias
    x_interp = data_interp[0, 1:]  #Eje x de la matriz de interpolación
    y_interp = data_interp[1:, 0]  #Eje y de la matriz de interpolación
    m_N_i = data_interp[1:, 1:]  #Matriz con los ciclos de iniciación

    #Creamos la función de interpolación
    function_interp = interp2d(x_interp,
                               y_interp,
                               m_N_i,
                               kind='quintic',
                               bounds_error=False)

    #Cargamos los datos experimentales y generamos el vector de FS o SWT
    x, sxx_max, s_max, e_max, e_min = lectura_datos(ruta_exp, exp_max, exp_min)
    param = parametro(par, MAT, x, s_max, e_max, e_min)

    a_i_min = round(x[1], 8)  #Tamaño mínimo de longitud de grieta de
    #iniciacion. Redondeamos para evitar errores
    #numericos.
    a_i_max = round(x[-1],
                    8)  #Tamaño máximo de longitud de grieta de iniciacion
    da = a_i_min  #Paso entre longitudes de grietas

    #Creamos el vector de longitudes de grieta de iniciacion

    v_ai = np.arange(a_i_min, a_i_max,
                     da)  #Vector de longitudes de grieta en m
    v_ai_mm = v_ai * 1e3  #Vector de longitudes de grieta en mm

    #Calculamos los ciclos de iniciación, de propagación y totales para cada
    #longitud de grieta de iniciacion
    #Inicializamos los ciclos
    N_i = np.zeros_like(v_ai)
    N_p = np.zeros_like(v_ai)
    N_t = np.zeros_like(v_ai)

    for i, a in enumerate(v_ai):
        ind_a = indice_a(a, x)  #Indice asociado a esa longitud de grieta
        param_med = np.mean(
            param[:ind_a +
                  1])  #Valor medio del parametro para la interpolacion

        #Realizamos la interpolacion para calcular los ciclos de iniciacion
        N_i[i] = function_interp(a, param_med)[0]

        #La interpolacion puede dar valores menores que 0 para ciclos muy bajos
        if N_i[i] < 0:
            N_i[i] = 0

        #Calculamos los ciclos de propagacion
        N_p[i] = fase_propagacion(sxx_max, ind_a, a, ac, da, W, MAT)

        #Ciclos totales
        N_t[i] = N_i[i] + N_p[i]

    #Calculamos el numero de ciclos hasta el fallo y la longitud de iniciación
    #de la grieta, que se producen en el mínimo de la curva de ciclos totales
    N_t_min = np.min(N_t)
    i_N_t_min = np.argmin(N_t)
    N_i_min = N_i[i_N_t_min]
    N_p_min = N_p[i_N_t_min]
    a_inic = v_ai_mm[i_N_t_min]

    #Pintamos la figura con la evolucion de la longitud de grieta y guardamos
    #en un archivo los datos
    ciclos = open(ruta_datos + '/{}.dat'.format(exp_id), 'w')
    ciclos.write('{:<5}\t{:<12}\t{:<12}\t{:<12}\t{:<12}'.format(
        'a_i', 'N_t', 'N_i', 'N_p', 'N_a'))

    N_a = []  #Vector de ciclos con la evolución de la grieta

    for i, ai in enumerate(v_ai):
        #Hasta la longitud de iniciacion crece como los ciclos de iniciacion
        if ai <= a_inic * 1e-3:
            n_a = N_i[i]
            N_a.append(n_a)
        #A partir de la longitud de iniciacion crece de acuerdo con los ciclos
        #de propagacion
        else:
            n_a = N_a[-1] + N_p[i - 1] - N_p[i]
            N_a.append(n_a)
        n_i = N_i[i]
        n_p = N_p[i]

        ciclos.write('\n{:.3f}\t{:.6e}\t{:.6e}\t{:.6e}\t{:.6e}'.format(
            ai * 1e3, n_i + n_p, n_i, n_p, n_a))
    ciclos.close()

    lines = np.loadtxt('resultados_generales/resultados_{}.dat'.format(trat),
                       dtype=str,
                       skiprows=1).tolist()
    # Se reescriben las lineas que ya estaban en el archivo. EL if else es debido
    # a que el formato de lines varía según haya una línea de resultados escrita
    # o mas de una.

    results = open('resultados_generales/resultados_{}.dat'.format(trat), 'w')
    results.write(
        '{:<13}\t{:<}\t{:<12}\t{:<12}\t{:<12}\t{:<5}\t{:<5}\t{:<}'.format(
            'exp_id', 'param', 'N_t_min', 'N_i_min', 'N_p_min', '% N_i',
            '% N_p', 'a_inic (mm)'))

    if len(lines[0][0]) == 1:
        #Solo se escriben los resultados que no pertenezcan al calculo actual
        if lines[0] != exp_id or lines[1] != par:
            results.write('\n')
            for j in i:
                results.write('{}\t'.format(j))
    else:
        for i in lines:
            #Solo se escriben los resultados que no pertenezcan al calculo actual
            if i[0] != exp_id or i[1] != par:
                results.write('\n')
                for j in i:
                    results.write('{}\t'.format(j))

    #Se escribe en el archivo el calculo actual
    results.write(
        '\n{}\t{}\t{:.6e}\t{:.6e}\t{:.6e}\t{:.1%}\t{:.1%}\t{:.3f}'.format(
            exp_id, par, N_t_min, N_i_min, N_p_min,
            float(N_i_min) / N_t_min,
            float(N_p_min) / N_t_min, a_inic))
    results.close()

    print('Longitud de iniciación de la grieta: {} mm'.format(a_inic))
    print('Numero de ciclos hasta el fallo: {}\n'.format(N_t_min))

    return a_inic, v_ai_mm, N_t_min, N_t, N_p, N_i, N_a
Example #4
0
def principal(par, W, MAT, exp_max, exp_min):
    """Estima la vida a fatiga.
    
    INPUTS:  par     = parametro para el modelo de iniciacion
             W       = (m) anchura del especimen        
             MAT     = indice asignado al material
             exp_max = nombre del archivo con la tensiones y defs maximas
             exp_min = nombre del archivo con la tensiones y defs minimas
            
    OUTPUTS: resultados.dat = actualiza el archivo de resultados con la
             longitud de iniciacion y los ciclos de iniciacion, propagacion y 
             total para que se produzca el fallo
             exp_id.dat     = archivo con los datos de las curvas de vida"""

    print('Datos Experimentales:\n    {}.dat\n    {}.dat\n'.format(
        exp_max, exp_min))
    #exp_id obtiene a partir del nombre del archivo con los datos un
    #identificador del experimento. Dependiendo del nombre del archivo debe
    #modificarse.
    exp_id = exp_max[16:]

    #Obtenemos las rutas a las carpetas necesarias para los calculos
    cwd = os.getcwd()
    ruta_exp = cwd + '/datos_exp'
    ruta_curvas = cwd + '/curvas_inic'
    ruta_fig = cwd + '/resultados/grafs/' + par
    ruta_datos = cwd + '/resultados/datos/' + par

    #Cargamos los datos de las curvas de iniciación del material
    data_interp = np.loadtxt("{}/MAT{}_{}.dat".format(ruta_curvas, MAT, par))

    #Separamos las curvas en las variables necesarias
    x_interp = data_interp[0, 1:]  #Eje x de la matriz de interpolación
    y_interp = data_interp[1:, 0]  #Eje y de la matriz de interpolación
    m_N_i = data_interp[1:, 1:]  #Matriz con los ciclos de iniciación

    #Creamos la función de interpolación
    function_interp = interp2d(x_interp,
                               y_interp,
                               m_N_i,
                               kind='quintic',
                               bounds_error=False)

    #Cargamos los datos experimentales y generamos el vector de FS o SWT
    x, sxx_max, s_max, e_max, e_min = lectura_datos(ruta_exp, exp_max, exp_min)
    param = parametro(par, MAT, x, s_max, e_max, e_min)

    a_i_min = round(x[1], 8)  #Tamaño mínimo de longitud de grieta de
    #iniciacion. Redondeamos para evitar errores
    #numericos.
    a_i_max = round(x[-1],
                    8)  #Tamaño máximo de longitud de grieta de iniciacion
    da = a_i_min  #Paso entre longitudes de grietas

    #Creamos el vector de longitudes de grieta de iniciacion

    v_ai = np.arange(a_i_min, a_i_max,
                     da)  #Vector de longitudes de grieta en m
    v_ai_mm = v_ai * 1e3  #Vector de longitudes de grieta en mm

    #Calculamos los ciclos de iniciación, de propagación y totales para cada
    #longitud de grieta de iniciacion
    #Inicializamos los ciclos
    N_i = np.zeros_like(v_ai)
    N_p = np.zeros_like(v_ai)
    N_t = np.zeros_like(v_ai)

    for i, a in enumerate(v_ai):
        ind_a = indice_a(a, x)  #Indice asociado a esa longitud de grieta
        param_med = np.mean(
            param[:ind_a +
                  1])  #Valor medio del parametro para la interpolacion

        #Realizamos la interpolacion para calcular los ciclos de iniciacion
        N_i[i] = function_interp(a, param_med)[0]

        #La interpolacion puede dar valores menores que 0 para ciclos muy bajos
        if N_i[i] < 0:
            N_i[i] = 0

        #Calculamos los ciclos de propagacion
        N_p[i] = fase_propagacion(sxx_max, ind_a, a, da, W, MAT)

        #Ciclos totales
        N_t[i] = N_i[i] + N_p[i]

    #Pintamos los curvas de iniciación, de propagación y totales
    plt.close(exp_id + '_' + par)
    plt.figure(exp_id + '_' + par)
    plt.yscale('log')
    plt.xlabel('Longitud de iniciacion (mm)')
    plt.ylabel('Ciclos')
    plot_inic = []
    plot_prop = []
    plot_tot = []
    plot_inic += plt.plot(v_ai_mm, N_i, 'b')
    plot_prop += plt.plot(v_ai_mm, N_p, 'k')
    plot_tot += plt.plot(v_ai_mm, N_t, 'r')

    #Calculamos el numero de ciclos hasta el fallo y la longitud de iniciación
    #de la grieta, que se producen en el mínimo de la curva de ciclos totales
    N_t_min = np.min(N_t)
    i_N_t_min = np.argmin(N_t)
    N_i_min = N_i[i_N_t_min]
    N_p_min = N_p[i_N_t_min]
    a_inic = v_ai_mm[i_N_t_min]

    #Pintamos el punto donde se da el minimo
    plt.plot(a_inic, N_t_min, 'ro')
    plt.ylim([1e3, 1e8])
    plt.xlim([0.0, a_i_max * 1e3])
    plt.legend([plot_inic[0], plot_prop[0], plot_tot[0]],
               ['Vida de iniciacion', 'Vida de propagacion', 'Vida total'],
               loc=0)
    plt.show()
    #Guardamos la figura y la cerramos
    plt.savefig(ruta_fig + '/{}.png'.format(exp_id))
    plt.close(exp_id + '_' + par)

    #Pintamos la figura con la evolucion de la longitud de grieta y guardamos
    #en un archivo los datos
    ciclos = open(ruta_datos + '/{}.dat'.format(exp_id), 'w')
    ciclos.write('{:<5}\t{:<12}\t{:<12}\t{:<12}\t{:<12}'.format(
        'a_i', 'N_t', 'N_i', 'N_p', 'N_a'))

    N_a = []  #Vector de ciclos con la evolución de la grieta

    for i, ai in enumerate(v_ai):
        #Hasta la longitud de iniciacion crece como los ciclos de iniciacion
        if ai <= a_inic * 1e-3:
            n_a = N_i[i]
            N_a.append(n_a)
        #A partir de la longitud de iniciacion crece de acuerdo con los ciclos
        #de propagacion
        else:
            n_a = N_a[-1] + N_p[i - 1] - N_p[i]
            N_a.append(n_a)
        n_i = N_i[i]
        n_p = N_p[i]

        ciclos.write('\n{:.3f}\t{:.6e}\t{:.6e}\t{:.6e}\t{:.6e}'.format(
            i * 1e3, n_i + n_p, n_i, n_p, n_a))
    ciclos.close()

    plt.figure('Longitud de grieta')
    plt.xscale('log')
    plt.xlabel('Ciclos')
    plt.ylabel('Longitud de grieta (mm)')
    plt.plot(N_a, v_ai_mm, 'k')
    plt.xlim([5e2, 1e8])
    plt.show()

    #represantamos la matriz de ciclos a través de un countour plot
    XX, YY = np.meshgrid(x_interp, y_interp)  # malla de la matriz
    breaks = np.logspace(1, 10, 10)  #intervalos de los niveles

    fig, ax = plt.subplots()
    cs = ax.contourf(XX, YY, m_N_i, breaks, locator=ticker.LogLocator())
    fig.colorbar(cs, ticks=breaks)
    plt.show()
    #Generamos/actualizamos el archivo con los resultados para la estimacion
    lines = np.loadtxt('resultados.dat', dtype=str, skiprows=1).tolist()

    results = open('resultados.dat', 'w')
    results.write(
        '{:<13}\t{:<}\t{:<12}\t{:<12}\t{:<12}\t{:<5}\t{:<5}\t{:<}'.format(
            'exp_id', 'param', 'N_t_min', 'N_i_min', 'N_p_min', '% N_i',
            '% N_p', 'a_inic (mm)'))

    #Se reescriben las lineas que ya estaban en el archivo. EL if else es debido
    #a que el formato de lines varía según haya una línea de resultados escrita
    #o mas de una.
    if len(lines[0][0]) == 1:
        #Solo se escriben los resultados que no pertenezcan al calculo actual
        if lines[0] != exp_id or lines[1] != par:
            results.write('\n')
            for j in i:
                results.write('{}\t'.format(j))
    else:
        for i in lines:
            #Solo se escriben los resultados que no pertenezcan al calculo actual
            if i[0] != exp_id or i[1] != par:
                results.write('\n')
                for j in i:
                    results.write('{}\t'.format(j))

    #Se escribe en el archivo el calculo actual
    results.write(
        '\n{}\t{}\t{:.6e}\t{:.6e}\t{:.6e}\t{:.1%}\t{:.1%}\t{:.3f}'.format(
            exp_id, par, N_t_min, N_i_min, N_p_min,
            float(N_i_min) / N_t_min,
            float(N_p_min) / N_t_min, a_inic))
    results.close()

    print('Longitud de iniciación de la grieta: {} mm'.format(a_inic))
    print('Numero de ciclos hasta el fallo: {}\n'.format(N_t_min))