143 lines
5.7 KiB
Python
143 lines
5.7 KiB
Python
# *****************************************************************************
|
|
# This program is free software; you can redistribute it and/or modify it under
|
|
# the terms of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
# details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License along with
|
|
# this program; if not, write to the Free Software Foundation, Inc.,
|
|
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# Module authors:
|
|
# Paul M. Neves <pmneves@mit.edu>
|
|
# *****************************************************************************
|
|
|
|
from frappy.core import Readable, Parameter, FloatRange, HasIO, StringIO, Property, IntRange,\
|
|
IDLE, BUSY, WARN, ERROR, Drivable, BoolType, Attached, Writable, StructOf
|
|
|
|
|
|
class Temp(Writable):
|
|
"""stores sample temperature"""
|
|
|
|
target = Parameter('target voltage', FloatRange(0, 325, unit='K'),
|
|
readonly=False)
|
|
|
|
def write_target(self, target):
|
|
self.value = target
|
|
|
|
def read_value(self):
|
|
return self.value
|
|
|
|
|
|
class Displacement(Readable):
|
|
|
|
# attached classes for capacitance and temperature
|
|
cap = Attached()
|
|
temp = Attached()
|
|
|
|
# modifying a property of inherited parameters (unit is propagated to the FloatRange datatype)
|
|
value = Parameter('displacement', FloatRange(None, None, unit='um'), readonly=True)
|
|
alpha290K = Parameter('capacitor constant at 290 K', FloatRange(None, None, unit='um pF'), readonly=False)
|
|
d0 = Parameter('offset displacement', FloatRange(None, None, unit='um'), readonly=False)
|
|
Cp = Parameter('parallel capacitance', FloatRange(None, None, unit='pF'), readonly=False)
|
|
d0_curve = Parameter('calibration curve for offset displacement',
|
|
StructOf(a=FloatRange(None, None, unit='um'),
|
|
b=FloatRange(None, None, unit='um/K'),
|
|
c=FloatRange(None, None, unit='um/K^2'),
|
|
d=FloatRange(None, None, unit='um/K^3'),
|
|
e=FloatRange(None, None, unit='um/K^4'),),
|
|
readonly=False)
|
|
|
|
def read_value(self):
|
|
# get temperature and capacitance
|
|
temp = self.temp.target
|
|
cap = self.cap.value
|
|
|
|
# calculate displacement from temperature and capacitance
|
|
d0_T = self.d0_curve['a'] + self.d0_curve['b']*temp + self.d0_curve['c']*temp**2 + self.d0_curve['d']*temp**3 + self.d0_curve['e']*temp**4
|
|
|
|
disp = self.alpha290K / (cap - self.Cp) - self.d0 - d0_T
|
|
|
|
return disp
|
|
|
|
|
|
class Force(Readable):
|
|
|
|
# attached classes for capacitance and temperature
|
|
cap = Attached()
|
|
temp = Attached()
|
|
|
|
# modifying a property of inherited parameters (unit is propagated to the FloatRange datatype)
|
|
value = Parameter('force', FloatRange(None, None, unit='N'), readonly=True)
|
|
alpha290K = Parameter('capacitor constant at 290 K', FloatRange(None, None, unit='N pF'), readonly=False)
|
|
f0 = Parameter('offset force', FloatRange(None, None, unit='N'), readonly=False)
|
|
Cp = Parameter('parallel capacitance', FloatRange(None, None, unit='pF'), readonly=False)
|
|
f0_curve = Parameter('calibration curve for offset force',
|
|
StructOf(a=FloatRange(None, None, unit='N'),
|
|
b=FloatRange(None, None, unit='N/K'),
|
|
c=FloatRange(None, None, unit='N/K^2'),
|
|
d=FloatRange(None, None, unit='N/K^3'),
|
|
e=FloatRange(None, None, unit='N/K^4'),),
|
|
readonly=False)
|
|
|
|
def read_value(self):
|
|
# get temperature and capacitance
|
|
temp = self.temp.target
|
|
cap = self.cap.value
|
|
|
|
# calculate force from temperature and capacitance
|
|
alpha = self.alpha290K * (0.91 + 5e-5*temp + 9e-7*temp**2)
|
|
f0_T = self.f0_curve['a'] + self.f0_curve['b']*temp + self.f0_curve['c']*temp**2 + self.f0_curve['d']*temp**3 + self.f0_curve['e']*temp**4
|
|
|
|
force = alpha / (cap - self.Cp) - self.f0 - f0_T
|
|
|
|
return force
|
|
|
|
|
|
class Stress(Readable):
|
|
|
|
# attached classes for displacement
|
|
force = Attached()
|
|
|
|
# modifying a property of inherited parameters (unit is propagated to the FloatRange datatype)
|
|
value = Parameter('stress', FloatRange(None, None, unit='GPa'), readonly=True)
|
|
area = Parameter('cross sectional area of sample in mm^2', FloatRange(None, None, unit='mm^2'), readonly=False)
|
|
|
|
def read_value(self):
|
|
return self.force.value / self.area / 1000
|
|
|
|
|
|
class Strain(Readable):
|
|
|
|
# attached classes for displacement
|
|
displacement = Attached()
|
|
|
|
# modifying a property of inherited parameters (unit is propagated to the FloatRange datatype)
|
|
value = Parameter('strain', FloatRange(None, None, unit='m/m'), readonly=True)
|
|
L = Parameter('length of sample in mm', FloatRange(None, None, unit='mm'), readonly=False)
|
|
|
|
def read_value(self):
|
|
return self.displacement.value / (1000*self.L)
|
|
|
|
|
|
class YoungsModulus(Readable):
|
|
|
|
# attached classes for displacement
|
|
stress = Attached()
|
|
strain = Attached()
|
|
|
|
# modifying a property of inherited parameters (unit is propagated to the FloatRange datatype)
|
|
value = Parameter('Young\'s modulus', FloatRange(None, None, unit='GPa'), readonly=True)
|
|
|
|
def read_value(self):
|
|
if self.strain.value:
|
|
return self.stress.value / self.strain.value
|
|
else:
|
|
return 0
|
|
|