scipy 用Carreau-Yasuda模型拟合流变数据

nhhxz33t  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(229)

我试图将一些流变学数据拟合到一个模型中。使用粘度和剪切速率的数组,我想将其拟合到Carreau模型中,但scipy中的curve_fit函数并没有给我特别好的值(我已经绘制了我之后收到的数据,它只遵循了大约一半的数据)。下面是代码:

  1. import numpy as np
  2. import pandas as pd
  3. import matplotlib.pyplot as plt
  4. import scipy
  5. from scipy.optimize import curve_fit
  6. from scipy.odr import ODR, Model, Data, RealData
  7. import seaborn as sns
  8. sns.set(style="whitegrid")
  9. df = pd.read_excel('Biomass.xls', sheet_name=1,)
  10. data_array = df.to_numpy()
  11. data_array_numbers = np.delete(data_array, 0, 0)
  12. data_array_numbers = np.delete(data_array_numbers, 0, 0)
  13. transposed_array = data_array_numbers.transpose()
  14. sorted_array = transposed_array[:, np.argsort( transposed_array[1])]
  15. shear_rate = np.array(sorted_array[1])
  16. viscosity = np.array(sorted_array[2])
  17. density=1000
  18. for i in range(0, len(viscosity)):
  19. viscosity[i] = viscosity[i]/density
  20. log_shear = np.zeros(shape=(len(shear_rate)))
  21. log_viscosity = np.zeros(shape=(len(shear_rate)))
  22. log_shear[i] = np.log(shear_rate[i])
  23. log_viscosity[i] = np.log(viscosity[i])
  24. def log_powerlaw(x, log_k, n_p):
  25. nu = log_k + n_p*x
  26. return nu
  27. def powerlaw(x, k, n):
  28. return k*(x)**(n-1)
  29. def carreau(x, n_inf, n_0, lamda, a, n):
  30. return n_inf + (n_0-n_inf)*(1+(x*lamda)**a)**((n-1)/a)
  31. params, covariance = curve_fit(carreau, xdata=shear_rate, ydata=viscosity, maxfev=200000, method='trf')
  32. n_inf_fit, n_0_fit, lambda_fit, a_fit, n_fit = params
  33. print(n_inf_fit)
  34. print(n_0_fit)
  35. print(lambda_fit)
  36. print(a_fit)
  37. print(n_fit)
  38. ax = plt.axes()
  39. plt.scatter(shear_rate, viscosity, c='g', marker='x')
  40. plt.plot(shear_rate, carreau(shear_rate, n_inf_fit, n_0_fit, lambda_fit, a_fit, n_fit ), c='b')
  41. #plt.plot(shear_rate, powerlaw(shear_rate, k=params[0], n=params[1]) )
  42. ax.set_title("Biomass Rheology")
  43. ax.set_ylabel('Viscosity')
  44. ax.set_xlabel('Shear Rate')
  45. plt.yscale('log')
  46. plt.show()

字符串
我试着想一种方法来线性化这个问题,就像我对幂律拟合所做的那样(用对数来使它成为一个直线方程),试着给出不同的初始猜测。我希望有一个很好的近似值,因为模型有5个参数。

3ks5zfa0

3ks5zfa01#

TL;DR

可以为这样的模型拟合参数,但它需要一些帮助,例如初始猜测或约束(至少对粘度常数的粗略估计)。

MCVE

让我们生成一些数据:

  1. import numpy as np
  2. from scipy import optimize
  3. def model(x, n_0, n_inf, lamda, a, n):
  4. return n_inf + (n_0 - n_inf) * np.power((1 + np.power((x[:, 0] * lamda), a)), ((n - 1) / a))
  5. np.random.seed(12345)
  6. parameters = (4e-2, 5e-4, 1.6, 2.1, 0.3)
  7. X = np.logspace(-4, 4, 30, base=10).reshape(-1, 1)
  8. y = model(X, *parameters)
  9. sigma = 1e-6 * np.ones(y.size)
  10. y += sigma * np.random.normal(size=y.size)

字符串
然后我们有两个选择:使用LM算法,并对耦合常数(至少是幅度)提供一点帮助。

  1. popt, pcov = optimize.curve_fit(
  2. model, X, y, sigma=sigma, absolute_sigma=True,
  3. p0=(1e-2, 1e-4, 1, 1, 1)
  4. )
  5. # array([3.99998407e-02, 4.99859627e-04, 1.59989329e+00, 2.10012984e+00, 2.99977836e-01]


或者在问题上增加限制。

  1. popt, pcov = optimize.curve_fit(
  2. model, X, y, sigma=sigma, absolute_sigma=True,
  3. method="trf", bounds=[(1e-3, 1e-5, 0, 0, 0), (1e-1, 1e-3, 10, 3, 1)]
  4. )
  5. # array([3.99998407e-02, 4.99859627e-04, 1.59989329e+00, 2.10012983e+00, 2.99977836e-01]


这两个方法返回的初始参数具有相当好的一致性。
100d 1xx 1c 1d 1x的字符串

展开查看全部

相关问题