File: test_vasp_kpoints.py

package info (click to toggle)
python-ase 3.26.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 15,484 kB
  • sloc: python: 148,112; xml: 2,728; makefile: 110; javascript: 47
file content (142 lines) | stat: -rw-r--r-- 4,126 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# fmt: off
"""
Check the many ways of specifying KPOINTS
"""
import os

import pytest

from ase.build import bulk
from ase.calculators.vasp.create_input import format_kpoints

from .filecmp_ignore_whitespace import filecmp_ignore_whitespace

calc = pytest.mark.calculator


@pytest.fixture()
def atoms():
    return bulk('Al', 'fcc', a=4.5, cubic=True)


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


@pytest.fixture()
def write_kpoints(atoms):
    """Helper fixture to write the input kpoints file"""
    def _write_kpoints(factory, **kwargs):
        calc = factory.calc(**kwargs)
        calc.initialize(atoms)
        calc.write_kpoints(atoms=atoms)
        return atoms, calc

    return _write_kpoints


def test_vasp_kpoints_111(atoms):
    # Default to (1 1 1)
    string = format_kpoints(gamma=True, atoms=atoms, kpts=(1, 1, 1))
    check_kpoints_string(string, 2, 'Gamma')
    check_kpoints_string(string, 3, '1 1 1')


def test_vasp_kpoints_3_tuple(atoms):
    string = format_kpoints(gamma=False, kpts=(4, 4, 4), atoms=atoms)
    lines = string.split('\n')
    assert lines[1] == '0'
    assert lines[2] == 'Monkhorst-Pack'
    assert lines[3] == '4 4 4'


def check_kpoints_string(string, lineno, value):
    assert string.splitlines()[lineno].strip() == value


def test_vasp_kpoints_auto(atoms):
    string = format_kpoints(atoms=atoms, kpts=20)
    check_kpoints_string(string, 1, '0')
    check_kpoints_string(string, 2, 'Auto')
    check_kpoints_string(string, 3, '20')


def test_vasp_kpoints_1_element_list_gamma(atoms):
    # 1-element list ok, Gamma ok
    string = format_kpoints(atoms=atoms, kpts=[20], gamma=True)
    check_kpoints_string(string, 1, '0')
    check_kpoints_string(string, 2, 'Auto')
    check_kpoints_string(string, 3, '20')


@calc('vasp')
def test_kspacing_supress_kpoints_file(factory, write_kpoints):
    # KSPACING suppresses KPOINTS file
    Al, calc = write_kpoints(factory, kspacing=0.23)
    calc.write_incar(Al)
    assert not os.path.isfile('KPOINTS')
    with open('INCAR') as fd:
        assert 'KSPACING = 0.230000\n' in fd.readlines()


@calc('vasp')
def test_negative_kspacing_error(factory, write_kpoints):
    # Negative KSPACING raises an error
    with pytest.raises(ValueError):
        write_kpoints(factory, kspacing=-0.5)


def test_weighted(atoms, testdir):
    # Explicit weighted points with nested lists, Cartesian if not specified
    string = format_kpoints(
        atoms=atoms,
        kpts=[[0.1, 0.2, 0.3, 2], [0.0, 0.0, 0.0, 1],
              [0.0, 0.5, 0.5, 2]])

    with open('KPOINTS', 'w') as fd:
        fd.write(string)

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

    assert filecmp_ignore_whitespace('KPOINTS', 'KPOINTS.ref')


def test_explicit_auto_weight(atoms, testdir):
    # Explicit points as list of tuples, automatic weighting = 1.
    string = format_kpoints(
        atoms=atoms,
        kpts=[(0.1, 0.2, 0.3), (0.0, 0.0, 0.0), (0.0, 0.5, 0.5)],
        reciprocal=True)

    with open('KPOINTS', 'w') as fd:
        fd.write(string)

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

    assert filecmp_ignore_whitespace('KPOINTS', 'KPOINTS.ref')


def test_bandpath(atoms):
    bandpath = atoms.cell.bandpath('GXMGRX,MR', npoints=100)
    string = format_kpoints(atoms=atoms, kpts=bandpath.kpts, reciprocal=True)
    check_kpoints_string(string, 1, '100')
    check_kpoints_string(string, 2, 'Reciprocal')
    check_kpoints_string(string, 3, '0.000000 0.000000 0.000000 1.0')
    check_kpoints_string(string, 102, '0.500000 0.500000 0.500000 1.0')