Пример #1
0
def main():
    assert installed()

    # simple test calculation of CO molecule
    d = 1.14
    co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True)
    co.center(vacuum=5.)

    calc = Vasp(xc='PBE',
                prec='Low',
                algo='Fast',
                ismear=0,
                sigma=1.,
                istart=0,
                lwave=False,
                lcharg=False,
                ldipol=True)

    co.set_calculator(calc)
    energy = co.get_potential_energy()
    forces = co.get_forces()
    dipole_moment = co.get_dipole_moment()

    # check that parsing of vasprun.xml file works
    conf = read('vasprun.xml')
    assert conf.calc.parameters['kpoints_generation']
    assert conf.calc.parameters['sigma'] == 1.0
    assert conf.calc.parameters['ialgo'] == 68
    assert energy - conf.get_potential_energy() == 0.0
    assert np.allclose(conf.get_forces(), forces)
    assert np.allclose(conf.get_dipole_moment(), dipole_moment, atol=1e-6)

    # Cleanup
    calc.clean()
Пример #2
0
def main():
    if sys.version_info < (2, 7):
        raise NotAvailable('read_xml requires Python version 2.7 or greater')

    assert installed()

    # simple test calculation of CO molecule
    d = 1.14
    co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)],
               pbc=True)
    co.center(vacuum=5.)

    calc = Vasp(xc='PBE',
                prec='Low',
                algo='Fast',
                ismear=0,
                sigma=1.,
                istart=0,
                lwave=False,
                lcharg=False)

    co.set_calculator(calc)
    energy = co.get_potential_energy()
    forces = co.get_forces()

    # check that parsing of vasprun.xml file works
    conf = read('vasprun.xml')
    assert conf.calc.parameters['kpoints_generation']
    assert conf.calc.parameters['sigma'] == 1.0
    assert conf.calc.parameters['ialgo'] == 68
    assert energy - conf.get_potential_energy() == 0.0
    assert array_almost_equal(conf.get_forces(), forces, tol=1e-4)

    # Cleanup
    calc.clean()
Пример #3
0
def test_vasp2_co():
    """
    Run some VASP tests to ensure that the VASP calculator works. This
    is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT
    environment variables

    """

    from ase.test.vasp import installed2 as installed

    assert installed()

    from ase import Atoms
    from ase.io import write
    from ase.calculators.vasp import Vasp2 as Vasp
    import numpy as np

    def array_almost_equal(a1, a2, tol=np.finfo(type(1.0)).eps):
        """Replacement for old numpy.testing.utils.array_almost_equal."""
        return (np.abs(a1 - a2) < tol).all()

    d = 1.14
    co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True)
    co.center(vacuum=5.)

    calc = Vasp(xc='PBE',
                prec='Low',
                algo='Fast',
                ismear=0,
                sigma=1.,
                istart=0,
                lwave=False,
                lcharg=False)

    co.set_calculator(calc)
    en = co.get_potential_energy()
    write('vasp_co.traj', co)
    assert abs(en + 14.918933) < 5e-3

    # Secondly, check that restart from the previously created VASP output works

    calc2 = Vasp(restart=True)
    co2 = calc2.get_atoms()

    # Need tolerance of 1e-14 because VASP itself changes coordinates
    # slightly between reading POSCAR and writing CONTCAR even if no ionic
    # steps are made.
    assert array_almost_equal(co.positions, co2.positions, 1e-14)

    assert en - co2.get_potential_energy() == 0.
    assert array_almost_equal(calc.get_stress(co), calc2.get_stress(co2))
    assert array_almost_equal(calc.get_forces(co), calc2.get_forces(co2))
    assert array_almost_equal(calc.get_eigenvalues(), calc2.get_eigenvalues())
    assert calc.get_number_of_bands() == calc2.get_number_of_bands()
    assert calc.get_xc_functional() == calc2.get_xc_functional()

    # Cleanup
    calc.clean()
Пример #4
0
def test_vasp_charge():
    """
    Run VASP tests to ensure that determining number of electrons from
    user-supplied charge works correctly. This is conditional on the existence
    of the VASP_COMMAND or VASP_SCRIPT environment variables.

    """

    from ase.build import bulk
    from ase.calculators.vasp import Vasp
    from ase.test import must_raise
    from ase.test.vasp import installed

    assert installed()

    system = bulk('Al', 'fcc', a=4.5, cubic=True)

    # Dummy calculation to let VASP determine default number of electrons
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False)
    calc.calculate(system)
    default_nelect_from_vasp = calc.get_number_of_electrons()
    assert default_nelect_from_vasp == 12

    # Make sure that no nelect was written into INCAR yet (as it wasn't necessary)
    calc = Vasp()
    calc.read_incar()
    assert calc.float_params['nelect'] is None

    # Compare VASP's output nelect from before minus charge to default nelect
    # determined by us minus charge
    charge = -2
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                charge=charge)
    calc.initialize(system)
    calc.write_input(system)
    calc.read_incar()
    assert calc.float_params['nelect'] == default_nelect_from_vasp - charge

    # Test that conflicts between explicitly given nelect and charge are detected
    with must_raise(ValueError):
        calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                    nelect=default_nelect_from_vasp-charge+1,
                    charge=charge)
        calc.calculate(system)

    # Test that nothing is written if charge is 0 and nelect not given
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                charge=0)
    calc.initialize(system)
    calc.write_input(system)
    calc.read_incar()
    assert calc.float_params['nelect'] is None

    # Test that explicitly given nelect still works as expected
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False,
                nelect=15)
    calc.calculate(system)
    assert calc.get_number_of_electrons() == 15
Пример #5
0
def main():
    if sys.version_info < (2, 7):
        raise NotAvailable('read_xml requires Python version 2.7 or greater')

    assert installed()

    # simple test calculation of CO molecule
    d = 1.14
    co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)],
               pbc=True)
    co.center(vacuum=5.)

    calc = Vasp(xc='LDA',
                prec='Low',
                algo='Fast',
                ismear=0,
                sigma=1.,
                nbands=12,
                istart=0,
                nelm=3,
                lwave=False,
                lcharg=False,
                ldipol=True)

    co.set_calculator(calc)
    energy = co.get_potential_energy()
    forces = co.get_forces()
    dipole_moment = co.get_dipole_moment()

    # check that parsing of vasprun.xml file works
    conf = read('vasprun.xml')
    assert conf.calc.parameters['kpoints_generation']
    assert conf.calc.parameters['sigma'] == 1.0
    assert conf.calc.parameters['ialgo'] == 68
    assert energy - conf.get_potential_energy() == 0.0

    # Check some arrays
    assert np.allclose(conf.get_forces(), forces)
    assert np.allclose(conf.get_dipole_moment(), dipole_moment, atol=1e-6)

    # Check k-point-dependent properties
    assert len(conf.calc.get_eigenvalues(spin=0)) >= 12
    assert conf.calc.get_occupation_numbers()[2] == 2
    assert conf.calc.get_eigenvalues(spin=1) is None
    kpt = conf.calc.get_kpt(0)
    assert kpt.weight == 1.

    # Perform a spin-polarised calculation
    co.calc.set(ispin=2, ibrion=-1)
    co.get_potential_energy()
    conf = read('vasprun.xml')
    assert len(conf.calc.get_eigenvalues(spin=1)) >= 12
    assert conf.calc.get_occupation_numbers(spin=1)[0] == 1.

    # Cleanup
    calc.clean()
Пример #6
0
def test_vasp2_import():
    """
    Test if we can find vasp2 using get_calculator()
    """

    from ase.test.vasp import installed2 as installed
    from ase.calculators.calculator import get_calculator_class

    assert installed()

    get_calculator_class('vasp2')
Пример #7
0
def test_vasp2_cell():
    """

    Check the unit cell is handled correctly

    """

    from ase.test.vasp import installed2 as installed
    from ase.calculators.vasp import Vasp2 as Vasp
    from ase.build import molecule
    from ase.test import must_raise
    assert installed()

    # Molecules come with no unit cell

    atoms = molecule('CH4')
    calc = Vasp()

    with must_raise(ValueError):
        atoms.set_calculator(calc)
        atoms.get_total_energy()
Пример #8
0
def test_vasp2_xc():
    """
    Run some tests to ensure that the xc setting in the VASP calculator
    works.

    """

    from ase.test.vasp import installed2 as installed
    from ase.calculators.vasp import Vasp2 as Vasp
    assert installed()

    def dict_is_subset(d1, d2):
        """True if all the key-value pairs in dict 1 are in dict 2"""
        for key, value in d1.items():
            if key not in d2:
                return False
            elif d2[key] != value:
                return False
        else:
            return True

    calc_vdw = Vasp(xc='optb86b-vdw')

    assert dict_is_subset({
        'param1': 0.1234,
        'param2': 1.0
    }, calc_vdw.float_params)

    calc_hse = Vasp(xc='hse06', hfscreen=0.1, gga='RE', encut=400, sigma=0.5)

    assert dict_is_subset({
        'hfscreen': 0.1,
        'encut': 400,
        'sigma': 0.5
    }, calc_hse.float_params)
    assert dict_is_subset({'gga': 'RE'}, calc_hse.string_params)
import numpy as np
import pytest

from ase.test.vasp import installed2 as installed
from ase.io import read
from ase.optimize import BFGS
from ase.build import fcc111
from ase.constraints import FixAtoms
from ase.calculators.vasp import Vasp2 as Vasp

pytestmark = pytest.mark.skipif(not installed())


def create_slab_with_constraints():
    slab = fcc111('Al', size=(1, 1, 3), periodic=True)
    slab.center(vacuum=4, axis=2)
    con = FixAtoms(indices=[0, 1])
    slab.set_constraint(con)
    return slab


def test_ase_relax():
    slab = create_slab_with_constraints()
    calc = Vasp(xc='LDA', ediffg=-1e-3, lwave=False, lcharg=False)
    slab.set_calculator(calc)
    opt = BFGS(slab, logfile=None)
    opt.run(fmax=0.1, steps=3)

    init_slab = create_slab_with_constraints()
    res = read('OUTCAR')
    assert np.allclose(res.positions[0], init_slab.positions[0])
Пример #10
0
"""
Run VASP tests to ensure that relaxation with the VASP calculator works.
This is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT
environment variables.

"""

from ase.test.vasp import installed2 as installed

assert installed()

import numpy as np
from ase import io
# QuasiNewton nowadays is an alias for BFGSLineSearch, which is
# broken. Use BFGS instead.
from ase.optimize import BFGS as QuasiNewton
from ase.build import bulk
from ase.calculators.vasp import Vasp2 as Vasp


# -- Perform Volume relaxation within Vasp
def vasp_vol_relax():
    Al = bulk('Al', 'fcc', a=4.5, cubic=True)
    calc = Vasp(xc='LDA',
                isif=7,
                nsw=5,
                ibrion=1,
                ediffg=-1e-3,
                lwave=False,
                lcharg=False)
    calc.calculate(Al)
Пример #11
0
#!/usr/bin/python

"""
Run VASP tests to ensure that relaxation with the VASP calculator works.
This is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT
environment variables.

"""

from ase.test.vasp import installed

assert installed()

import numpy as np
from ase import io
# QuasiNewton nowadays is an alias for BFGSLineSearch, which is
# broken. Use BFGS instead.
from ase.optimize import BFGS as QuasiNewton
from ase.lattice import bulk
from ase.calculators.vasp import Vasp

# -- Perform Volume relaxation within Vasp
def vasp_vol_relax():
    Al = bulk('Al', 'fcc', a=4.5, cubic=True)
    calc = Vasp(xc='LDA', isif=7, nsw=5,
                ibrion=1, ediffg=-1e-3, lwave=False, lcharg=False)
    calc.calculate(Al)

    # Explicitly parse atomic position output file from Vasp
    CONTCAR_Al = io.read('CONTCAR', format='vasp')
Пример #12
0
def test_vasp2_wdir():
    """
    Run tests to ensure that the VASP txt and label arguments function correctly,
    i.e. correctly sets the working directories and works in that directory.

    This is conditional on the existence of the ASE_VASP_COMMAND, VASP_COMMAND
    or VASP_SCRIPT environment variables

    """

    import filecmp
    import os

    from ase.test.vasp import installed2 as installed

    from ase import Atoms
    from ase.calculators.vasp import Vasp2 as Vasp

    assert installed()

    def compare_paths(path1, path2):
        assert os.path.abspath(path1) == os.path.abspath(path2)

    # Test setup system, borrowed from vasp_co.py
    d = 1.14
    atoms = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True)
    atoms.center(vacuum=5.)

    file1 = '_vasp_dummy_str.out'
    file2 = '_vasp_dummy_io.out'
    file3 = '_vasp_dummy_2.out'

    testdir = '_dummy_txt_testdir'
    label = os.path.join(testdir, 'vasp')

    # Test
    settings = dict(label=label,
                    xc='PBE',
                    prec='Low',
                    algo='Fast',
                    ismear=0,
                    sigma=1.,
                    istart=0,
                    lwave=False,
                    lcharg=False)

    # Make 2 copies of the calculator object
    calc = Vasp(**settings)
    calc2 = Vasp(**settings)

    # Check the calculator path is the expected path
    compare_paths(calc.directory, testdir)

    calc.set_txt(file1)
    atoms.set_calculator(calc)
    en1 = atoms.get_potential_energy()

    # Check that the output files are in the correct directory
    for fi in ['OUTCAR', 'CONTCAR', 'vasprun.xml']:
        fi = os.path.join(testdir, fi)
        assert os.path.isfile(fi)

    # We open file2 in our current directory, so we don't want it to write
    # in the label directory
    with open(file2, 'w') as f:
        calc2.set_txt(f)
        atoms.set_calculator(calc2)
        atoms.get_potential_energy()

    # Make sure the two outputfiles are identical
    assert filecmp.cmp(os.path.join(calc.directory, file1), file2)

    # Test restarting from working directory in test directory
    label2 = os.path.join(testdir, file3)
    calc2 = Vasp(restart=label, label=label2)

    # Check the calculator path is the expected path
    compare_paths(calc2.directory, testdir)

    assert not calc2.calculation_required(calc2.atoms, ['energy', 'forces'])
    en2 = calc2.get_potential_energy()

    # Check that the restarted calculation didn't run, i.e. write to output file
    assert not os.path.isfile(os.path.join(calc.directory, file3))

    # Check that we loaded energy correctly
    assert en1 == en2
Пример #13
0
def test_vasp2_kpoints():
    """

    Check the many ways of specifying KPOINTS

    """

    import os
    import filecmp

    from ase.calculators.vasp import Vasp2 as Vasp
    from ase.build import bulk
    from ase.test.vasp import installed2 as installed

    assert installed()

    Al = bulk('Al', 'fcc', a=4.5, cubic=True)

    def check_kpoints_line(n, contents):
        """Assert the contents of a line"""
        with open('KPOINTS', 'r') as f:
            lines = f.readlines()
            assert lines[n] == contents

    # Default to (1 1 1)

    calc = Vasp(gamma=True)
    calc.write_kpoints()
    check_kpoints_line(2, 'Gamma\n')
    check_kpoints_line(3, '1 1 1 \n')
    calc.clean()

    # 3-tuple prints mesh
    calc = Vasp(gamma=False, kpts=(4, 4, 4))
    calc.write_kpoints()
    check_kpoints_line(2, 'Monkhorst-Pack\n')
    check_kpoints_line(3, '4 4 4 \n')
    calc.clean()

    # Auto mode
    calc = Vasp(kpts=20)
    calc.write_kpoints()
    check_kpoints_line(1, '0\n')
    check_kpoints_line(2, 'Auto\n')
    check_kpoints_line(3, '20 \n')
    calc.clean()

    # 1-element list ok, Gamma ok
    calc = Vasp(kpts=[20], gamma=True)
    calc.write_kpoints()
    check_kpoints_line(1, '0\n')
    check_kpoints_line(2, 'Auto\n')
    check_kpoints_line(3, '20 \n')
    calc.clean()

    # KSPACING suppresses KPOINTS file
    calc = Vasp(kspacing=0.23)
    calc.initialize(Al)
    calc.write_kpoints()
    calc.write_incar(Al)
    assert not os.path.isfile('KPOINTS')
    with open('INCAR', 'r') as f:
        assert ' KSPACING = 0.230000\n' in f.readlines()
    calc.clean()

    # Negative KSPACING raises an error
    calc = Vasp(kspacing=-0.5)

    try:
        calc.write_kpoints()
    except ValueError:
        pass
    else:
        raise AssertionError("Negative KSPACING did not raise ValueError")
    calc.clean()

    # Explicit weighted points with nested lists, Cartesian if not specified
    calc = Vasp(
        kpts=[[0.1, 0.2, 0.3, 2], [0.0, 0.0, 0.0, 1], [0.0, 0.5, 0.5, 2]])
    calc.write_kpoints()

    with open('KPOINTS.ref', 'w') as f:
        f.write("""KPOINTS created by Atomic Simulation Environment
    3 
    Cartesian
    0.100000 0.200000 0.300000 2.000000 
    0.000000 0.000000 0.000000 1.000000 
    0.000000 0.500000 0.500000 2.000000 
    """)

    assert filecmp.cmp('KPOINTS', 'KPOINTS.ref')
    os.remove('KPOINTS.ref')

    # Explicit points as list of tuples, automatic weighting = 1.
    calc = Vasp(kpts=[(0.1, 0.2, 0.3), (0.0, 0.0, 0.0), (0.0, 0.5, 0.5)],
                reciprocal=True)
    calc.write_kpoints()

    with open('KPOINTS.ref', 'w') as f:
        f.write("""KPOINTS created by Atomic Simulation Environment
    3 
    Reciprocal
    0.100000 0.200000 0.300000 1.0 
    0.000000 0.000000 0.000000 1.0 
    0.000000 0.500000 0.500000 1.0 
    """)

    assert filecmp.cmp('KPOINTS', 'KPOINTS.ref')
    os.remove('KPOINTS.ref')
Пример #14
0
def test_vasp2_check_state():
    """
    Run tests to ensure that the VASP check_state() function call works correctly,
    i.e. correctly sets the working directories and works in that directory.

    This is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT
    environment variables

    """

    from ase.test.vasp import installed2 as installed

    import os
    from ase import Atoms
    from ase.calculators.vasp import Vasp2 as Vasp
    assert installed()

    # Test setup system, borrowed from vasp_co.py
    d = 1.14
    atoms = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True)
    atoms.extend(Atoms('CO', positions=[(0, 2, 0), (0, 2, d)]))

    atoms.center(vacuum=5.)

    # Test
    settings = dict(xc='LDA',
                    prec='Low',
                    algo='Fast',
                    ismear=0,
                    sigma=1.,
                    istart=0,
                    lwave=False,
                    lcharg=False)

    s1 = atoms.get_chemical_symbols()

    calc = Vasp(**settings)

    atoms.set_calculator(calc)

    en1 = atoms.get_potential_energy()

    # Test JSON dumping and restarting works
    fi = 'json_test.json'
    calc.write_json(filename=fi)

    assert os.path.isfile(fi)

    calc2 = Vasp()
    calc2.read_json(fi)
    assert not calc2.calculation_required(atoms, ['energy', 'forces'])
    en2 = calc2.get_potential_energy()
    assert abs(en1 - en2) < 1e-8
    os.remove(fi)  # Clean up the JSON file

    # Check that the symbols remain in order (non-sorted)
    s2 = calc.atoms.get_chemical_symbols()
    assert s1 == s2
    s3 = sorted(s2)
    assert s2 != s3

    # Check that get_atoms() doesn't reset results
    r1 = dict(calc.results)  # Force a copy
    calc.get_atoms()
    r2 = dict(calc.results)
    assert r1 == r2

    # Make a parameter change to the calculator
    calc.set(sigma=0.5)

    # Check that we capture a change for float params
    assert calc.check_state(atoms) == ['float_params']
    assert calc.calculation_required(atoms, ['energy', 'forces'])

    en2 = atoms.get_potential_energy()

    # The change in sigma should result in a small change in energy
    assert (en1 - en2) > 1e-7

    # Now we make a change in input_params instead
    calc.kpts = 2

    # Check that this requires a new calculation
    assert calc.check_state(atoms) == ['input_params']
    assert calc.calculation_required(atoms, ['energy', 'forces'])

    # Clean up
    calc.clean()
def test_vasp_Al_volrelax():
    """
    Run VASP tests to ensure that relaxation with the VASP calculator works.
    This is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT
    environment variables.

    """

    from ase.test.vasp import installed

    assert installed()

    import numpy as np
    from ase import io
    # QuasiNewton nowadays is an alias for BFGSLineSearch, which is
    # broken. Use BFGS instead.
    from ase.optimize import BFGS as QuasiNewton
    from ase.build import bulk
    from ase.calculators.vasp import Vasp

    # -- Perform Volume relaxation within Vasp
    def vasp_vol_relax():
        Al = bulk('Al', 'fcc', a=4.5, cubic=True)
        calc = Vasp(xc='LDA',
                    isif=7,
                    nsw=5,
                    ibrion=1,
                    ediffg=-1e-3,
                    lwave=False,
                    lcharg=False)
        calc.calculate(Al)

        # Explicitly parse atomic position output file from Vasp
        CONTCAR_Al = io.read('CONTCAR', format='vasp')

        print('Stress after relaxation:\n', calc.read_stress())

        print('Al cell post relaxation from calc:\n',
              calc.get_atoms().get_cell())
        print('Al cell post relaxation from atoms:\n', Al.get_cell())
        print('Al cell post relaxation from CONTCAR:\n', CONTCAR_Al.get_cell())

        # All the cells should be the same.
        assert (calc.get_atoms().get_cell() == CONTCAR_Al.get_cell()).all()
        assert (Al.get_cell() == CONTCAR_Al.get_cell()).all()

        return Al

    # -- Perform Volume relaxation using ASE with Vasp as force/stress calculator
    def ase_vol_relax():
        Al = bulk('Al', 'fcc', a=4.5, cubic=True)
        calc = Vasp(xc='LDA')
        Al.calc = calc

        from ase.constraints import StrainFilter
        sf = StrainFilter(Al)
        qn = QuasiNewton(sf, logfile='relaxation.log')
        qn.run(fmax=0.1, steps=5)

        print('Stress:\n', calc.read_stress())
        print('Al post ASE volume relaxation\n', calc.get_atoms().get_cell())

        return Al

    # Test function for comparing two cells
    def cells_almost_equal(cellA, cellB, tol=0.01):
        return (np.abs(cellA - cellB) < tol).all()

    # Correct LDA relaxed cell
    a_rel = 4.18
    LDA_cell = np.diag([a_rel, a_rel, a_rel])

    Al_vasp = vasp_vol_relax()
    Al_ase = ase_vol_relax()

    assert cells_almost_equal(LDA_cell, Al_vasp.get_cell())
    assert cells_almost_equal(LDA_cell, Al_ase.get_cell())

    # Cleanup
    Al_ase.calc.clean()
Пример #16
0
def test_vasp_net_charge():
    """
    Run VASP tests to ensure that determining number of electrons from
    user-supplied net charge (via the deprecated net_charge parameter) works
    correctly. This is conditional on the existence of the VASP_COMMAND or
    VASP_SCRIPT environment variables.

    This is mainly a slightly reduced duplicate of the vasp_charge test, but with
    flipped signs and with checks that ensure FutureWarning is emitted.

    Should be removed along with the net_charge parameter itself at some point.
    """

    from ase.build import bulk
    from ase.calculators.vasp import Vasp
    from ase.test import must_raise, must_warn
    from ase.test.vasp import installed

    assert installed()

    system = bulk('Al', 'fcc', a=4.5, cubic=True)

    # Dummy calculation to let VASP determine default number of electrons
    calc = Vasp(xc='LDA', nsw=-1, ibrion=-1, nelm=1, lwave=False, lcharg=False)
    calc.calculate(system)
    default_nelect_from_vasp = calc.get_number_of_electrons()
    assert default_nelect_from_vasp == 12

    # Compare VASP's output nelect from before + net charge to default nelect
    # determined by us + net charge
    with must_warn(FutureWarning):
        net_charge = -2
        calc = Vasp(xc='LDA',
                    nsw=-1,
                    ibrion=-1,
                    nelm=1,
                    lwave=False,
                    lcharg=False,
                    net_charge=net_charge)
        calc.initialize(system)
        calc.write_input(system)
        calc.read_incar()
    assert calc.float_params['nelect'] == default_nelect_from_vasp + net_charge

    # Test that conflicts between explicitly given nelect and net charge are
    # detected
    with must_raise(ValueError):
        with must_warn(FutureWarning):
            calc = Vasp(xc='LDA',
                        nsw=-1,
                        ibrion=-1,
                        nelm=1,
                        lwave=False,
                        lcharg=False,
                        nelect=default_nelect_from_vasp + net_charge + 1,
                        net_charge=net_charge)
            calc.calculate(system)

    # Test that conflicts between charge and net_charge are detected
    with must_raise(ValueError):
        with must_warn(FutureWarning):
            calc = Vasp(xc='LDA',
                        nsw=-1,
                        ibrion=-1,
                        nelm=1,
                        lwave=False,
                        lcharg=False,
                        charge=-net_charge - 1,
                        net_charge=net_charge)
            calc.calculate(system)

    # Test that nothing is written if net charge is 0 and nelect not given
    with must_warn(FutureWarning):
        calc = Vasp(xc='LDA',
                    nsw=-1,
                    ibrion=-1,
                    nelm=1,
                    lwave=False,
                    lcharg=False,
                    net_charge=0)
        calc.initialize(system)
        calc.write_input(system)
        calc.read_incar()
    assert calc.float_params['nelect'] is None