Exemple #1
0
def test_eos_fit_deriv():
    data = np.loadtxt("files/ev/evdata.txt")
    volume = data[:,0] * Bohr3_to_Ang3
    energy = data[:,1] * (Ry / eV)
    
    eos = EosFit(volume=volume,
                 energy=energy,
                 splpoints=500)
    
    # EosFit is a num.Fit1D subclass, so it has self.x and self.y
    assert (volume == eos.x).all()
    assert (energy == eos.y).all()
    
    # this reference to self.spl causes self.spl to be defined (lazyprop)               
    xx = eos.spl.x             
    yy = eos.spl.y             
    assert len(xx) == len(yy) == 500
    
    # spline thru fitted data, must be exactly like eos.spl
    spl = num.Spline(xx, yy, k=5, s=None)
    
    assert np.allclose(eos(xx), yy)             # call _vinet, consistency of fitted data
    assert np.allclose(eos(xx), spl(xx))        # consistency of splines
    assert np.allclose(eos(xx), eos.spl(xx))    # consistency of splines
    assert np.allclose(eos(xx, der=1), spl(xx, der=1)) # call _vinet_deriv1
    assert np.allclose(eos(xx, der=2), spl(xx, der=2)) # call _vinet_deriv2
    assert np.allclose(eos(xx, der=3), spl(xx, der=3)) # call eos.spl(xx, der=3)
Exemple #2
0
 def _get_spl(self, attr_name):
     # attr_name : 'ev', 'pv', 'bv'
     # spl_attr_name : 'self.spl_{ev,pv,bv}'
     spl_attr_name = "spl_%s" % attr_name
     if self.is_set_attr(spl_attr_name):
         return getattr(self, spl_attr_name)
     else:
         arr = getattr(self, attr_name)
         return num.Spline(arr[:, 0], arr[:, 1])
Exemple #3
0
def test_gibbs():
    # number of varied axis points
    nax = 6
    # phonon freq axis
    freq = np.linspace(0, 1000, 300)  # cm^-1
    T = np.linspace(5, 2000, 50)
    P = np.linspace(0, 5, 2)

    # 2d case
    case = '2d'
    cell_a = np.linspace(2.5, 3.5, nax)
    cell_c = np.linspace(3, 3.8, nax)
    volfunc_ax = lambda x: x[0]**2 * x[1]
    axes_flat = np.array([x for x in product(cell_a, cell_c)])
    V = np.array([volfunc_ax(x) for x in axes_flat])
    cell_a_mean = cell_a.mean()
    cell_c_mean = cell_c.mean()
    cell_a_min = cell_a.min()
    cell_c_min = cell_c.min()
    etot = np.array([(a - cell_a_mean)**2.0 + (c - cell_c_mean)**2.0
                     for a, c in axes_flat])
    phdos = []
    Vmax = V.max()
    # phonon dos (just a gaussian) shifted to lower (higher) freqs for higher
    # (lower) volume
    for ii in range(axes_flat.shape[0]):
        a, c = axes_flat[ii, :]
        fc = 550 - 50 * V[ii] / Vmax
        phdos.append(np.array([freq, gauss(freq - fc, 100) * 0.01]).T)

    gibbs = Gibbs(T=T,
                  P=P,
                  etot=etot,
                  phdos=phdos,
                  axes_flat=axes_flat,
                  volfunc_ax=volfunc_ax,
                  case=case,
                  dosarea=None)
    gibbs.set_fitfunc('C',
                      lambda x, y: num.Spline(x, y, s=None, k=5, eps=1e-5))
    g = gibbs.calc_G(calc_all=True)

    dr = 'files/gibbs/2d'
    for name in os.listdir(dr):
        fn = '%s/%s' % (dr, name)
        gref = io.read_h5(fn)
        print("testing: %s" % fn)
        compare_dicts_with_arrays(gref, g)
        tools.assert_dict_with_all_types_almost_equal(gref,
                                                      g,
                                                      keys=list(gref.keys()),
                                                      atol=1e-8,
                                                      rtol=1e-3)

    # 1d case
    case = '1d'
    V = np.linspace(10, 20, nax)
    axes_flat = V**(1 / 3.)  # cubic
    volfunc_ax = lambda x: x[0]**3.0
    etot = (V - V.mean())**2
    fcenter = 450 + 100 * (axes_flat - axes_flat.min())
    # fake phonon dos data (Gaussian), shift to lower freq for higher volume
    phdos = [np.array([freq, gauss(freq - fc, 100)]).T for fc in fcenter[::-1]]

    gibbs = Gibbs(T=T,
                  P=P,
                  etot=etot,
                  phdos=phdos,
                  axes_flat=axes_flat,
                  volfunc_ax=volfunc_ax,
                  case=case,
                  dosarea=None)
    gibbs.set_fitfunc('C',
                      lambda x, y: num.Spline(x, y, s=None, k=5, eps=1e-5))
    g = gibbs.calc_G(calc_all=True)

    dr = 'files/gibbs/1d'
    for name in os.listdir(dr):
        fn = '%s/%s' % (dr, name)
        gref = io.read_h5(fn)
        print("testing: %s" % fn)
        compare_dicts_with_arrays(gref, g)
        tools.assert_dict_with_all_types_almost_equal(gref,
                                                      g,
                                                      keys=list(gref.keys()),
                                                      atol=1e-14,
                                                      rtol=1e-8)

    # test enthalpy stuff for 1d case
    # E(V)
    ev = num.PolyFit1D(g['/ax0/V'], g['/ax0/Etot'], deg=5)
    # P(V)
    pv = lambda v: -ev(v, der=1) * constants.eV_by_Ang3_to_GPa
    assert np.allclose(g['/P/P'], pv(g['/#opt/P/V']))
    assert np.allclose(g['/#opt/P/H'],
                       ev(g['/#opt/P/V']) + g['/P/P']*g['/#opt/P/V'] / \
                       constants.eV_by_Ang3_to_GPa)
Exemple #4
0
    # (lower) volume
    for ii in range(axes_flat.shape[0]):
        a, c = axes_flat[ii, :]
        fc = 550 - 50 * V[ii] / Vmax
        phdos.append(np.array([freq, gauss(freq - fc, 100) * 0.01]).T)

    gibbs = Gibbs(T=T,
                  P=P,
                  etot=etot,
                  phdos=phdos,
                  axes_flat=axes_flat,
                  volfunc_ax=volfunc_ax,
                  case=case,
                  dosarea=None)
    gibbs.set_fitfunc('C',
                      lambda x, y: num.Spline(x, y, s=None, k=5, eps=1e-5))
    g = gibbs.calc_G(calc_all=True)
    common.makedirs('../files/gibbs/2d')
    io.write_h5('../files/gibbs/2d/%s.h5' % gethostname(),
                filt_dct(g),
                mode='w')

    # 1d case
    case = '1d'
    V = np.linspace(10, 20, nax)
    axes_flat = V**(1 / 3.)  # cubic
    volfunc_ax = lambda x: x[0]**3.0
    etot = (V - V.mean())**2
    fcenter = 450 + 100 * (axes_flat - axes_flat.min())
    # fake phonon dos data (Gaussian), shift to lower freq for higher volume
    phdos = [np.array([freq, gauss(freq - fc, 100)]).T for fc in fcenter[::-1]]
Exemple #5
0
def find_peaks(y, x=None, k=3, spread=2, ymin=None):
    """Simple peak finding algorithm.
    
    Find all peaks where ``y > ymin``. If `x` given, also extract peak maxima
    positions by fitting a spline of order `k` to each found peak. To find
    minima, just use ``-y``.
    
    Parameters
    ----------
    y : 1d array_like
        data with peaks
    x : 1d array_like, optional, len(y)
        x axis
    k : int
        order of spline 
    spread : int
        Use ``2*spread+1`` points around each peak to fit a spline. Note that
        we need ``2*spread+1 > k``.
    ymin : float, optional
        Find all peaks above that value.

    Returns
    -------
    idx0, pos0
    idx0 : indices of peaks from finite diffs, each peak is at ``x[idx0[i]]``
    pos0 : refined `x`-positions of peaks if `x` given, else None

    Examples
    --------
    >>> from pwtools.signal import gauss, find_peaks
    >>> from pwtools import num
    >>> x=linspace(0,10,300); y=0.2*gauss(x-0.5,.1) + gauss(x-2,.1) + 0.7*gauss(x-3,0.1) + gauss(x-6,1)
    >>> # ymin=0.4: ignore first peak at x=0.5
    >>> find_peaks(y,x, ymin=0.4)
    ([60, 90, 179], [2.000231296097065, 3.0007122565950572, 5.999998055132549])
    >>> idx0, pos0=find_peaks(y,x, ymin=0.4)
    >>> spl=num.Spline(x,y)
    >>> plot(x,y)
    >>> for x0 in pos0:
    ...    plot([x0], [spl(x0)], 'ro')
    """
    ymin = y.min() if ymin is None else ymin
    idx0 = []
    dfy = np.diff(y, n=1)
    for ii in range(len(dfy) - 1):
        if dfy[ii] > 0 and dfy[ii + 1] < 0 and y[ii] >= ymin:
            idx0.append(ii + 1)
    pos0 = None
    if x is not None:
        pos0 = []
        for i0 in idx0:
            sl = slice(i0 - spread, i0 + 1 + spread, None)
            xx = x[sl]
            yy = y[sl]
            spl = num.Spline(xx, -yy, k=k, s=None)
            try:
                root = spl.get_min()
                pos0.append(root)
            except ValueError:
                raise ValueError(
                    "error calculating spline maximum at idx=%i, x=%f" %
                    (i0, x[i0]))
    return idx0, pos0
Exemple #6
0
 def spl(self):
     """Spline thru the fitted E(V) b/c we are too lazy to calculate the
     analytic derivative. Fallback."""
     # use many points for accurate deriv
     vv = np.linspace(self.volume.min(), self.volume.max(), self.splpoints)
     return num.Spline(vv, self(vv, der=0), k=5, s=None)
Exemple #7
0
 def _default_fit_C(x, y):
     return num.Spline(x, y, k=5, s=None)