-
Notifications
You must be signed in to change notification settings - Fork 2
/
tingFC_constructor.py
166 lines (144 loc) · 7.21 KB
/
tingFC_constructor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# -*- coding: utf-8 -*-
"""
@author: Yuri Efremov
function tingFC_constructor takes parameters from ViscoIndent GUI and
construct force vs distance curve via ting_numerical function
most of the used parameters described in Ting_numerical.py
additional parameters:
Pars['indpars'] - constructor for indentation history
indpars[0]: [yes/no] 0 - use constructor, 1 - use provided indentation history
indpars[1]: maximum indentation depth [nm]
indpars[2]: indentation speed [nm/s]
indpars[3]: number of points in approach phase
indpars[4]: [ramp/sin] - 0 - ramp (triangular indentation profile), 1 - sinusoidal indentation profile
indpars[5]: add dwell phase [s]
Pars['noise'] noise level relative to median force [%] (random.normal)
Pars['hydrodrag'] coefficient of viscous drag of the probe [nN*s/nm]
"""
import numpy as np
from numpy import pi, tan, sin
import matplotlib.pyplot as plt
from Ting_numerical import ting_numerical
def tingFC_constructor(Pars, indentationfull):
probe_geom = Pars['probe_shape'] # probe shape
probe_size = Pars['probe_dimension'] # probe size
Poisson = Pars['Poisson'] # Poisson's ratio of the sample
dT = Pars['dT'] # Sampling time
viscomodel = Pars['viscomodel'] # relaxation function
Height = Pars['height'] # sample thickness
pars = Pars['Vpars'] # relaxation function parameters
noise = Pars['noise'] # % noise level from median force
hydrodrag = Pars['hydrodrag'] # [nN*s/nm] coefficient of viscous drag
adhesion_model = Pars['adhesion_model'] # none, DMT, JKR
adhesion_region = Pars['adhesion_region'] # 'approach' 'retraction' 'both'
adhesion = Pars['adhesion'] # max adhesion force
adhesion_pars = [adhesion_model, adhesion_region, -adhesion]
try:
indpars = Pars['indpars']
except:
indpars = 0 # if no indentation parameters were provided, the "indentationfull" is used
PointN = indentationfull.size
time = np.linspace(dT, dT*PointN, PointN)
time = time-dT
MaxInd = np.argmax(indentationfull)
Depth = indentationfull[MaxInd]
Speed = Depth/time[MaxInd]
# indpars: constructor for the indentation history
if indpars[0] == 1: # [yes/no; depth; speed; numpoints; ramp/sin; dwell points];
Depth = indpars[1] # [nm]
Speed = indpars[2] # [nm/s]
MaxInd = int(indpars[3]) # number of points in approach-indentation
dT2 = Depth/Speed/MaxInd # calculate time step based on number of points
dT = dT2 # suppress original dT
PointN = MaxInd*2
time = np.linspace(0, dT*(PointN-1), PointN)
timeL = np.linspace(dT, dT*(PointN*2-1), PointN*2)
ind_ramp = np.zeros([MaxInd*2])
ind_rampL = np.zeros([MaxInd*4]) # extended indentation with noncontact region
if indpars[4] == 0: # ramp or sin
for ii in range(MaxInd):
ind_ramp[ii] = Speed*time[ii]
for ii in range(MaxInd, MaxInd*2):
ind_ramp[ii] = Speed*time[-1]-Speed*time[ii]
for ii in range(2*MaxInd):
ind_rampL[ii] = Speed*timeL[ii]-Speed*time[MaxInd]-Speed*dT
for ii in range(2*MaxInd, MaxInd*4):
ind_rampL[ii] = Speed*timeL[-1]-Speed*time[MaxInd]-Speed*timeL[ii]-Speed*dT
elif indpars[4] == 1: # sinuspidal indentation
Freq = Speed/Depth/4
ind_ramp = Depth*sin(2*pi*Freq*time) # -1/4period
ind_rampL = Depth*sin(2*pi*Freq*timeL-pi/2) # -1/2period
indentationfull = ind_ramp
indentationfullL = ind_rampL
if len(indpars) > 5: # add dwell region
Dwell_time = indpars[5] # dwell time in seconds
dwell_points = int(Dwell_time/dT)
PointN = MaxInd*2 + dwell_points
time = np.linspace(0, dT*(PointN-1), PointN)
timeL = np.linspace(dT, dT*(PointN*2-1), PointN*2)
inddwell = np.ones(dwell_points)*ind_ramp[MaxInd]
indentationfull = np.concatenate((ind_ramp[0:MaxInd+1], inddwell, ind_ramp[MaxInd:-1]))
indentationfullL = np.concatenate((ind_rampL[0:2*MaxInd+1], inddwell, ind_rampL[2*MaxInd:-1]))
MaxInd = MaxInd + dwell_points
else:
dwell_points = 0
# launch ting_numerical to construct force
[force, cradius, contact_time, t1_ndx2, Et] = ting_numerical(pars, adhesion_pars,
Poisson, probe_size, dT, MaxInd, Height, viscomodel, probe_geom,
indentationfull)[0:5]
# add noise
force = force + np.random.normal(0, abs(0.01*noise*np.median(force)), len(force))
# force for the extended indentation with non-contact region
# forceL = np.pad(force, MaxInd - dwell_points, 'constant', constant_values=(0, 0))
forcePadL = np.zeros(MaxInd - dwell_points) + np.random.normal(0, abs(0.01*noise*np.median(force)), MaxInd - dwell_points)
forcePadR = np.zeros(MaxInd - dwell_points) + np.random.normal(0, abs(0.01*noise*np.median(force)), MaxInd - dwell_points)
forceL = np.concatenate((forcePadL, force, forcePadR), axis=0)
# add hydrodynamic drag
speedfull = np.diff(indentationfullL)/dT
speedfull = np.append(speedfull, speedfull[-1])
drag = speedfull*hydrodrag
forceL = forceL + drag
return time, indentationfull, force, cradius, indentationfullL, forceL
if __name__ == '__main__':
import time as mtime
Pars = {}
Pars['probe_shape'] = 'sphere'
Pars['probe_dimension'] = 5000
Pars['Poisson'] = 0.5 # Poisson's ratio of the sample
Pars['dT'] = 1e-3 # Sampling time (time step)
Pars['height'] = 0
Pars['indpars'] = np.array([1, 500, 500, 500, 0, 2]) # [yes/no; depth; speed; numpoimts; ramp/sin; dwell_time];
Pars['viscomodel'] = 'elastic' # 'sPLR'
Pars['Vpars'] = np.array([1000, 0.1, 0, 0])
Pars['noise'] = 3 # % noise level from median force
Pars['hydrodrag'] = 1e-5 # [nN*s/nm] coefficient of viscous drag
Pars['adhesion_model'] = 'JKR_transition'
Pars['adhesion_region'] = 'retraction'
Pars['adhesion'] = 0.3
# Pars['viscomodel'] = 'dSLS'
# Pars['Vpars'] = np.array([1000, 0.4, 1, 0.01, 0])
indentationfull = np.array([0, 1]) # arbitrary indentation profile
t1 = mtime.time()
time, indentationfull, force, cradius, indentationfullL, forceL = tingFC_constructor(Pars, indentationfull)
t2 = mtime.time()
print(t2-t1)
# curvedata = [time, indentationfull, force, cradius, indentationfullL, forceL]
# arr = np.vstack([curvedata[0], curvedata[1], curvedata[2]])
# arr.transpose()
plt.figure(num='Force vs Indentation')
plt.plot(indentationfull, force)
plt.xlabel('Indentation')
plt.ylabel('Force')
plt.figure(num='Contact Radius vs Time')
plt.plot(time, cradius)
plt.xlabel('Time')
plt.ylabel('Contact radius')
plt.figure(num='Simulated Indentation')
plt.plot(indentationfullL, forceL)
plt.xlabel('Indentation')
plt.ylabel('Force')
plt.figure(num='Simulated Force vs Time')
timeL = np.arange(0, len(forceL))*Pars['dT']
plt.plot(timeL, forceL)
plt.xlabel('Time')
plt.ylabel('Force')