-1

I have the following dataset from a mechanical indentation test:

https://www.dropbox.com/s/jovjl55sjjyph3r/Test%20dataset.csv?dl=0

The graph shows the displacement of a spherical probe vs force recorded. I need to fit these data with specific equations (DMT model if you are familiar with it). I have produced the code below, but I am unable to get a good fitting result. The code gives no error or warnings, so I don't know if the problem is on the plotting or on the actually fitting.

Did I write the fitting code correctly? Did I pass the variables Fad and R correctly into the function? Is the code that plots the fitting curve correct?

Also, in the code you can notice 2 different fitting functions. Function1 is based on 2 equations:

a = ((R/K)*(x+Fad))^(1/3)

y = ((a^2)/R)

Function2 is the same as function1 but the 2 equations are combined in a single equation. The funny thing is that they give 2 different plots!

Importantly, I'd like to use the 2 equations method because there are other more complex models that I should use to fit the same dataset. In these models the equations cannot be combined that easily like in this case.

Any help from the Community to solve this problem would be very much appreciated.

import pandas
from matplotlib import pyplot as plt
from scipy import optimize
import numpy as np


df = pandas.read_table("Test dataset.csv", sep = ',', header=0)
df = df.astype(float) #Change data from object to float
print(df.shape)
print(df)

df_Fad = -(df.iloc[0, 0])
print("Adhesion force = {} N".format(df_Fad))
R = 280*1e-6
print("Probe radius = {} m".format(df_Fad))


df_x = df["Corr Force A [N]"].to_list()
df_y = df["Corr Displacement [m]"].to_list()


#Define fitting function1
def DMT(x, R, K, Fad):
    a = ((R/K)*(x+Fad))**(1/3)
    return ((a**2)/R)

custom_DMT = lambda x, K: DMT(x, R, K, df_Fad) #Fix Fad value
pars_DMT, cov_DMT = optimize.curve_fit(f=custom_DMT, xdata=df_x, ydata=df_y)
print("K = ", round(pars_DMT[0],2))
print ("E = ", round(pars_DMT[0]*(4/3),2))

ax0 = df.plot(kind='scatter', x="Corr Force A [N]", y="Corr Displacement [m]", color='lightblue')
plt.plot(df_x, DMT(np.array(df_y), pars_DMT[0], R, df_Fad), "--", color='black')
ax0.set_title("DMT fitting")
ax0.set_xlabel("Force / N")
ax0.set_ylabel("Displacement / m")
ax0.legend(['Dataset'])
plt.tight_layout()


#Define fitting function2 => function2 = funtion1 in one line
def DMT2(x, Fad, R, K):
    return ((x+Fad)**(2/3))/((R**(1/3))*(K**(2/3)))

custom_DMT2 = lambda x, K: DMT2(x, df_Fad, R, K) #Fix Fad value
pars_DMT2, cov_DMT2 = optimize.curve_fit(f=custom_DMT2, xdata=df_x, ydata=df_y)
print("K = ", round(pars_DMT2[0],2))
print ("E = ", round(pars_DMT2[0]*(4/3),2))

ax1 = df.plot(kind='scatter', x="Corr Force A [N]", y="Corr Displacement [m]", color='lightblue')
plt.plot( df_x, DMT2(np.array(df_y), pars_DMT2[0], df_Fad, R), "--", color='black')
ax1.set_title("DMT fitting")
ax1.set_xlabel("Force / N")
ax1.set_ylabel("Displacement / m")
ax1.legend(['Dataset'])
plt.tight_layout()

plt.show()
Pier
  • 133
  • 2
  • 10

1 Answers1

0

After further attempts and research I have solved the problem even though a doubt on a line of the code above still remains. I decided to post my solution here hoping that this could be helpful to others.

I could see that the code:

def DMT(x, R, K, Fad):
    a = ((R/K)*(x+Fad))**(1/3)
    return ((a**2)/R)

works well in fitting the experimental data, meaning that more equations can be easily used and combined in Python, which is great. It is important though that the variables (x, R, K, Fad) are introduced in the same order as they appear in the equations. Failing to do this gives random results.

The problem stays in the code line:

plt.plot(df_x, DMT(np.array(df_y), pars_DMT[0], R, df_Fad), "--", color='black')

Initially I thought that the order of the parameters (x, R, K, Fad) was wrong. I tried:

plt.plot(df_x, DMT(np.array(df_y), R, pars_DMT[0], df_Fad), "--", color='black')

but this didn't solve the problem. Anyone who can tell me what's wrong with this line?

Anyway, my way around this problem was to directly calculate the y data of the fitting line from the calculated parameter K (R and df_Fad are fixed) using the following code:

df["Fitting Displacement [m]"] = ((df["Corr Force A [N]"]+df_Fad)**(2/3))/((R**(1/3))*(pars_DMT[0]**(2/3)))

This was anyway a necessary step to do in order to save the fitting results.

Pier
  • 133
  • 2
  • 10