run_tests.py 11 KB
Newer Older
1
2
3
4
"""
This is a module for unit testing the CP2K parser. The unit tests are run with
a custom backend that outputs the results directly into native python object for
easier and faster analysis.
5
6
7
8
9
10
11

Each property that has an enumerable list of different possible options is
assigned a new test class, that should ideally test through all the options.

The properties that can have any value imaginable will be tested only for one
specific case inside a test class that is designed for a certain type of run
(MD, optimization, QM/MM, etc.)
12
13
14
15
16
17
18
19
20
21
"""
import os
import unittest
import logging
import numpy as np
from cp2kparser import CP2KParser
from nomadcore.unit_conversion.unit_conversion import convert_unit


#===============================================================================
22
def get_results(folder, metainfo_to_keep=None):
23
24
25
26
27
28
    """Get the given result from the calculation in the given folder by using
    the Analyzer in the nomadtoolkit package. Tries to optimize the parsing by
    giving the metainfo_to_keep argument.

    Args:
        folder: The folder relative to the directory of this script where the
29
            parsed calculation resides.
30
31
32
        metaname: The quantity to extract.
    """
    dirname = os.path.dirname(__file__)
33
34
    filename = os.path.join(dirname, folder, "unittest.out")
    parser = CP2KParser(filename, metainfo_to_keep)
35
    results = parser.parse()
36
37
38
39
40
41
    return results


#===============================================================================
def get_result(folder, metaname):
    results = get_results(folder, metaname)
42
    result = results[metaname]
Lauri Himanen's avatar
Lauri Himanen committed
43
    return result
44
45
46
47


#===============================================================================
class TestXCFunctional(unittest.TestCase):
48
49
    """Tests that the XC functionals can be properly parsed.
    """
50
51
52

    def test_pade(self):
        xc = get_result("XC_functional/pade", "XC_functional")
53
        self.assertEqual(xc, "1*LDA_XC_TETER93")
54
55
56

    def test_lda(self):
        xc = get_result("XC_functional/lda", "XC_functional")
57
        self.assertEqual(xc, "1*LDA_XC_TETER93")
58
59
60

    def test_blyp(self):
        xc = get_result("XC_functional/blyp", "XC_functional")
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
        self.assertEqual(xc, "1*GGA_C_LYP+1*GGA_X_B88")

    def test_b3lyp(self):
        xc = get_result("XC_functional/b3lyp", "XC_functional")
        self.assertEqual(xc, "1*HYB_GGA_XC_B3LYP")

    def test_olyp(self):
        xc = get_result("XC_functional/olyp", "XC_functional")
        self.assertEqual(xc, "1*GGA_C_LYP+1*GGA_X_OPTX")

    def test_hcth120(self):
        xc = get_result("XC_functional/hcth120", "XC_functional")
        self.assertEqual(xc, "1*GGA_XC_HCTH_120")

    def test_pbe0(self):
        xc = get_result("XC_functional/pbe0", "XC_functional")
        self.assertEqual(xc, "1*HYB_GGA_XC_PBEH")

    def test_pbe(self):
        xc = get_result("XC_functional/pbe", "XC_functional")
        self.assertEqual(xc, "1*GGA_C_PBE+1*GGA_X_PBE")
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
#===============================================================================
class TestSelfInteractionCorrectionMethod(unittest.TestCase):
    """Tests that the self-interaction correction can be properly parsed.
    """

    def test_no(self):
        sic = get_result("sic/no", "self_interaction_correction_method")
        self.assertEqual(sic, "")

    def test_ad(self):
        sic = get_result("sic/ad", "self_interaction_correction_method")
        self.assertEqual(sic, "SIC_AD")

    def test_explicit_orbitals(self):
        sic = get_result("sic/explicit_orbitals", "self_interaction_correction_method")
        self.assertEqual(sic, "SIC_EXPLICIT_ORBITALS")

    def test_mauri_spz(self):
        sic = get_result("sic/mauri_spz", "self_interaction_correction_method")
        self.assertEqual(sic, "SIC_MAURI_SPZ")

    def test_mauri_us(self):
        sic = get_result("sic/mauri_us", "self_interaction_correction_method")
        self.assertEqual(sic, "SIC_MAURI_US")


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
143
144
145
146
147
148
149
150
151
#===============================================================================
class TestConfigurationPeriodicDimensions(unittest.TestCase):
    """Tests that the self-interaction correction can be properly parsed.
    """

    def test_default(self):
        result = get_result("configuration_periodic_dimensions/default", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((True, True, True))))

    def test_none(self):
        result = get_result("configuration_periodic_dimensions/none", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((False, False, False))))

    def test_x(self):
        result = get_result("configuration_periodic_dimensions/x", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((True, False, False))))

    def test_y(self):
        result = get_result("configuration_periodic_dimensions/y", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((False, True, False))))

    def test_z(self):
        result = get_result("configuration_periodic_dimensions/z", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((False, False, True))))

    def test_xy(self):
        result = get_result("configuration_periodic_dimensions/xy", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((True, True, False))))

    def test_xyz(self):
        result = get_result("configuration_periodic_dimensions/xyz", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((True, True, True))))

    def test_xz(self):
        result = get_result("configuration_periodic_dimensions/xz", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((True, False, True))))

    def test_yz(self):
        result = get_result("configuration_periodic_dimensions/yz", "configuration_periodic_dimensions")
        self.assertTrue(np.array_equal(result, np.array((False, True, True))))


152
#===============================================================================
153
154
155
class TestEnergyForce(unittest.TestCase):
    """Tests for a CP2K calculation with RUN_TYPE ENERGY_FORCE.
    """
156

Lauri Himanen's avatar
Lauri Himanen committed
157
    def setUp(self):
158
        self.results = get_results("energy_force", "section_run")
159

160
    def test_energy_total_scf_iteration(self):
Lauri Himanen's avatar
Lauri Himanen committed
161
        energy_total = self.results["energy_total_scf_iteration"]
162
163
164
        expected_result = convert_unit(np.array(-32.2320848878), "hartree")
        self.assertTrue(np.array_equal(energy_total[0], expected_result))

165
166
167
168
169
170
171
172
173
174
    def test_energy_change_scf_iteration(self):
        energy_change = self.results["energy_change_scf_iteration"]
        expected_result = convert_unit(np.array(-3.22E+01), "hartree")
        self.assertTrue(np.array_equal(energy_change[0], expected_result))

    def test_energy_XC_scf_iteration(self):
        result = self.results["energy_XC_scf_iteration"]
        expected_result = convert_unit(np.array(-9.4555961214), "hartree")
        self.assertTrue(np.array_equal(result[0], expected_result))

175
    def test_energy_total(self):
Lauri Himanen's avatar
Lauri Himanen committed
176
        energy_total = self.results["energy_total"]
177
178
179
        expected_result = convert_unit(np.array(-31.297885372811063), "hartree")
        self.assertTrue(np.array_equal(energy_total, expected_result))

180
181
182
183
184
    def test_electronic_kinetic_energy(self):
        result = self.results["electronic_kinetic_energy"]
        expected_result = convert_unit(np.array(13.31525592466418), "hartree")
        self.assertTrue(np.array_equal(result, expected_result))

185
    def test_atom_forces(self):
Lauri Himanen's avatar
Lauri Himanen committed
186
        atomic_forces = self.results["atom_forces"]
187
188
189
190
191
192
193
194
195
196
197
        expected_result = convert_unit(
            np.array([
                [0.00000000, 0.00000000, 0.00000000],
                [0.00000000, 0.00000001, 0.00000001],
                [0.00000001, 0.00000001, 0.00000000],
                [0.00000001, 0.00000000, 0.00000001],
                [-0.00000001, -0.00000001, -0.00000001],
                [-0.00000001, -0.00000001, -0.00000001],
                [-0.00000001, -0.00000001, -0.00000001],
                [-0.00000001, -0.00000001, -0.00000001],
            ]),
198
            "forceAu"
199
200
201
        )
        self.assertTrue(np.array_equal(atomic_forces, expected_result))

202
    def test_atom_label(self):
Lauri Himanen's avatar
Lauri Himanen committed
203
        atom_labels = self.results["atom_label"]
Lauri Himanen's avatar
Lauri Himanen committed
204
205
206
207
        expected_labels = np.array(8*["Si"])
        self.assertTrue(np.array_equal(atom_labels, expected_labels))

    def test_simulation_cell(self):
Lauri Himanen's avatar
Lauri Himanen committed
208
        cell = self.results["simulation_cell"]
Lauri Himanen's avatar
Lauri Himanen committed
209
210
211
212
213
214
215
216
        n_vectors = cell.shape[0]
        n_dim = cell.shape[1]
        self.assertEqual(n_vectors, 3)
        self.assertEqual(n_dim, 3)
        expected_cell = convert_unit(np.array([[5.431, 0, 0], [0, 5.431, 0], [0, 0, 5.431]]), "angstrom")
        self.assertTrue(np.array_equal(cell, expected_cell))

    def test_number_of_atoms(self):
Lauri Himanen's avatar
Lauri Himanen committed
217
        n_atoms = self.results["number_of_atoms"]
Lauri Himanen's avatar
Lauri Himanen committed
218
219
220
        self.assertEqual(n_atoms, 8)

    def test_atom_position(self):
Lauri Himanen's avatar
Lauri Himanen committed
221
        atom_position = self.results["atom_position"]
Lauri Himanen's avatar
Lauri Himanen committed
222
223
224
        expected_position = convert_unit(np.array([4.073023, 4.073023, 1.357674]), "angstrom")
        self.assertTrue(np.array_equal(atom_position[-1, :], expected_position))

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
    def test_cp2k_filenames(self):
        input_filename = self.results["cp2k_input_filename"]
        expected_input = "si_bulk8.inp"
        self.assertTrue(input_filename, expected_input)

        bs_filename = self.results["cp2k_basis_set_filename"]
        expected_bs = "../BASIS_SET"
        self.assertEqual(bs_filename, expected_bs)

        geminal_filename = self.results["cp2k_geminal_filename"]
        expected_geminal = "BASIS_GEMINAL"
        self.assertEqual(geminal_filename, expected_geminal)

        potential_filename = self.results["cp2k_potential_filename"]
        expected_potential = "../GTH_POTENTIALS"
        self.assertEqual(potential_filename, expected_potential)

        mm_potential_filename = self.results["cp2k_mm_potential_filename"]
        expected_mm_potential = "MM_POTENTIAL"
        self.assertEqual(mm_potential_filename, expected_mm_potential)

        coordinate_filename = self.results["cp2k_coordinate_filename"]
        expected_coordinate = "__STD_INPUT__"
        self.assertEqual(coordinate_filename, expected_coordinate)
249

250
251
252
253
254
255
256
257
    def test_target_multiplicity(self):
        multiplicity = self.results["target_multiplicity"]
        self.assertEqual(multiplicity, 1)

    def test_total_charge(self):
        charge = self.results["total_charge"]
        self.assertEqual(charge, 0)

258
259
#===============================================================================
if __name__ == '__main__':
Lauri Himanen's avatar
Lauri Himanen committed
260
    pass
261
262
263
264
    logger = logging.getLogger("cp2kparser")
    logger.setLevel(logging.ERROR)

    suites = []
Lauri Himanen's avatar
Lauri Himanen committed
265
    suites.append(unittest.TestLoader().loadTestsFromTestCase(TestXCFunctional))
266
    suites.append(unittest.TestLoader().loadTestsFromTestCase(TestEnergyForce))
267
    suites.append(unittest.TestLoader().loadTestsFromTestCase(TestSelfInteractionCorrectionMethod))
268
    suites.append(unittest.TestLoader().loadTestsFromTestCase(TestConfigurationPeriodicDimensions))
269
270
    alltests = unittest.TestSuite(suites)
    unittest.TextTestRunner(verbosity=0).run(alltests)