141 lines
3.6 KiB
Python
141 lines
3.6 KiB
Python
# coding=utf-8
|
|
import warnings
|
|
import numpy as np
|
|
import yafflib
|
|
|
|
__author__ = 'markusro'
|
|
|
|
|
|
class Function(object):
|
|
|
|
|
|
def __init__(self):
|
|
super(Function, self).__init__()
|
|
self._id_string = None
|
|
self._num_parameters = None
|
|
self._pretty_name = ""
|
|
self._function = None
|
|
|
|
def get_id_string(cls):
|
|
if cls._id_string is None:
|
|
raise NotImplementedError("You need to set the id_string")
|
|
return cls._id_string
|
|
|
|
def set_id_string(cls, s):
|
|
cls._id_string = s
|
|
|
|
def get_num_paramters(cls):
|
|
if cls._num_paramters is None:
|
|
raise NotImplementedError("You need to set the num_paramters")
|
|
return cls._num_paramters
|
|
|
|
def set_num_paramters(cls, s):
|
|
cls._num_paramters = s
|
|
|
|
def get_function(cls):
|
|
if cls._function is None:
|
|
raise NotImplementedError("You need to set f")
|
|
return cls._function
|
|
|
|
def set_function(cls, f):
|
|
cls._function = f
|
|
|
|
def calculate(self, x, p):
|
|
if self._function is None: raise NotImplementedError("You need to set f")
|
|
data = self._function(x, p)
|
|
return x,data[0],data[1]
|
|
|
|
|
|
class HavNegCmplx(Function):
|
|
def __init__(self):
|
|
super(HavNegCmplx, self).__init__()
|
|
self.set_function(hn)
|
|
self.set_id_string("hn")
|
|
self.set_num_paramters(4)
|
|
|
|
|
|
def hn(p, x):
|
|
om = 2*np.pi*x
|
|
#hn = om*1j
|
|
eps, t, a, b = p
|
|
h_n = eps/(1+(1j*om*t)**a)**b
|
|
cplx = np.array([h_n.real, -h_n.imag])
|
|
return cplx
|
|
|
|
|
|
class ConductivityCmplx(Function):
|
|
def __init__(self):
|
|
super(ConductivityCmplx, self).__init__()
|
|
self.set_num_paramters(3)
|
|
self.set_function(cond_cmplx)
|
|
self.set_id_string("conductivity")
|
|
|
|
|
|
def cond_cmplx(p, x ):
|
|
om = 2*np.pi*x
|
|
sgma, isgma, n = p
|
|
cond = sgma/(om**n)+isgma/(1j*om**n) # Jonscher (Universal Dielectric Response: e",e' prop sigma/omega**n
|
|
cplx = np.array([cond.real, -cond.imag])
|
|
return cplx
|
|
|
|
|
|
class PowerCmplx(Function):
|
|
def __init__(self):
|
|
super(PowerCmplx, self).__init__()
|
|
self.set_function(power_cmplx)
|
|
self.set_num_paramters(2)
|
|
self.set_id_string("power_law")
|
|
|
|
|
|
def power_cmplx( p, x ):
|
|
om = 2*np.pi*x
|
|
sgma, n = p
|
|
power = sgma/(om*1j)**n
|
|
cplx = np.array([power.real, -power.imag])
|
|
return cplx
|
|
|
|
|
|
class EpsInftyCmplx(Function):
|
|
def __init__(self):
|
|
super(EpsInftyCmplx, self).__init__()
|
|
self.set_function(static_cmplx)
|
|
self.set_id_string("e_inf")
|
|
self.set_num_paramters(1)
|
|
|
|
|
|
def static_cmplx(p, x ):
|
|
eps_inf = p[0]
|
|
static = np.ones((2, x.size))*eps_inf
|
|
static[1, :] *= 0 # set imag part zero
|
|
return static
|
|
|
|
|
|
class YaffCmplx(Function):
|
|
def __init__(self):
|
|
super(YaffCmplx, self).__init__()
|
|
self.set_function(yaff)
|
|
self.set_id_string("yaff")
|
|
self.set_num_paramters(8)
|
|
|
|
|
|
def yaff( p, x ):
|
|
#ya = self.YAFF.yaff(p[:8], x)
|
|
ya = yafflib.Yaff.yaff(p[:,0], x)
|
|
cplx = np.array([ya.imag, ya.real])
|
|
return cplx
|
|
|
|
|
|
class ModelFunction(object):
|
|
def __init__(self):
|
|
super(ModelFunction, self).__init__(self)
|
|
self.model = None
|
|
|
|
@classmethod
|
|
def select_model(self, model):
|
|
self._functions_avail = ", ".join( cls().get_id_string() for cls in Function.__subclasses__())
|
|
for cls in Function.__subclasses__():
|
|
if model == cls().get_id_string():
|
|
self.model = cls()
|
|
return True
|
|
warnings.warn("Function not found: %s \n(available functions: %s)"%(model, self._functions_avail))
|
|
return False |