Пример #1
0
 def predict(self, c_p, m_p, method='tanaka'):
     # usage:完成预测过程,输出SIF变幅、FCGR、循环次数、有效性判定
     # NOTE:参数全部引用自函数外部,不适合从其它文件调用
     # input parameter:
     # load:实验施加的载荷峰值,应当为1个数,可从外部的数组中取一个调用
     # return parameter:
     # cracklength:给定的裂纹长度,mm
     # dk_predict:计算的SIF变幅,Mpa.m0.5
     # dadn:估计的FCGR,mm/cycles
     # valid:有效性判断结果
     _ = self.evaluate_sif_range_k1()
     _ = self.evaluate_sif_range_k2()
     _ = self.calculate_sif_range_eff(method=method)
     self.fcg_rate = mts_analysis.ParisCalculating(c=c_p,
                                                   m=m_p,
                                                   dk=self.sif_range_eff)
     self.cycle = experiment_predict.CycleIntegrateBySimpson(
         c=c_p, m=m_p, dk=self.sif_range_eff, cracklength=self.cracklength)
     for seq, value in enumerate(self.cracklength):
         self.valid.append(
             mts_analysis.LigamentValidCheck(w=self.width,
                                             a=value,
                                             dk=self.sif_range_eff[seq],
                                             ys=self.yieldstrength,
                                             r=self.stressratio))
     return self.cracklength, self.sif_range_eff, self.fcg_rate, self.cycle, self.valid
Пример #2
0
def AlphaCalculate(fade_rate,
                   amplitude,
                   dadn,
                   dk,
                   kc,
                   a,
                   a_range,
                   a_amplitude,
                   stress_ratio,
                   numofaverage=7,
                   error_ratio=0.2):
    # 放弃
    # 移动平均
    kc_Manual_averaged2, dk_Manual_averaged2 = \
        DoubleDataSelectMovingAverage(data=kc, reference=dk,
                                      ratio=error_ratio, numofaverage=numofaverage)
    _, a_Manual_averaged2 = \
        DoubleDataSelectMovingAverage(data=kc, reference=a,
                                      ratio=error_ratio, numofaverage=numofaverage)
    _, dadn_Manual_averaged2 = \
        DoubleDataSelectMovingAverage(data=kc, reference=dadn,
                                      ratio=error_ratio, numofaverage=numofaverage)
    # 数据筛选a_range
    dadn_selecting_average2, dk_selecting_averaged2, kc_selecting_averaged2, a_selecting_averaged2 = \
        mts_analysis.FCGDataSelectByThreshold(dadn=dadn_Manual_averaged2, dk=dk_Manual_averaged2,
                                              n=kc_Manual_averaged2, a=a_Manual_averaged2,
                                              threshold=a_range[0], target='a', keepbigger=1)
    dadn_selected_averaged2, dk_selected_averaged2, kc_selected_averaged2, a_selected_averaged2 = \
        mts_analysis.FCGDataSelectByThreshold(dadn=dadn_selecting_average2, dk=dk_selecting_averaged2,
                                              n=kc_selecting_averaged2, a=a_selecting_averaged2,
                                              threshold=a_range[1], target='a', keepbigger=0)
    # 拟合数据准备
    kmin_selected_averaged2 = dk_selected_averaged2 * (
        stress_ratio / (1 - stress_ratio))  # Kmin计算
    kmax_selected_averaged2 = dk_selected_averaged2 * (1 / (1 - stress_ratio)
                                                       )  # Kmax计算
    c_p, m_p = paris_and_walker.ParisParameter(r=stress_ratio)  # Paris参数读取
    betas = (a_selected_averaged2 - a_amplitude) / a_amplitude  # 裂纹长度无量纲量
    # 计算参数alpha
    alpha_e = []
    for beta in betas:
        if beta < 0:
            alpha_e.append(2 / np.pi)
        else:
            alpha_e.append(amplitude * np.exp(-fade_rate * beta))
    alpha_e = np.array(alpha_e)
    # 基于参数计算有效应力强度因子
    dkeff_alpha_e = kmax_selected_averaged2 - alpha_e * kc_selected_averaged2 - (
        1 - alpha_e) * kmin_selected_averaged2
    # 计算dadn
    dadn_alpha_e = mts_analysis.ParisCalculating(c=c_p,
                                                 m=m_p,
                                                 dk=dkeff_alpha_e)
    return dk_selected_averaged2, dkeff_alpha_e, dadn_alpha_e, alpha_e, betas, a_selected_averaged2
Пример #3
0
 def evaluate_fcg_rate_by_paris(self, c_p, m_p):
     self.fcg_rate = mts_analysis.ParisCalculating(c=c_p,
                                                   m=m_p,
                                                   dk=self.sif_range_eff)
     return self.fcg_rate
'''
数据读取处理
'''
specimen_data = []
for sequence in sequences:
    specimen_data.append(
        mts_class.SpecimenBasic(name=sequence, stress_ratio=r,
                                threshold=0))  # 创建实例

for specimen in specimen_data:
    specimen.read_experimental_data()  # 读取和计算
'''
Paris拟合和Walker模型效果对比
'''
dadn_paris_Manual = mts_analysis.ParisCalculating(c=c_p,
                                                  m=m_p,
                                                  dk=np.array(
                                                      specimen.dk_Manual))
'''
数据保存
'''
if filesave:
    for specimen in specimen_data:
        data = np.array([
            specimen.n_Manual, specimen.a_Manual, specimen.dk_Manual,
            specimen.dadn_Manual, specimen.kc_Manual
        ])
        name = [
            "Original_Cycles", "Original_CrackLength/mm",
            "Original_SIFRange/MPam0.5", "Original_FCGRate/mm per cycle",
            "Original_ClosureSIF/MPam0.5"
        ]
Пример #5
0
# dkeff计算
dkeff_Manual_2pi = closureanalysis.dKeffCalculation(kmax=dk_Manual / (1 - r),
                                                    kclose=kc_Manual,
                                                    kmin=dk_Manual * (r /
                                                                      (1 - r)),
                                                    method='2/PI')
# 移动平均
dkeff_Manual_averaged0, dk_Manual_averaged0 = \
    closureanalysis.DoubleDataSelectMovingAverage(data=dkeff_Manual_2pi, reference=dk_Manual,
                                                  ratio=ratio, numofaverage=numofaverage)
_, a_Manual_averaged0 = \
    closureanalysis.DoubleDataSelectMovingAverage(data=dkeff_Manual_2pi, reference=a_Manual,
                                                  ratio=ratio, numofaverage=numofaverage)
# 计算基于裂纹闭合效应的dadn(2/PI法)
dadn_paris_dkeff_2pi = mts_analysis.ParisCalculating(c=c_p,
                                                     m=m_p,
                                                     dk=dkeff_Manual_averaged0)
'''
传统dkeff法(basic)
'''
# dkeff计算
dkeff_Manual_bac = closureanalysis.dKeffCalculation(kmax=dk_Manual / (1 - r),
                                                    kclose=kc_Manual,
                                                    kmin=dk_Manual * (r /
                                                                      (1 - r)),
                                                    method='basic')
# 移动平均
dkeff_Manual_averaged1, dk_Manual_averaged1 = \
    closureanalysis.DoubleDataSelectMovingAverage(data=dkeff_Manual_bac, reference=dk_Manual,
                                                  ratio=ratio, numofaverage=numofaverage)
_, a_Manual_averaged1 = \
Пример #6
0
def AlphaModifiedCalculate(alpha_fade_rate, alpha_amplitude, pmax,
                           stress_ratio, thickness, width, a_amplitude, a_list,
                           c_ca, m_ca, a_start, a_end, dadn_start):
    # Modified Alpha模型计算函数
    # 该函数通过由已知起点(通常为a_kc_max_cal)和终点(通常为a_retard_end)的裂纹长度值和裂纹扩展速率
    # 采用直线拟合得到Kop的值,代入已知的Alpha模型参数值计算
    # 得到该段裂纹闭合效应主导的裂纹扩展速率模型
    # input parameters:
    # alpha_fade_rate: 模型衰减率参数
    # alpha_amplitude: 模型峰值参数,常取2/pi
    # pmax, stress_ratio: 载荷峰值,应力比
    # thickness, width: CT试件几何参数厚度和宽度
    # a_amplitude: 模型起点a0
    # a_list:要计算的裂纹长度值的数组
    # c_ca, m_ca:该应力比下的Paris公式参数
    # a_start, a_end: 要输出的裂纹长度起止点
    # dadn_start: 输入a0对应的dadn速率,通过反转Paris公式计算其dkeff
    # return parameters:
    # dk: 输入的a_list计算对应的dk
    # dkeff_alpha_e: 输入的a_list对应的alpha模型下的dkeff
    # dadn_alpha_e: 输入的a_list由alpha模型计算得到的dadn
    # alpha_e: a_list各值对应的alpha值
    # betas:a_list各值对应的无量纲裂纹长度参数值
    kmax = mts_analysis.DeltaKCalculating(b=thickness,
                                          w=width,
                                          a=a_list,
                                          pmax=pmax,
                                          pmin=0)
    kmin = mts_analysis.DeltaKCalculating(b=thickness,
                                          w=width,
                                          a=a_list,
                                          pmax=pmax * stress_ratio,
                                          pmin=0)
    dk = kmax - kmin
    # 计算无量纲量
    betas = (a_list - a_amplitude) / a_amplitude
    # 计算系数alpha
    alpha_e = []
    for beta in betas:
        if beta < 0:
            alpha_e.append(2 / np.pi)
        else:
            alpha_e.append(alpha_amplitude * np.exp(-alpha_fade_rate * beta))
    alpha_e = np.array(alpha_e)
    # 计算Kop
    dk_start = mts_analysis.DeltaKCalculating(b=thickness,
                                              w=width,
                                              a=a_start,
                                              pmax=pmax,
                                              pmin=pmax * stress_ratio)
    dk_end = mts_analysis.DeltaKCalculating(b=thickness,
                                            w=width,
                                            a=a_end,
                                            pmax=pmax,
                                            pmin=pmax * stress_ratio)
    dkeff_start = mts_analysis.ParisInverseCalculation(c=c_ca,
                                                       m=m_ca,
                                                       dadn=dadn_start)
    print("The Effective SIF when beta=0:" + str(dkeff_start))
    pi = np.pi
    kop_start = pi / 2 * (dk_start / (1 - stress_ratio) - dkeff_start -
                          (1 - 2 / pi) * dk_start * stress_ratio /
                          (1 - stress_ratio))
    print("The Open SIF when beta=0 based on Alpha Method:" + str(kop_start))
    kop_end = dk_end * (stress_ratio / (1 - stress_ratio))
    dk_fit = [dk_start[0], dk_end]
    kop_fit = [kop_start[0], kop_end]
    k_kopfit_cal, b_kopfit_cal = mixed_model.LogLinearFit(y=kop_fit, x=dk_fit)
    kop_cal = mixed_model.LogLinearFittedCalculate(k=k_kopfit_cal,
                                                   b=b_kopfit_cal,
                                                   x=dk)

    # 计算dKeff
    dkeff_alpha_e = kmax - alpha_e * kop_cal - (1 - alpha_e) * kmin
    # 计算dadn
    dadn_alpha_e = mts_analysis.ParisCalculating(c=c_ca,
                                                 m=m_ca,
                                                 dk=dkeff_alpha_e)

    return dk, dkeff_alpha_e, dadn_alpha_e, alpha_e, betas
Пример #7
0
def Alpha2(sequence,
           stress_ratio,
           error_ratio,
           numofaverage,
           a_range,
           amplitude=0,
           fade_rate=0,
           fitting=0,
           model='paris'):
    # usage: 采用提出的Alpha方法先拟合出幅度系数M,再根据其计算dadn结果
    # input parameter:
    # sequence: 试件名(与MTS中一致,将直接读取文件)
    # stress_ratio:实验应力比
    # error_ratio:进行数据筛选的误差带半宽度,详细注释见函数DoubleDataSelectMovingAverage
    # numofaverage:进行移动平均的数据个数,详细注释见函数DoubleDataSelectMovingAverage
    # a_range:拟合的数据范围,格式为数组[a_begin, a_end],a_begin推荐为dkeff_basic的谷值或dadn的谷值,
    # a_end要注意截止在数据开始离散之前
    # fade_rate:幂函数中的指数系数,直接指定,常见[5,8]
    # amplitude: 幂函数中的幅度系数,可定2/pi
    # 注:函数自动将对输入为0的项先拟合参数再进行计算,若均不为零则直接计算不进行拟合
    # fitting: 若fitting为1,则输出拟合时对标的dkeff_experiment值,以用于计算lost
    # model: 设定计算过程中采用的model,默认采用paris,可选walker
    # return parameter:
    # Ce1: 计算得到的幅度系数
    # dk_selected_averaged2, dkeff_alpha_e, dadn_alpha_e:对应的裂纹扩展参数
    # alpha_e:对应的参数alpha

    # 数据读入
    dadn_Manual, n_Manual, dk_Manual, a_Manual, kc_Manual = \
        BasicDataDispose(sequence=sequence, r=stress_ratio)
    if model == 'walker':
        c_w, m_w, gamma = paris_and_walker.WalkerParameter(data=1)
    else:
        c_p, m_p = paris_and_walker.ParisParameter(r=stress_ratio)

    # 移动平均
    kc_Manual_averaged2, dk_Manual_averaged2 = \
        DoubleDataSelectMovingAverage(data=kc_Manual, reference=dk_Manual,
                                      ratio=error_ratio, numofaverage=numofaverage)
    _, a_Manual_averaged2 = \
        DoubleDataSelectMovingAverage(data=kc_Manual, reference=a_Manual,
                                      ratio=error_ratio, numofaverage=numofaverage)
    _, dadn_Manual_averaged2 = \
        DoubleDataSelectMovingAverage(data=kc_Manual, reference=dadn_Manual,
                                      ratio=error_ratio, numofaverage=numofaverage)

    # 数据筛选a_range
    dadn_selecting_average2, dk_selecting_averaged2, kc_selecting_averaged2, a_selecting_averaged2 = \
        mts_analysis.FCGDataSelectByThreshold(dadn=dadn_Manual_averaged2, dk=dk_Manual_averaged2,
                                              n=kc_Manual_averaged2, a=a_Manual_averaged2,
                                              threshold=a_range[0], target='a', keepbigger=1)
    dadn_selected_averaged2, dk_selected_averaged2, kc_selected_averaged2, a_selected_averaged2 = \
        mts_analysis.FCGDataSelectByThreshold(dadn=dadn_selecting_average2, dk=dk_selecting_averaged2,
                                              n=kc_selecting_averaged2, a=a_selecting_averaged2,
                                              threshold=a_range[1], target='a', keepbigger=0)

    # 拟合数据准备
    kmin_selected_averaged2 = dk_selected_averaged2 * (
        stress_ratio / (1 - stress_ratio))  # Kmin计算
    kmax_selected_averaged2 = dk_selected_averaged2 * (1 / (1 - stress_ratio)
                                                       )  # Kmax计算
    if model == 'walker':
        dkeff_experiment_averaged2 = (
            (dadn_selected_averaged2 / c_w)**(1 / m_w)) / (
                (1 - stress_ratio)**(gamma - 1))
    else:
        dkeff_experiment_averaged2 = (dadn_selected_averaged2 / c_p)**(
            1 / m_p)  # 拟合时的真值dkeff,由Paris给出
    beta = (a_selected_averaged2 - a_range[0]) / a_range[0]  # 裂纹长度无量纲量

    # 拟合,得到幅度或衰减系数
    if fade_rate != 0 and amplitude == 0:

        def residual_alpha_e(p):
            Ce = p
            return dkeff_experiment_averaged2 - (
                kmax_selected_averaged2 -
                (Ce * np.exp(-fade_rate * beta)) * kc_selected_averaged2 -
                (1 -
                 (Ce * np.exp(-fade_rate * beta))) * kmin_selected_averaged2)

        k = opt.leastsq(residual_alpha_e, np.array([1]))
        Ce1 = k[0]
    elif amplitude != 0 and fade_rate == 0:

        def residual_alpha_e(p):
            n = p
            return dkeff_experiment_averaged2 - (
                kmax_selected_averaged2 -
                (amplitude * np.exp(-n * beta)) * kc_selected_averaged2 -
                (1 -
                 (amplitude * np.exp(-n * beta))) * kmin_selected_averaged2)

        k = opt.leastsq(residual_alpha_e, np.array([1]))
        fade_rate = k[0]
        Ce1 = amplitude

    elif amplitude != 0 and fade_rate != 0:
        Ce1 = amplitude
    elif amplitude == 0 and fade_rate == 0:

        def residual_alpha_e(p):
            Ce, n = p
            return dkeff_experiment_averaged2 - (
                kmax_selected_averaged2 -
                (Ce * np.exp(-n * beta)) * kc_selected_averaged2 -
                (1 - (Ce * np.exp(-n * beta))) * kmin_selected_averaged2)

        k = opt.leastsq(residual_alpha_e, np.array([1, 1]))
        Ce1, fade_rate = k[0]

    # 计算参数alpha
    alpha_e = Ce1 * np.exp(-fade_rate * beta)
    print("alpha幂函数拟合:试件名:", sequence, "幅度:", Ce1, "衰减速率:", fade_rate)

    # 计算dkeff_alpha和对应的dadn
    dkeff_alpha_e = kmax_selected_averaged2 - alpha_e * kc_selected_averaged2 - (
        1 - alpha_e) * kmin_selected_averaged2
    if model == 'walker':
        dadn_alpha_e = mts_analysis.WalkerCalculating(c0=c_w,
                                                      gamma=gamma,
                                                      m0=m_w,
                                                      r=stress_ratio,
                                                      dk=dkeff_alpha_e)
    else:
        dadn_alpha_e = mts_analysis.ParisCalculating(c=c_p,
                                                     m=m_p,
                                                     dk=dkeff_alpha_e)
    if fitting:
        return Ce1, fade_rate, dk_selected_averaged2, dkeff_alpha_e, dadn_alpha_e, alpha_e, dkeff_experiment_averaged2
    else:
        return Ce1, fade_rate, dk_selected_averaged2, dkeff_alpha_e, dadn_alpha_e, alpha_e
Пример #8
0
                                                  aol=specimen.a_ol_applied, rol=plz_ol, plasticzonefactor=plz_factor,
                                                  m1=m1_2, c=c_ca, m=m_ca, eta=0)
# 2/PI法:
# dkeff计算
dkeff_Manual_2pi = closureanalysis.dKeffCalculation(
    kmax=specimen.dk / (1 - specimen.stress_ratio),
    kclose=specimen.kc,
    kmin=specimen.dk * (specimen.stress_ratio / (1 - specimen.stress_ratio)),
    method='2/PI')
dkeff_2pi, dk_2pi = \
    closureanalysis.DoubleDataSelectMovingAverage(data=dkeff_Manual_2pi, reference=specimen.dk,
                                                  ratio=0.2, numofaverage=7)
_, a_2pi = \
    closureanalysis.DoubleDataSelectMovingAverage(data=dkeff_Manual_2pi, reference=specimen.a,
                                                  ratio=0.2, numofaverage=7)
dadn_2pi = mts_analysis.ParisCalculating(c=c_ca, m=m_ca, dk=dkeff_2pi)

# Try: mix try 1
# 采用logistic sigmoid函数分配两种
# logistic sigmoid单调递增,表征crack closure
sigmas = 1 / (1 + np.exp(-kappa * betas))
dadn_mixed_1 = dadn_wheeler * (1 - sigmas) + dadn_alpha_e * sigmas

# 绘图部分
# Plotting
plt.figure(num=1, figsize=(8, 6))
plt.scatter(specimen.dk, specimen.dadn, lw=1, marker='+', label='Experiment')
if moving_average:
    plt.scatter(dk_ave, dadn_ave, lw=1, marker='*', label='Moving average')
plt.plot(dk_wheeler2,
         dadn_wheeler2,
dadn_Manual2, n_Manual2, dk_Manual2, a_Manual2, _ = \
    closureanalysis.BasicDataDispose(sequence=sequence[1], r=stress_ratio[1])

dadn_Manual3, n_Manual3, dk_Manual3, a_Manual3, _ = \
    closureanalysis.BasicDataDispose(sequence=sequence[2], r=stress_ratio[2])

dadn_Manual4, n_Manual4, dk_Manual4, a_Manual4, _ = \
    closureanalysis.BasicDataDispose(sequence=sequence[3], r=stress_ratio[3])

dadn_Manual5, n_Manual5, dk_Manual5, a_Manual5, _ = \
    closureanalysis.BasicDataDispose(sequence=sequence[4], r=stress_ratio[4])

# CA曲线计算
dk_paris = np.linspace(15, 25, 9)
dadn_paris = mts_analysis.ParisCalculating(c=c_CA, m=m_CA, dk=dk_paris)

plt.figure(num=1, figsize=(10, 8))
plt.scatter(dk_Manual1, dadn_Manual1, lw=1, marker='+', label='CA')
plt.scatter(dk_Manual2, dadn_Manual2, lw=1, marker='*', label='OLR=1.5')
plt.scatter(dk_Manual3, dadn_Manual3, lw=1, marker='2', label='OLR=2.0')
#plt.scatter(dk_Manual4, dadn_Manual4, lw=1, marker='3', label='OLR=2.5')
#plt.scatter(dk_Manual5, dadn_Manual5, lw=1, marker='1', label='OLR=4.0')
plt.plot(dk_paris, dadn_paris, label='CA_Paris', color='black', linewidth=2)
plt.axis([
    min(dk_Manual1),
    max(dk_Manual1),
    min(dadn_Manual1),
    max(dadn_Manual1) * 1.2
])
plt.yticks(np.linspace(min(dadn_Manual3) * 0.5, max(dadn_Manual1), 6))
c_p, m_p = paris_and_walker.ParisParameter(r=r)

# 数据读取
dadn_Manual, n_Manual, dk_Manual, a_Manual, kc_Manual = closureanalysis.BasicDataDispose(sequence=sequence[0], r=r)
dkeff_Manual = closureanalysis.dKeffCalculation(kmax=dk_Manual/(1-r), kclose=kc_Manual, kmin=dk_Manual*(r/(1-r)),
                                                method='basic')

# moving average
numofaverage = 7
ratio = 0.5
dadn_Manual_averaged, dk_Manual_averaged = \
    closureanalysis.DoubleDataSelectMovingAverage(data=dadn_Manual, reference=dk_Manual,
                                                  ratio=ratio, numofaverage=numofaverage)

# 无高载Paris虚线
dadn_paris_Manual = mts_analysis.ParisCalculating(c=c_p, m=m_p, dk=dk_Manual)

# ploting
plt.figure(num=1, figsize=(10, 8))
plt.scatter(dk_Manual, dadn_Manual, label='$ExperimentData$', color='red', marker='.')
plt.scatter(dk_Manual_averaged, dadn_Manual_averaged, label='$MovingAverage$', color='blue', marker='.')
plt.plot(dk_Manual, dadn_paris_Manual, label='$Paris for CA$', color='black', linewidth=2)
plt.axis([min(dk_Manual) * 0.95, max(dk_Manual) * 1.05, min(dadn_Manual) * 0.95, max(dadn_Manual) * 1.05])
plt.xlabel("DeltaK Applied (MPa*m^0.5)")
plt.xscale('log')
plt.ylabel("da/dN (mm/cycle)")
plt.yscale('log')
plt.xticks(np.linspace(min(dk_Manual), max(dk_Manual), 6))
plt.title('da/dN - dK ' + sequence[0] + '(MTS Result)')
plt.legend()
plt.grid()