Source code for iDEA.test_mix
"""Tests for mixing schemes
"""
from __future__ import division
from __future__ import absolute_import
import numpy as np
import numpy.testing as nt
import unittest
from . import input
from . import mix
from . import NON
[docs]class TestPulay(unittest.TestCase):
"""Tests for the Pulay mixer
"""
[docs] def setUp(self):
""" Sets up harmonic oscillator system """
pm = input.Input()
pm.run.name = 'unittest'
pm.run.save = False
pm.run.verbosity = 'low'
# It might still be possible to speed this up
pm.sys.NE = 2 #: Number of electrons
pm.sys.grid = 61 #: Number of grid points (must be odd)
pm.sys.xmax = 7.5 #: Size of the system
pm.sys.acon = 1.0 #: Smoothing of the Coloumb interaction
pm.sys.interaction_strength = 1#: Scales the strength of the Coulomb interaction
def v_ext(x):
"""Initial external potential"""
return 0.5*(0.25**2)*(x**2)
pm.sys.v_ext = v_ext
pm.ext.ctol = 1e-5
self.pm = pm
[docs] def test_array_update_1(self):
"""Testing internal variables of Pulay mixer
Just checking that the maths works as expected from
[Kresse1996]_ p.34 ...
"""
pm = self.pm
pm.lda.kerker_length = 100
order = 4
mixer = mix.PulayMixer(pm, order=order, preconditioner=None)
x = np.linspace(-pm.sys.xmax, pm.sys.xmax, pm.sys.grid)
den_in = 1 + 0.1*np.sin(x)
den_out = 1 - 0.1*np.sin(x)
den_in_new = mixer.mix(den_in, den_out)
nt.assert_allclose(mixer.den_in[0], den_in)
#nt.assert_allclose(mixer.den_delta[0], den_in-0)
nt.assert_allclose(mixer.res[0], -0.2*np.sin(x))
#nt.assert_allclose(mixer.res_delta[0], -0.2*np.sin(x)-0)
#overlaps = 0.04*np.dot(np.sin(x),np.sin(x))
#A_bar = overlaps
#A_bar_inv = 1/overlaps
#alpha_bar = - A_bar_inv * overlaps
#nt.assert_allclose(alpha_bar, -1)
[docs]class TestKerker(unittest.TestCase):
"""Tests for the Kerker preconditioner
"""
[docs] def setUp(self):
""" Sets up harmonic oscillator system """
pm = input.Input()
pm.run.name = 'unittest'
pm.run.save = False
pm.run.verbosity = 'low'
# It might still be possible to speed this up
pm.sys.NE = 2 #: Number of electrons
pm.sys.grid = 61 #: Number of grid points (must be odd)
pm.sys.xmax = 7.5 #: Size of the system
pm.sys.acon = 1.0 #: Smoothing of the Coloumb interaction
pm.sys.interaction_strength = 1#: Scales the strength of the Coulomb interaction
def v_ext(x):
"""Initial external potential"""
return 0.5*(0.25**2)*(x**2)
pm.sys.v_ext = v_ext
pm.ext.ctol = 1e-5
pm.setup_space()
self.pm = pm
[docs] def test_screening_length_1(self):
"""Testing screening length in Kerker
Check that for infinite screening length, simple mixing is recovered.
[Kresse1996]_ p.34 ...
"""
pm = self.pm
pm.lda.kerker_length = 1e6
pm.lda.mix = 1.0
mixer = mix.PulayMixer(pm, order=20, preconditioner='kerker')
den = NON.main(pm).gs_non_den
# Note: Kerker always removes G=0 cmponent
# (it is intended to be used on density *differences*, where the G=0
# component vanishes anyhow)
den -= np.average(den)
den_cond = mixer.precondition(den, None, None)
nt.assert_allclose(den, den_cond, 1e-3)
[docs]class TestRPA(unittest.TestCase):
"""Tests for the RPA preconditioner
"""
[docs] def setUp(self):
""" Sets up harmonic oscillator system """
pm = input.Input()
pm.run.name = 'unittest'
pm.run.save = False
pm.run.verbosity = 'low'
# It might still be possible to speed this up
pm.sys.NE = 2 #: Number of electrons
pm.sys.grid = 61 #: Number of grid points (must be odd)
pm.sys.xmax = 7.5 #: Size of the system
pm.sys.acon = 1.0 #: Smoothing of the Coloumb interaction
pm.sys.interaction_strength = 1#: Scales the strength of the Coulomb interaction
def v_ext(x):
"""Initial external potential"""
return 0.5*(0.25**2)*(x**2)
pm.sys.v_ext = v_ext
pm.lda.mix = 1.0
self.pm = pm
[docs] def test_chi_1(self):
"""Testing potential-density response
Testing some basic symmetry properties of the
potential-density response and the preconditioning matrices
required for density/potential mixing.
"""
pm = self.pm
mixer = mix.PulayMixer(pm, order=1, preconditioner='rpa')
results = NON.main(pm)
den = results.gs_non_den
eigv = results.gs_non_eigv
eigf = results.gs_non_eigf
chi = mixer.preconditioner.chi(eigv, eigf)
v = mixer.preconditioner.coulomb_repulsion
dx = mixer.preconditioner.x_delta
nx = mixer.preconditioner.x_npt
nt.assert_allclose(chi, chi.T, 1e-6)
nt.assert_allclose(v, v.T, 1e-6)
# this is just for testing purposes
eps_pmix = np.eye(nx)/dx - np.dot(v,chi)*dx
eps_dmix = np.eye(nx)/dx - np.dot(chi,v)*dx
nt.assert_allclose(eps_pmix, eps_dmix.T, 1e-6)