• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

materialsproject / pymatgen / 4075885785

pending completion
4075885785

push

github

Shyue Ping Ong
Merge branch 'master' of github.com:materialsproject/pymatgen

96 of 96 new or added lines in 27 files covered. (100.0%)

81013 of 102710 relevant lines covered (78.88%)

0.79 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

99.12
/pymatgen/io/lobster/tests/test_lobster.py
1
# Copyright (c) Pymatgen Development Team.
2
# Distributed under the terms of the MIT License.
3

4
from __future__ import annotations
1✔
5

6
import json
1✔
7
import os
1✔
8
import tempfile
1✔
9
import unittest
1✔
10
import warnings
1✔
11

12
import numpy as np
1✔
13
import pytest
1✔
14
from pytest import approx
1✔
15

16
from pymatgen.core.structure import Structure
1✔
17
from pymatgen.electronic_structure.core import Orbital, Spin
1✔
18
from pymatgen.io.lobster import (
1✔
19
    Bandoverlaps,
20
    Charge,
21
    Cohpcar,
22
    Doscar,
23
    Fatband,
24
    Grosspop,
25
    Icohplist,
26
    Lobsterin,
27
    Lobsterout,
28
    MadelungEnergies,
29
    SitePotential,
30
    Wavefunction,
31
)
32
from pymatgen.io.lobster.inputs import get_all_possible_basis_combinations
1✔
33
from pymatgen.io.vasp import Vasprun
1✔
34
from pymatgen.io.vasp.inputs import Incar, Kpoints, Potcar
1✔
35
from pymatgen.util.testing import PymatgenTest
1✔
36

37
__author__ = "Janine George, Marco Esters"
1✔
38
__copyright__ = "Copyright 2017, The Materials Project"
1✔
39
__version__ = "0.2"
1✔
40
__email__ = "janine.george@uclouvain.be, esters@uoregon.edu"
1✔
41
__date__ = "Dec 10, 2017"
1✔
42

43
test_dir_doscar = PymatgenTest.TEST_FILES_DIR
1✔
44

45
this_dir = os.path.dirname(os.path.abspath(__file__))
1✔
46

47

48
class CohpcarTest(PymatgenTest):
1✔
49
    def setUp(self):
1✔
50
        self.cohp_bise = Cohpcar(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COHPCAR.lobster.BiSe"))
1✔
51
        self.coop_bise = Cohpcar(
1✔
52
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COOPCAR.lobster.BiSe"),
53
            are_coops=True,
54
        )
55
        self.cohp_fe = Cohpcar(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COOPCAR.lobster"))
1✔
56
        self.coop_fe = Cohpcar(
1✔
57
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COOPCAR.lobster"),
58
            are_coops=True,
59
        )
60
        self.orb = Cohpcar(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COHPCAR.lobster.orbitalwise"))
1✔
61
        self.orb_notot = Cohpcar(
1✔
62
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COHPCAR.lobster.notot.orbitalwise")
63
        )
64

65
        # Lobster 3.1 (Test data is from prerelease of Lobster 3.1)
66
        self.cohp_KF = Cohpcar(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COHPCAR.lobster.KF"))
1✔
67
        self.coop_KF = Cohpcar(
1✔
68
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COHPCAR.lobster.KF"),
69
            are_coops=True,
70
        )
71

72
        # example with f electrons
73
        self.cohp_Na2UO4 = Cohpcar(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COHPCAR.lobster.Na2UO4"))
1✔
74
        self.coop_Na2UO4 = Cohpcar(
1✔
75
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COOPCAR.lobster.Na2UO4"),
76
            are_coops=True,
77
        )
78
        self.cobi = Cohpcar(
1✔
79
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "COBICAR.lobster"),
80
            are_cobis=True,
81
        )
82

83
    def test_attributes(self):
1✔
84
        assert not self.cohp_bise.are_coops
1✔
85
        assert self.coop_bise.are_coops
1✔
86
        assert not self.cohp_bise.is_spin_polarized
1✔
87
        assert not self.coop_bise.is_spin_polarized
1✔
88
        assert not self.cohp_fe.are_coops
1✔
89
        assert self.coop_fe.are_coops
1✔
90
        assert self.cohp_fe.is_spin_polarized
1✔
91
        assert self.coop_fe.is_spin_polarized
1✔
92
        assert len(self.cohp_bise.energies) == 241
1✔
93
        assert len(self.coop_bise.energies) == 241
1✔
94
        assert len(self.cohp_fe.energies) == 301
1✔
95
        assert len(self.coop_fe.energies) == 301
1✔
96
        assert len(self.cohp_bise.cohp_data) == 12
1✔
97
        assert len(self.coop_bise.cohp_data) == 12
1✔
98
        assert len(self.cohp_fe.cohp_data) == 3
1✔
99
        assert len(self.coop_fe.cohp_data) == 3
1✔
100

101
        # Lobster 3.1
102
        assert not self.cohp_KF.are_coops
1✔
103
        assert self.coop_KF.are_coops
1✔
104
        assert not self.cohp_KF.is_spin_polarized
1✔
105
        assert not self.coop_KF.is_spin_polarized
1✔
106
        assert len(self.cohp_KF.energies) == 6
1✔
107
        assert len(self.coop_KF.energies) == 6
1✔
108
        assert len(self.cohp_KF.cohp_data) == 7
1✔
109
        assert len(self.coop_KF.cohp_data) == 7
1✔
110

111
        # Lobster 4.1.0
112
        assert not self.cohp_KF.are_cobis
1✔
113
        assert not self.coop_KF.are_cobis
1✔
114
        assert not self.cobi.are_coops
1✔
115
        assert self.cobi.are_cobis
1✔
116
        assert not self.cobi.is_spin_polarized
1✔
117

118
    def test_energies(self):
1✔
119
        efermi_bise = 5.90043
1✔
120
        elim_bise = (-0.124679, 11.9255)
1✔
121
        efermi_fe = 9.75576
1✔
122
        elim_fe = (-0.277681, 14.7725)
1✔
123
        efermi_KF = -2.87475
1✔
124
        elim_KF = (-11.25000 + efermi_KF, 7.5000 + efermi_KF)
1✔
125

126
        assert self.cohp_bise.efermi == efermi_bise
1✔
127
        assert self.coop_bise.efermi == efermi_bise
1✔
128
        assert self.cohp_fe.efermi == efermi_fe
1✔
129
        assert self.coop_fe.efermi == efermi_fe
1✔
130
        # Lobster 3.1
131
        assert self.cohp_KF.efermi == efermi_KF
1✔
132
        assert self.coop_KF.efermi == efermi_KF
1✔
133

134
        assert self.cohp_bise.energies[0] + self.cohp_bise.efermi == approx(elim_bise[0], abs=1e-4)
1✔
135
        assert self.cohp_bise.energies[-1] + self.cohp_bise.efermi == approx(elim_bise[1], abs=1e-4)
1✔
136
        assert self.coop_bise.energies[0] + self.coop_bise.efermi == approx(elim_bise[0], abs=1e-4)
1✔
137
        assert self.coop_bise.energies[-1] + self.coop_bise.efermi == approx(elim_bise[1], abs=1e-4)
1✔
138

139
        assert self.cohp_fe.energies[0] + self.cohp_fe.efermi == approx(elim_fe[0], abs=1e-4)
1✔
140
        assert self.cohp_fe.energies[-1] + self.cohp_fe.efermi == approx(elim_fe[1], abs=1e-4)
1✔
141
        assert self.coop_fe.energies[0] + self.coop_fe.efermi == approx(elim_fe[0], abs=1e-4)
1✔
142
        assert self.coop_fe.energies[-1] + self.coop_fe.efermi == approx(elim_fe[1], abs=1e-4)
1✔
143

144
        # Lobster 3.1
145
        assert self.cohp_KF.energies[0] + self.cohp_KF.efermi == approx(elim_KF[0], abs=1e-4)
1✔
146
        assert self.cohp_KF.energies[-1] + self.cohp_KF.efermi == approx(elim_KF[1], abs=1e-4)
1✔
147
        assert self.coop_KF.energies[0] + self.coop_KF.efermi == approx(elim_KF[0], abs=1e-4)
1✔
148
        assert self.coop_KF.energies[-1] + self.coop_KF.efermi == approx(elim_KF[1], abs=1e-4)
1✔
149

150
    def test_cohp_data(self):
1✔
151
        lengths_sites_bise = {
1✔
152
            "1": (2.882308829886294, (0, 6)),
153
            "2": (3.1014396233274444, (0, 9)),
154
            "3": (2.8823088298862083, (1, 7)),
155
            "4": (3.1014396233275434, (1, 8)),
156
            "5": (3.0500070394403904, (2, 9)),
157
            "6": (2.9167594580335807, (2, 10)),
158
            "7": (3.05000703944039, (3, 8)),
159
            "8": (2.9167594580335803, (3, 11)),
160
            "9": (3.3752173204052101, (4, 11)),
161
            "10": (3.0729354518345948, (4, 5)),
162
            "11": (3.3752173204052101, (5, 10)),
163
        }
164
        lengths_sites_fe = {
1✔
165
            "1": (2.8318907764979082, (7, 6)),
166
            "2": (2.4524893531900283, (7, 8)),
167
        }
168
        # Lobster 3.1
169
        lengths_sites_KF = {
1✔
170
            "1": (2.7119923200622269, (0, 1)),
171
            "2": (2.7119923200622269, (0, 1)),
172
            "3": (2.7119923576010501, (0, 1)),
173
            "4": (2.7119923576010501, (0, 1)),
174
            "5": (2.7119923200622269, (0, 1)),
175
            "6": (2.7119923200622269, (0, 1)),
176
        }
177

178
        for data in [self.cohp_bise.cohp_data, self.coop_bise.cohp_data]:
1✔
179
            for bond, val in data.items():
1✔
180
                if bond != "average":
1✔
181
                    assert val["length"] == lengths_sites_bise[bond][0]
1✔
182
                    assert val["sites"] == lengths_sites_bise[bond][1]
1✔
183
                    assert len(val["COHP"][Spin.up]) == 241
1✔
184
                    assert len(val["ICOHP"][Spin.up]) == 241
1✔
185
        for data in [self.cohp_fe.cohp_data, self.coop_fe.cohp_data]:
1✔
186
            for bond, val in data.items():
1✔
187
                if bond != "average":
1✔
188
                    assert val["length"] == lengths_sites_fe[bond][0]
1✔
189
                    assert val["sites"] == lengths_sites_fe[bond][1]
1✔
190
                    assert len(val["COHP"][Spin.up]) == 301
1✔
191
                    assert len(val["ICOHP"][Spin.up]) == 301
1✔
192

193
        # Lobster 3.1
194
        for data in [self.cohp_KF.cohp_data, self.coop_KF.cohp_data]:
1✔
195
            for bond, val in data.items():
1✔
196
                if bond != "average":
1✔
197
                    assert val["length"] == lengths_sites_KF[bond][0]
1✔
198
                    assert val["sites"] == lengths_sites_KF[bond][1]
1✔
199
                    assert len(val["COHP"][Spin.up]) == 6
1✔
200
                    assert len(val["ICOHP"][Spin.up]) == 6
1✔
201

202
    def test_orbital_resolved_cohp(self):
1✔
203
        orbitals = [tuple((Orbital(i), Orbital(j))) for j in range(4) for i in range(4)]
1✔
204
        assert self.cohp_bise.orb_res_cohp is None
1✔
205
        assert self.coop_bise.orb_res_cohp is None
1✔
206
        assert self.cohp_fe.orb_res_cohp is None
1✔
207
        assert self.coop_fe.orb_res_cohp is None
1✔
208
        assert self.orb_notot.cohp_data["1"]["COHP"] is None
1✔
209
        assert self.orb_notot.cohp_data["1"]["ICOHP"] is None
1✔
210
        for orbs in self.orb.orb_res_cohp["1"]:
1✔
211
            orb_set = self.orb.orb_res_cohp["1"][orbs]["orbitals"]
1✔
212
            assert orb_set[0][0] == 4
1✔
213
            assert orb_set[1][0] == 4
1✔
214
            assert tuple((orb_set[0][1], orb_set[1][1])) in orbitals
1✔
215

216
        # test d and f orbitals
217
        comparelist = [
1✔
218
            5,
219
            5,
220
            5,
221
            5,
222
            5,
223
            5,
224
            5,
225
            5,
226
            5,
227
            5,
228
            5,
229
            5,
230
            5,
231
            5,
232
            5,
233
            5,
234
            5,
235
            5,
236
            5,
237
            5,
238
            5,
239
            5,
240
            5,
241
            5,
242
            5,
243
            5,
244
            5,
245
            5,
246
            6,
247
            6,
248
            6,
249
            6,
250
            6,
251
            6,
252
            6,
253
            6,
254
            6,
255
            6,
256
            6,
257
            6,
258
            6,
259
            6,
260
            6,
261
            6,
262
            6,
263
            6,
264
            6,
265
            6,
266
            6,
267
            6,
268
            6,
269
            6,
270
            6,
271
            6,
272
            6,
273
            6,
274
            6,
275
            6,
276
            6,
277
            6,
278
            6,
279
            6,
280
            6,
281
            6,
282
            7,
283
            7,
284
            7,
285
            7,
286
        ]
287
        comparelist2 = [
1✔
288
            "f0",
289
            "f0",
290
            "f0",
291
            "f0",
292
            "f1",
293
            "f1",
294
            "f1",
295
            "f1",
296
            "f2",
297
            "f2",
298
            "f2",
299
            "f2",
300
            "f3",
301
            "f3",
302
            "f3",
303
            "f3",
304
            "f_1",
305
            "f_1",
306
            "f_1",
307
            "f_1",
308
            "f_2",
309
            "f_2",
310
            "f_2",
311
            "f_2",
312
            "f_3",
313
            "f_3",
314
            "f_3",
315
            "f_3",
316
            "dx2",
317
            "dx2",
318
            "dx2",
319
            "dx2",
320
            "dxy",
321
            "dxy",
322
            "dxy",
323
            "dxy",
324
            "dxz",
325
            "dxz",
326
            "dxz",
327
            "dxz",
328
            "dyz",
329
            "dyz",
330
            "dyz",
331
            "dyz",
332
            "dz2",
333
            "dz2",
334
            "dz2",
335
            "dz2",
336
            "px",
337
            "px",
338
            "px",
339
            "px",
340
            "py",
341
            "py",
342
            "py",
343
            "py",
344
            "pz",
345
            "pz",
346
            "pz",
347
            "pz",
348
            "s",
349
            "s",
350
            "s",
351
            "s",
352
            "s",
353
            "s",
354
            "s",
355
            "s",
356
        ]
357
        for iorb, orbs in enumerate(sorted(self.cohp_Na2UO4.orb_res_cohp["49"])):
1✔
358
            orb_set = self.cohp_Na2UO4.orb_res_cohp["49"][orbs]["orbitals"]
1✔
359
            assert orb_set[0][0] == comparelist[iorb]
1✔
360
            assert str(orb_set[0][1]) == comparelist2[iorb]
1✔
361

362
        # The sum of the orbital-resolved COHPs should be approximately
363
        # the total COHP. Due to small deviations in the LOBSTER calculation,
364
        # the precision is not very high though.
365
        cohp = self.orb.cohp_data["1"]["COHP"][Spin.up]
1✔
366
        icohp = self.orb.cohp_data["1"]["ICOHP"][Spin.up]
1✔
367
        tot = np.sum(
1✔
368
            [self.orb.orb_res_cohp["1"][orbs]["COHP"][Spin.up] for orbs in self.orb.orb_res_cohp["1"]],
369
            axis=0,
370
        )
371
        self.assertArrayAlmostEqual(tot, cohp, decimal=3)
1✔
372
        tot = np.sum(
1✔
373
            [self.orb.orb_res_cohp["1"][orbs]["ICOHP"][Spin.up] for orbs in self.orb.orb_res_cohp["1"]],
374
            axis=0,
375
        )
376
        self.assertArrayAlmostEqual(tot, icohp, decimal=3)
1✔
377

378
        # Lobster 3.1
379
        cohp_KF = self.cohp_KF.cohp_data["1"]["COHP"][Spin.up]
1✔
380
        icohp_KF = self.cohp_KF.cohp_data["1"]["ICOHP"][Spin.up]
1✔
381
        tot_KF = np.sum(
1✔
382
            [self.cohp_KF.orb_res_cohp["1"][orbs]["COHP"][Spin.up] for orbs in self.cohp_KF.orb_res_cohp["1"]],
383
            axis=0,
384
        )
385
        self.assertArrayAlmostEqual(tot_KF, cohp_KF, decimal=3)
1✔
386
        tot_KF = np.sum(
1✔
387
            [self.cohp_KF.orb_res_cohp["1"][orbs]["ICOHP"][Spin.up] for orbs in self.cohp_KF.orb_res_cohp["1"]],
388
            axis=0,
389
        )
390
        self.assertArrayAlmostEqual(tot_KF, icohp_KF, decimal=3)
1✔
391

392
        # d and f orbitals
393
        cohp_Na2UO4 = self.cohp_Na2UO4.cohp_data["49"]["COHP"][Spin.up]
1✔
394
        icohp_Na2UO4 = self.cohp_Na2UO4.cohp_data["49"]["ICOHP"][Spin.up]
1✔
395
        tot_Na2UO4 = np.sum(
1✔
396
            [
397
                self.cohp_Na2UO4.orb_res_cohp["49"][orbs]["COHP"][Spin.up]
398
                for orbs in self.cohp_Na2UO4.orb_res_cohp["49"]
399
            ],
400
            axis=0,
401
        )
402
        self.assertArrayAlmostEqual(tot_Na2UO4, cohp_Na2UO4, decimal=3)
1✔
403
        tot_Na2UO4 = np.sum(
1✔
404
            [
405
                self.cohp_Na2UO4.orb_res_cohp["49"][orbs]["ICOHP"][Spin.up]
406
                for orbs in self.cohp_Na2UO4.orb_res_cohp["49"]
407
            ],
408
            axis=0,
409
        )
410
        self.assertArrayAlmostEqual(tot_Na2UO4, icohp_Na2UO4, decimal=3)
1✔
411

412

413
class IcohplistTest(unittest.TestCase):
1✔
414
    def setUp(self):
1✔
415
        self.icohp_bise = Icohplist(
1✔
416
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOHPLIST.lobster.BiSe")
417
        )
418
        self.icoop_bise = Icohplist(
1✔
419
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOOPLIST.lobster.BiSe"),
420
            are_coops=True,
421
        )
422
        self.icohp_fe = Icohplist(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOHPLIST.lobster"))
1✔
423
        # allow gzipped files
424
        self.icohp_gzipped = Icohplist(
1✔
425
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOHPLIST.lobster.gz")
426
        )
427
        self.icoop_fe = Icohplist(
1✔
428
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOHPLIST.lobster"),
429
            are_coops=True,
430
        )
431
        # ICOBIs and orbitalwise ICOBILIST.lobster
432
        self.icobi_orbitalwise = Icohplist(
1✔
433
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOBILIST.lobster"),
434
            are_cobis=True,
435
        )
436
        # TODO: test orbitalwise ICOHPs with and without spin polarization
437

438
        self.icobi = Icohplist(
1✔
439
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOBILIST.lobster.withoutorbitals"),
440
            are_cobis=True,
441
        )
442
        self.icobi_orbitalwise_spinpolarized = Icohplist(
1✔
443
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOBILIST.lobster.spinpolarized"),
444
            are_cobis=True,
445
        )
446
        # make sure the correct line is read to check if this is a orbitalwise ICOBILIST
447
        self.icobi_orbitalwise_add = Icohplist(
1✔
448
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "ICOBILIST.lobster.additional_case"),
449
            are_cobis=True,
450
        )
451
        self.icobi_orbitalwise_spinpolarized_add = Icohplist(
1✔
452
            filename=os.path.join(
453
                PymatgenTest.TEST_FILES_DIR,
454
                "cohp",
455
                "ICOBILIST.lobster.spinpolarized.additional_case",
456
            ),
457
            are_cobis=True,
458
        )
459

460
    def test_attributes(self):
1✔
461
        assert not self.icohp_bise.are_coops
1✔
462
        assert self.icoop_bise.are_coops
1✔
463
        assert not self.icohp_bise.is_spin_polarized
1✔
464
        assert not self.icoop_bise.is_spin_polarized
1✔
465
        assert len(self.icohp_bise.icohplist) == 11
1✔
466
        assert len(self.icoop_bise.icohplist) == 11
1✔
467
        assert not self.icohp_fe.are_coops
1✔
468
        assert self.icoop_fe.are_coops
1✔
469
        assert self.icohp_fe.is_spin_polarized
1✔
470
        assert self.icoop_fe.is_spin_polarized
1✔
471
        assert len(self.icohp_fe.icohplist) == 2
1✔
472
        assert len(self.icoop_fe.icohplist) == 2
1✔
473
        # test are_cobis
474
        assert not self.icohp_fe.are_coops
1✔
475
        assert not self.icohp_fe.are_cobis
1✔
476
        assert self.icoop_fe.are_coops
1✔
477
        assert not self.icoop_fe.are_cobis
1✔
478
        assert self.icobi.are_cobis
1✔
479
        assert not self.icobi.are_coops
1✔
480

481
        # orbitalwise
482
        assert self.icobi_orbitalwise.orbitalwise
1✔
483
        assert not self.icobi.orbitalwise
1✔
484

485
        assert self.icobi_orbitalwise_spinpolarized.orbitalwise
1✔
486

487
        assert self.icobi_orbitalwise_add.orbitalwise
1✔
488
        assert self.icobi_orbitalwise_spinpolarized_add.orbitalwise
1✔
489

490
    def test_values(self):
1✔
491
        icohplist_bise = {
1✔
492
            "1": {
493
                "length": 2.88231,
494
                "number_of_bonds": 3,
495
                "icohp": {Spin.up: -2.18042},
496
                "translation": [0, 0, 0],
497
            },
498
            "2": {
499
                "length": 3.10144,
500
                "number_of_bonds": 3,
501
                "icohp": {Spin.up: -1.14347},
502
                "translation": [0, 0, 0],
503
            },
504
            "3": {
505
                "length": 2.88231,
506
                "number_of_bonds": 3,
507
                "icohp": {Spin.up: -2.18042},
508
                "translation": [0, 0, 0],
509
            },
510
            "4": {
511
                "length": 3.10144,
512
                "number_of_bonds": 3,
513
                "icohp": {Spin.up: -1.14348},
514
                "translation": [0, 0, 0],
515
            },
516
            "5": {
517
                "length": 3.05001,
518
                "number_of_bonds": 3,
519
                "icohp": {Spin.up: -1.30006},
520
                "translation": [0, 0, 0],
521
            },
522
            "6": {
523
                "length": 2.91676,
524
                "number_of_bonds": 3,
525
                "icohp": {Spin.up: -1.96843},
526
                "translation": [0, 0, 0],
527
            },
528
            "7": {
529
                "length": 3.05001,
530
                "number_of_bonds": 3,
531
                "icohp": {Spin.up: -1.30006},
532
                "translation": [0, 0, 0],
533
            },
534
            "8": {
535
                "length": 2.91676,
536
                "number_of_bonds": 3,
537
                "icohp": {Spin.up: -1.96843},
538
                "translation": [0, 0, 0],
539
            },
540
            "9": {
541
                "length": 3.37522,
542
                "number_of_bonds": 3,
543
                "icohp": {Spin.up: -0.47531},
544
                "translation": [0, 0, 0],
545
            },
546
            "10": {
547
                "length": 3.07294,
548
                "number_of_bonds": 3,
549
                "icohp": {Spin.up: -2.38796},
550
                "translation": [0, 0, 0],
551
            },
552
            "11": {
553
                "length": 3.37522,
554
                "number_of_bonds": 3,
555
                "icohp": {Spin.up: -0.47531},
556
                "translation": [0, 0, 0],
557
            },
558
        }
559
        icooplist_bise = {
1✔
560
            "1": {
561
                "length": 2.88231,
562
                "number_of_bonds": 3,
563
                "icohp": {Spin.up: 0.14245},
564
                "translation": [0, 0, 0],
565
            },
566
            "2": {
567
                "length": 3.10144,
568
                "number_of_bonds": 3,
569
                "icohp": {Spin.up: -0.04118},
570
                "translation": [0, 0, 0],
571
            },
572
            "3": {
573
                "length": 2.88231,
574
                "number_of_bonds": 3,
575
                "icohp": {Spin.up: 0.14245},
576
                "translation": [0, 0, 0],
577
            },
578
            "4": {
579
                "length": 3.10144,
580
                "number_of_bonds": 3,
581
                "icohp": {Spin.up: -0.04118},
582
                "translation": [0, 0, 0],
583
            },
584
            "5": {
585
                "length": 3.05001,
586
                "number_of_bonds": 3,
587
                "icohp": {Spin.up: -0.03516},
588
                "translation": [0, 0, 0],
589
            },
590
            "6": {
591
                "length": 2.91676,
592
                "number_of_bonds": 3,
593
                "icohp": {Spin.up: 0.10745},
594
                "translation": [0, 0, 0],
595
            },
596
            "7": {
597
                "length": 3.05001,
598
                "number_of_bonds": 3,
599
                "icohp": {Spin.up: -0.03516},
600
                "translation": [0, 0, 0],
601
            },
602
            "8": {
603
                "length": 2.91676,
604
                "number_of_bonds": 3,
605
                "icohp": {Spin.up: 0.10745},
606
                "translation": [0, 0, 0],
607
            },
608
            "9": {
609
                "length": 3.37522,
610
                "number_of_bonds": 3,
611
                "icohp": {Spin.up: -0.12395},
612
                "translation": [0, 0, 0],
613
            },
614
            "10": {
615
                "length": 3.07294,
616
                "number_of_bonds": 3,
617
                "icohp": {Spin.up: 0.24714},
618
                "translation": [0, 0, 0],
619
            },
620
            "11": {
621
                "length": 3.37522,
622
                "number_of_bonds": 3,
623
                "icohp": {Spin.up: -0.12395},
624
                "translation": [0, 0, 0],
625
            },
626
        }
627
        icooplist_fe = {
1✔
628
            "1": {
629
                "length": 2.83189,
630
                "number_of_bonds": 2,
631
                "icohp": {Spin.up: -0.10218, Spin.down: -0.19701},
632
                "translation": [0, 0, 0],
633
            },
634
            "2": {
635
                "length": 2.45249,
636
                "number_of_bonds": 1,
637
                "icohp": {Spin.up: -0.28485, Spin.down: -0.58279},
638
                "translation": [0, 0, 0],
639
            },
640
        }
641

642
        assert icohplist_bise == self.icohp_bise.icohplist
1✔
643
        assert -2.38796 == self.icohp_bise.icohpcollection.extremum_icohpvalue()
1✔
644
        assert icooplist_fe == self.icoop_fe.icohplist
1✔
645
        assert -0.29919 == self.icoop_fe.icohpcollection.extremum_icohpvalue()
1✔
646
        assert icooplist_bise == self.icoop_bise.icohplist
1✔
647
        assert 0.24714 == self.icoop_bise.icohpcollection.extremum_icohpvalue()
1✔
648
        assert self.icobi.icohplist["1"]["icohp"][Spin.up] == approx(0.58649)
1✔
649
        assert self.icobi_orbitalwise.icohplist["2"]["icohp"][Spin.up] == approx(0.58649)
1✔
650
        assert self.icobi_orbitalwise.icohplist["1"]["icohp"][Spin.up] == approx(0.58649)
1✔
651
        assert self.icobi_orbitalwise_spinpolarized.icohplist["1"]["icohp"][Spin.up] == approx(0.58649 / 2, abs=1e-3)
1✔
652
        assert self.icobi_orbitalwise_spinpolarized.icohplist["1"]["icohp"][Spin.down] == approx(0.58649 / 2, abs=1e-3)
1✔
653
        assert self.icobi_orbitalwise_spinpolarized.icohplist["2"]["icohp"][Spin.down] == approx(0.58649 / 2, abs=1e-3)
1✔
654
        assert 0.58649 == self.icobi.icohpcollection.extremum_icohpvalue()
1✔
655

656

657
class DoscarTest(unittest.TestCase):
1✔
658
    def setUp(self):
1✔
659
        # first for spin polarized version
660
        doscar = os.path.join(test_dir_doscar, "DOSCAR.lobster.spin")
1✔
661
        poscar = os.path.join(test_dir_doscar, "POSCAR.lobster.spin_DOS")
1✔
662
        # not spin polarized
663
        doscar2 = os.path.join(test_dir_doscar, "DOSCAR.lobster.nonspin")
1✔
664
        poscar2 = os.path.join(test_dir_doscar, "POSCAR.lobster.nonspin_DOS")
1✔
665
        os.path.join(test_dir_doscar, "DOSCAR.lobster.nonspin_zip.gz")
1✔
666
        os.path.join(test_dir_doscar, "POSCAR.lobster.nonspin_DOS_zip.gz")
1✔
667
        self.DOSCAR_spin_pol = Doscar(doscar=doscar, structure_file=poscar)
1✔
668
        self.DOSCAR_nonspin_pol = Doscar(doscar=doscar2, structure_file=poscar2)
1✔
669

670
        self.DOSCAR_spin_pol = Doscar(doscar=doscar, structure_file=poscar)
1✔
671
        self.DOSCAR_nonspin_pol = Doscar(doscar=doscar2, structure_file=poscar2)
1✔
672

673
        with open(os.path.join(test_dir_doscar, "structure_KF.json")) as f:
1✔
674
            data = json.load(f)
1✔
675

676
        self.structure = Structure.from_dict(data)
1✔
677

678
    def test_completedos(self):
1✔
679
        # first for spin polarized version
680
        energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
1✔
681
        tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577]
1✔
682
        tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586]
1✔
683
        fermi = 0.0
1✔
684

685
        PDOS_F_2s_up = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
1✔
686
        PDOS_F_2s_down = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
1✔
687
        PDOS_F_2py_up = [0.00000, 0.00160, 0.00000, 0.25801, 0.00000, 0.00029]
1✔
688
        PDOS_F_2py_down = [0.00000, 0.00161, 0.00000, 0.25819, 0.00000, 0.00029]
1✔
689
        PDOS_F_2pz_up = [0.00000, 0.00161, 0.00000, 0.25823, 0.00000, 0.00029]
1✔
690
        PDOS_F_2pz_down = [0.00000, 0.00160, 0.00000, 0.25795, 0.00000, 0.00029]
1✔
691
        PDOS_F_2px_up = [0.00000, 0.00160, 0.00000, 0.25805, 0.00000, 0.00029]
1✔
692
        PDOS_F_2px_down = [0.00000, 0.00161, 0.00000, 0.25814, 0.00000, 0.00029]
1✔
693

694
        assert energies_spin == self.DOSCAR_spin_pol.completedos.energies.tolist()
1✔
695
        assert tdos_up == self.DOSCAR_spin_pol.completedos.densities[Spin.up].tolist()
1✔
696
        assert tdos_down == self.DOSCAR_spin_pol.completedos.densities[Spin.down].tolist()
1✔
697
        assert fermi == approx(self.DOSCAR_spin_pol.completedos.efermi)
1✔
698
        for coords, coords2 in zip(
1✔
699
            self.DOSCAR_spin_pol.completedos.structure.frac_coords,
700
            self.structure.frac_coords,
701
        ):
702
            for xyz, xyz2 in zip(coords, coords2):
1✔
703
                assert xyz == approx(xyz2)
1✔
704
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.up].tolist() == PDOS_F_2s_up
1✔
705
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.down].tolist() == PDOS_F_2s_down
1✔
706
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.up].tolist() == PDOS_F_2py_up
1✔
707
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.down].tolist() == PDOS_F_2py_down
1✔
708
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.up].tolist() == PDOS_F_2pz_up
1✔
709
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.down].tolist() == PDOS_F_2pz_down
1✔
710
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.up].tolist() == PDOS_F_2px_up
1✔
711
        assert self.DOSCAR_spin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.down].tolist() == PDOS_F_2px_down
1✔
712

713
        energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
1✔
714
        tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418]
1✔
715
        PDOS_F_2s = [0.00000, 0.00320, 0.00000, 0.00017, 0.00000, 0.00060]
1✔
716
        PDOS_F_2py = [0.00000, 0.00322, 0.00000, 0.51635, 0.00000, 0.00037]
1✔
717
        PDOS_F_2pz = [0.00000, 0.00322, 0.00000, 0.51636, 0.00000, 0.00037]
1✔
718
        PDOS_F_2px = [0.00000, 0.00322, 0.00000, 0.51634, 0.00000, 0.00037]
1✔
719

720
        assert energies_nonspin == self.DOSCAR_nonspin_pol.completedos.energies.tolist()
1✔
721

722
        assert tdos_nonspin == self.DOSCAR_nonspin_pol.completedos.densities[Spin.up].tolist()
1✔
723

724
        assert fermi == approx(self.DOSCAR_nonspin_pol.completedos.efermi)
1✔
725
        assert self.DOSCAR_nonspin_pol.completedos.structure.as_dict() == self.structure.as_dict()
1✔
726

727
        assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2s"][Spin.up].tolist() == PDOS_F_2s
1✔
728
        assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_y"][Spin.up].tolist() == PDOS_F_2py
1✔
729
        assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_z"][Spin.up].tolist() == PDOS_F_2pz
1✔
730
        assert self.DOSCAR_nonspin_pol.completedos.pdos[self.structure[0]]["2p_x"][Spin.up].tolist() == PDOS_F_2px
1✔
731

732
    def test_pdos(self):
1✔
733
        # first for spin polarized version
734

735
        PDOS_F_2s_up = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
1✔
736
        PDOS_F_2s_down = [0.00000, 0.00159, 0.00000, 0.00011, 0.00000, 0.00069]
1✔
737
        PDOS_F_2py_up = [0.00000, 0.00160, 0.00000, 0.25801, 0.00000, 0.00029]
1✔
738
        PDOS_F_2py_down = [0.00000, 0.00161, 0.00000, 0.25819, 0.00000, 0.00029]
1✔
739
        PDOS_F_2pz_up = [0.00000, 0.00161, 0.00000, 0.25823, 0.00000, 0.00029]
1✔
740
        PDOS_F_2pz_down = [0.00000, 0.00160, 0.00000, 0.25795, 0.00000, 0.00029]
1✔
741
        PDOS_F_2px_up = [0.00000, 0.00160, 0.00000, 0.25805, 0.00000, 0.00029]
1✔
742
        PDOS_F_2px_down = [0.00000, 0.00161, 0.00000, 0.25814, 0.00000, 0.00029]
1✔
743

744
        assert self.DOSCAR_spin_pol.pdos[0]["2s"][Spin.up].tolist() == PDOS_F_2s_up
1✔
745
        assert self.DOSCAR_spin_pol.pdos[0]["2s"][Spin.down].tolist() == PDOS_F_2s_down
1✔
746
        assert self.DOSCAR_spin_pol.pdos[0]["2p_y"][Spin.up].tolist() == PDOS_F_2py_up
1✔
747
        assert self.DOSCAR_spin_pol.pdos[0]["2p_y"][Spin.down].tolist() == PDOS_F_2py_down
1✔
748
        assert self.DOSCAR_spin_pol.pdos[0]["2p_z"][Spin.up].tolist() == PDOS_F_2pz_up
1✔
749
        assert self.DOSCAR_spin_pol.pdos[0]["2p_z"][Spin.down].tolist() == PDOS_F_2pz_down
1✔
750
        assert self.DOSCAR_spin_pol.pdos[0]["2p_x"][Spin.up].tolist() == PDOS_F_2px_up
1✔
751
        assert self.DOSCAR_spin_pol.pdos[0]["2p_x"][Spin.down].tolist() == PDOS_F_2px_down
1✔
752

753
        # non spin
754
        PDOS_F_2s = [0.00000, 0.00320, 0.00000, 0.00017, 0.00000, 0.00060]
1✔
755
        PDOS_F_2py = [0.00000, 0.00322, 0.00000, 0.51635, 0.00000, 0.00037]
1✔
756
        PDOS_F_2pz = [0.00000, 0.00322, 0.00000, 0.51636, 0.00000, 0.00037]
1✔
757
        PDOS_F_2px = [0.00000, 0.00322, 0.00000, 0.51634, 0.00000, 0.00037]
1✔
758

759
        assert self.DOSCAR_nonspin_pol.pdos[0]["2s"][Spin.up].tolist() == PDOS_F_2s
1✔
760
        assert self.DOSCAR_nonspin_pol.pdos[0]["2p_y"][Spin.up].tolist() == PDOS_F_2py
1✔
761
        assert self.DOSCAR_nonspin_pol.pdos[0]["2p_z"][Spin.up].tolist() == PDOS_F_2pz
1✔
762
        assert self.DOSCAR_nonspin_pol.pdos[0]["2p_x"][Spin.up].tolist() == PDOS_F_2px
1✔
763

764
    def test_tdos(self):
1✔
765
        # first for spin polarized version
766
        energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
1✔
767
        tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577]
1✔
768
        tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586]
1✔
769
        fermi = 0.0
1✔
770

771
        assert energies_spin == self.DOSCAR_spin_pol.tdos.energies.tolist()
1✔
772
        assert tdos_up == self.DOSCAR_spin_pol.tdos.densities[Spin.up].tolist()
1✔
773
        assert tdos_down == self.DOSCAR_spin_pol.tdos.densities[Spin.down].tolist()
1✔
774
        assert fermi == approx(self.DOSCAR_spin_pol.tdos.efermi)
1✔
775

776
        energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
1✔
777
        tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418]
1✔
778
        fermi = 0.0
1✔
779

780
        assert energies_nonspin == self.DOSCAR_nonspin_pol.tdos.energies.tolist()
1✔
781
        assert tdos_nonspin == self.DOSCAR_nonspin_pol.tdos.densities[Spin.up].tolist()
1✔
782
        assert fermi == approx(self.DOSCAR_nonspin_pol.tdos.efermi)
1✔
783

784
    def test_energies(self):
1✔
785
        # first for spin polarized version
786
        energies_spin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
1✔
787

788
        assert energies_spin == self.DOSCAR_spin_pol.energies.tolist()
1✔
789

790
        energies_nonspin = [-11.25000, -7.50000, -3.75000, 0.00000, 3.75000, 7.50000]
1✔
791
        assert energies_nonspin == self.DOSCAR_nonspin_pol.energies.tolist()
1✔
792

793
    def test_tdensities(self):
1✔
794
        # first for spin polarized version
795
        tdos_up = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02577]
1✔
796
        tdos_down = [0.00000, 0.79999, 0.00000, 0.79999, 0.00000, 0.02586]
1✔
797

798
        assert tdos_up == self.DOSCAR_spin_pol.tdensities[Spin.up].tolist()
1✔
799
        assert tdos_down == self.DOSCAR_spin_pol.tdensities[Spin.down].tolist()
1✔
800

801
        tdos_nonspin = [0.00000, 1.60000, 0.00000, 1.60000, 0.00000, 0.02418]
1✔
802
        assert tdos_nonspin == self.DOSCAR_nonspin_pol.tdensities[Spin.up].tolist()
1✔
803

804
    def test_itdensities(self):
1✔
805
        itdos_up = [1.99997, 4.99992, 4.99992, 7.99987, 7.99987, 8.09650]
1✔
806
        itdos_down = [1.99997, 4.99992, 4.99992, 7.99987, 7.99987, 8.09685]
1✔
807
        assert itdos_up == self.DOSCAR_spin_pol.itdensities[Spin.up].tolist()
1✔
808
        assert itdos_down == self.DOSCAR_spin_pol.itdensities[Spin.down].tolist()
1✔
809

810
        itdos_nonspin = [4.00000, 10.00000, 10.00000, 16.00000, 16.00000, 16.09067]
1✔
811
        assert itdos_nonspin == self.DOSCAR_nonspin_pol.itdensities[Spin.up].tolist()
1✔
812

813
    def test_is_spin_polarized(self):
1✔
814
        # first for spin polarized version
815
        assert self.DOSCAR_spin_pol.is_spin_polarized
1✔
816

817
        assert not self.DOSCAR_nonspin_pol.is_spin_polarized
1✔
818

819

820
class ChargeTest(PymatgenTest):
1✔
821
    def setUp(self):
1✔
822
        self.charge2 = Charge(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "CHARGE.lobster.MnO"))
1✔
823
        # gzipped file
824
        self.charge = Charge(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "CHARGE.lobster.MnO2.gz"))
1✔
825

826
    def testattributes(self):
1✔
827
        charge_Loewdin = [-1.25, 1.25]
1✔
828
        charge_Mulliken = [-1.30, 1.30]
1✔
829
        atomlist = ["O1", "Mn2"]
1✔
830
        types = ["O", "Mn"]
1✔
831
        num_atoms = 2
1✔
832
        self.assertArrayEqual(charge_Mulliken, self.charge2.Mulliken)
1✔
833
        self.assertArrayEqual(charge_Loewdin, self.charge2.Loewdin)
1✔
834
        self.assertArrayEqual(atomlist, self.charge2.atomlist)
1✔
835
        self.assertArrayEqual(types, self.charge2.types)
1✔
836
        self.assertArrayEqual(num_atoms, self.charge2.num_atoms)
1✔
837

838
    def test_get_structure_with_charges(self):
1✔
839
        structure_dict2 = {
1✔
840
            "lattice": {
841
                "c": 3.198244,
842
                "volume": 23.132361565928807,
843
                "b": 3.1982447183003364,
844
                "gamma": 60.00000011873414,
845
                "beta": 60.00000401737447,
846
                "alpha": 60.00000742944491,
847
                "matrix": [
848
                    [2.769761, 0.0, 1.599122],
849
                    [0.923254, 2.611356, 1.599122],
850
                    [0.0, 0.0, 3.198244],
851
                ],
852
                "a": 3.1982443884113985,
853
            },
854
            "@class": "Structure",
855
            "sites": [
856
                {
857
                    "xyz": [1.846502883732, 1.305680611356, 3.198248797366],
858
                    "properties": {"Loewdin Charges": -1.25, "Mulliken Charges": -1.3},
859
                    "abc": [0.499998, 0.500001, 0.500002],
860
                    "species": [{"occu": 1, "element": "O"}],
861
                    "label": "O",
862
                },
863
                {
864
                    "xyz": [0.0, 0.0, 0.0],
865
                    "properties": {"Loewdin Charges": 1.25, "Mulliken Charges": 1.3},
866
                    "abc": [0.0, 0.0, 0.0],
867
                    "species": [{"occu": 1, "element": "Mn"}],
868
                    "label": "Mn",
869
                },
870
            ],
871
            "charge": None,
872
            "@module": "pymatgen.core.structure",
873
        }
874
        s2 = Structure.from_dict(structure_dict2)
1✔
875
        assert s2 == self.charge2.get_structure_with_charges(os.path.join(this_dir, "../../tests/POSCAR.MnO"))
1✔
876

877

878
class LobsteroutTest(PymatgenTest):
1✔
879
    def setUp(self):
1✔
880
        warnings.simplefilter("ignore")
1✔
881
        self.lobsterout_normal = Lobsterout(
1✔
882
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.normal")
883
        )
884
        # make sure .gz files are also read correctly
885
        self.lobsterout_normal = Lobsterout(
1✔
886
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.normal2.gz")
887
        )
888
        self.lobsterout_fatband_grosspop_densityofenergies = Lobsterout(
1✔
889
            filename=os.path.join(
890
                PymatgenTest.TEST_FILES_DIR,
891
                "cohp",
892
                "lobsterout.fatband_grosspop_densityofenergy",
893
            )
894
        )
895
        self.lobsterout_saveprojection = Lobsterout(
1✔
896
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.saveprojection")
897
        )
898
        self.lobsterout_skipping_all = Lobsterout(
1✔
899
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.skipping_all")
900
        )
901
        self.lobsterout_twospins = Lobsterout(
1✔
902
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.twospins")
903
        )
904
        self.lobsterout_GaAs = Lobsterout(filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.GaAs"))
1✔
905
        self.lobsterout_from_projection = Lobsterout(
1✔
906
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout_from_projection")
907
        )
908
        self.lobsterout_onethread = Lobsterout(
1✔
909
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.onethread")
910
        )
911
        self.lobsterout_cobi_madelung = Lobsterout(
1✔
912
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout_cobi_madelung")
913
        )
914
        self.lobsterout_doscar_lso = Lobsterout(
1✔
915
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout_doscar_lso")
916
        )
917

918
        # TODO: implement skipping madelung/cobi
919
        self.lobsterout_skipping_cobi_madelung = Lobsterout(
1✔
920
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterout.skip_cobi_madelung")
921
        )
922

923
    def tearDown(self):
1✔
924
        warnings.simplefilter("default")
1✔
925

926
    def testattributes(self):
1✔
927
        assert self.lobsterout_normal.basis_functions == [
1✔
928
            [
929
                "3s",
930
                "4s",
931
                "3p_y",
932
                "3p_z",
933
                "3p_x",
934
                "3d_xy",
935
                "3d_yz",
936
                "3d_z^2",
937
                "3d_xz",
938
                "3d_x^2-y^2",
939
            ]
940
        ]
941
        assert self.lobsterout_normal.basis_type == ["pbeVaspFit2015"]
1✔
942
        assert self.lobsterout_normal.charge_spilling == [0.0268]
1✔
943
        assert self.lobsterout_normal.dft_program == "VASP"
1✔
944
        assert self.lobsterout_normal.elements == ["Ti"]
1✔
945
        assert self.lobsterout_normal.has_charge
1✔
946
        assert self.lobsterout_normal.has_cohpcar
1✔
947
        assert self.lobsterout_normal.has_coopcar
1✔
948
        assert self.lobsterout_normal.has_doscar
1✔
949
        assert not self.lobsterout_normal.has_projection
1✔
950
        assert self.lobsterout_normal.has_bandoverlaps
1✔
951
        assert not self.lobsterout_normal.has_density_of_energies
1✔
952
        assert not self.lobsterout_normal.has_fatbands
1✔
953
        assert not self.lobsterout_normal.has_grosspopulation
1✔
954
        assert self.lobsterout_normal.info_lines == [
1✔
955
            "There are more PAW bands than local basis functions available.",
956
            "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
957
            "the PAW bands from 21 and upwards will be ignored.",
958
        ]
959
        assert self.lobsterout_normal.info_orthonormalization == [
1✔
960
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5."
961
        ]
962
        assert not self.lobsterout_normal.is_restart_from_projection
1✔
963
        assert self.lobsterout_normal.lobster_version == "v3.1.0"
1✔
964
        assert self.lobsterout_normal.number_of_spins == 1
1✔
965
        assert self.lobsterout_normal.number_of_threads == 8
1✔
966
        assert self.lobsterout_normal.timing == {
1✔
967
            "wall_time": {"h": "0", "min": "0", "s": "2", "ms": "702"},
968
            "user_time": {"h": "0", "min": "0", "s": "20", "ms": "330"},
969
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "310"},
970
        }
971
        assert self.lobsterout_normal.total_spilling[0] == approx([0.044000000000000004][0])
1✔
972
        assert self.lobsterout_normal.warning_lines == [
1✔
973
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.",
974
            "Generally, this is not a critical error. But to help you analyze it,",
975
            "I dumped the band overlap matrices to the file bandOverlaps.lobster.",
976
            "Please check how much they deviate from the identity matrix and decide to",
977
            "use your results only, if you are sure that this is ok.",
978
        ]
979

980
        assert self.lobsterout_fatband_grosspop_densityofenergies.basis_functions == [
1✔
981
            [
982
                "3s",
983
                "4s",
984
                "3p_y",
985
                "3p_z",
986
                "3p_x",
987
                "3d_xy",
988
                "3d_yz",
989
                "3d_z^2",
990
                "3d_xz",
991
                "3d_x^2-y^2",
992
            ]
993
        ]
994
        assert self.lobsterout_fatband_grosspop_densityofenergies.basis_type == ["pbeVaspFit2015"]
1✔
995
        assert self.lobsterout_fatband_grosspop_densityofenergies.charge_spilling == [0.0268]
1✔
996
        assert self.lobsterout_fatband_grosspop_densityofenergies.dft_program == "VASP"
1✔
997
        assert self.lobsterout_fatband_grosspop_densityofenergies.elements == ["Ti"]
1✔
998
        assert self.lobsterout_fatband_grosspop_densityofenergies.has_charge
1✔
999
        assert not self.lobsterout_fatband_grosspop_densityofenergies.has_cohpcar
1✔
1000
        assert not self.lobsterout_fatband_grosspop_densityofenergies.has_coopcar
1✔
1001
        assert not self.lobsterout_fatband_grosspop_densityofenergies.has_doscar
1✔
1002
        assert not self.lobsterout_fatband_grosspop_densityofenergies.has_projection
1✔
1003
        assert self.lobsterout_fatband_grosspop_densityofenergies.has_bandoverlaps
1✔
1004
        assert self.lobsterout_fatband_grosspop_densityofenergies.has_density_of_energies
1✔
1005
        assert self.lobsterout_fatband_grosspop_densityofenergies.has_fatbands
1✔
1006
        assert self.lobsterout_fatband_grosspop_densityofenergies.has_grosspopulation
1✔
1007
        assert self.lobsterout_fatband_grosspop_densityofenergies.info_lines == [
1✔
1008
            "There are more PAW bands than local basis functions available.",
1009
            "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
1010
            "the PAW bands from 21 and upwards will be ignored.",
1011
        ]
1012
        assert self.lobsterout_fatband_grosspop_densityofenergies.info_orthonormalization == [
1✔
1013
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5."
1014
        ]
1015
        assert not self.lobsterout_fatband_grosspop_densityofenergies.is_restart_from_projection
1✔
1016
        assert self.lobsterout_fatband_grosspop_densityofenergies.lobster_version == "v3.1.0"
1✔
1017
        assert self.lobsterout_fatband_grosspop_densityofenergies.number_of_spins == 1
1✔
1018
        assert self.lobsterout_fatband_grosspop_densityofenergies.number_of_threads == 8
1✔
1019
        assert self.lobsterout_fatband_grosspop_densityofenergies.timing == {
1✔
1020
            "wall_time": {"h": "0", "min": "0", "s": "4", "ms": "136"},
1021
            "user_time": {"h": "0", "min": "0", "s": "18", "ms": "280"},
1022
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "290"},
1023
        }
1024
        assert self.lobsterout_fatband_grosspop_densityofenergies.total_spilling[0] == approx([0.044000000000000004][0])
1✔
1025
        assert self.lobsterout_fatband_grosspop_densityofenergies.warning_lines == [
1✔
1026
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.",
1027
            "Generally, this is not a critical error. But to help you analyze it,",
1028
            "I dumped the band overlap matrices to the file bandOverlaps.lobster.",
1029
            "Please check how much they deviate from the identity matrix and decide to",
1030
            "use your results only, if you are sure that this is ok.",
1031
        ]
1032

1033
        assert self.lobsterout_saveprojection.basis_functions == [
1✔
1034
            [
1035
                "3s",
1036
                "4s",
1037
                "3p_y",
1038
                "3p_z",
1039
                "3p_x",
1040
                "3d_xy",
1041
                "3d_yz",
1042
                "3d_z^2",
1043
                "3d_xz",
1044
                "3d_x^2-y^2",
1045
            ]
1046
        ]
1047
        assert self.lobsterout_saveprojection.basis_type == ["pbeVaspFit2015"]
1✔
1048
        assert self.lobsterout_saveprojection.charge_spilling == [0.0268]
1✔
1049
        assert self.lobsterout_saveprojection.dft_program == "VASP"
1✔
1050
        assert self.lobsterout_saveprojection.elements == ["Ti"]
1✔
1051
        assert self.lobsterout_saveprojection.has_charge
1✔
1052
        assert not self.lobsterout_saveprojection.has_cohpcar
1✔
1053
        assert not self.lobsterout_saveprojection.has_coopcar
1✔
1054
        assert not self.lobsterout_saveprojection.has_doscar
1✔
1055
        assert self.lobsterout_saveprojection.has_projection
1✔
1056
        assert self.lobsterout_saveprojection.has_bandoverlaps
1✔
1057
        assert self.lobsterout_saveprojection.has_density_of_energies
1✔
1058
        assert not self.lobsterout_saveprojection.has_fatbands
1✔
1059
        assert not self.lobsterout_saveprojection.has_grosspopulation
1✔
1060
        assert self.lobsterout_saveprojection.info_lines == [
1✔
1061
            "There are more PAW bands than local basis functions available.",
1062
            "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
1063
            "the PAW bands from 21 and upwards will be ignored.",
1064
        ]
1065
        assert self.lobsterout_saveprojection.info_orthonormalization == [
1✔
1066
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5."
1067
        ]
1068
        assert not self.lobsterout_saveprojection.is_restart_from_projection
1✔
1069
        assert self.lobsterout_saveprojection.lobster_version == "v3.1.0"
1✔
1070
        assert self.lobsterout_saveprojection.number_of_spins == 1
1✔
1071
        assert self.lobsterout_saveprojection.number_of_threads == 8
1✔
1072
        assert self.lobsterout_saveprojection.timing == {
1✔
1073
            "wall_time": {"h": "0", "min": "0", "s": "2", "ms": "574"},
1074
            "user_time": {"h": "0", "min": "0", "s": "18", "ms": "250"},
1075
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "320"},
1076
        }
1077
        assert self.lobsterout_saveprojection.total_spilling[0] == approx([0.044000000000000004][0])
1✔
1078
        assert self.lobsterout_saveprojection.warning_lines == [
1✔
1079
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.",
1080
            "Generally, this is not a critical error. But to help you analyze it,",
1081
            "I dumped the band overlap matrices to the file bandOverlaps.lobster.",
1082
            "Please check how much they deviate from the identity matrix and decide to",
1083
            "use your results only, if you are sure that this is ok.",
1084
        ]
1085

1086
        assert self.lobsterout_skipping_all.basis_functions == [
1✔
1087
            [
1088
                "3s",
1089
                "4s",
1090
                "3p_y",
1091
                "3p_z",
1092
                "3p_x",
1093
                "3d_xy",
1094
                "3d_yz",
1095
                "3d_z^2",
1096
                "3d_xz",
1097
                "3d_x^2-y^2",
1098
            ]
1099
        ]
1100
        assert self.lobsterout_skipping_all.basis_type == ["pbeVaspFit2015"]
1✔
1101
        assert self.lobsterout_skipping_all.charge_spilling == [0.0268]
1✔
1102
        assert self.lobsterout_skipping_all.dft_program == "VASP"
1✔
1103
        assert self.lobsterout_skipping_all.elements == ["Ti"]
1✔
1104
        assert not self.lobsterout_skipping_all.has_charge
1✔
1105
        assert not self.lobsterout_skipping_all.has_cohpcar
1✔
1106
        assert not self.lobsterout_skipping_all.has_coopcar
1✔
1107
        assert not self.lobsterout_skipping_all.has_doscar
1✔
1108
        assert not self.lobsterout_skipping_all.has_projection
1✔
1109
        assert self.lobsterout_skipping_all.has_bandoverlaps
1✔
1110
        assert not self.lobsterout_skipping_all.has_density_of_energies
1✔
1111
        assert not self.lobsterout_skipping_all.has_fatbands
1✔
1112
        assert not self.lobsterout_skipping_all.has_grosspopulation
1✔
1113
        assert not self.lobsterout_skipping_all.has_cobicar
1✔
1114
        assert not self.lobsterout_skipping_all.has_madelung
1✔
1115
        assert self.lobsterout_skipping_all.info_lines == [
1✔
1116
            "There are more PAW bands than local basis functions available.",
1117
            "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
1118
            "the PAW bands from 21 and upwards will be ignored.",
1119
        ]
1120
        assert self.lobsterout_skipping_all.info_orthonormalization == [
1✔
1121
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5."
1122
        ]
1123
        assert not self.lobsterout_skipping_all.is_restart_from_projection
1✔
1124
        assert self.lobsterout_skipping_all.lobster_version == "v3.1.0"
1✔
1125
        assert self.lobsterout_skipping_all.number_of_spins == 1
1✔
1126
        assert self.lobsterout_skipping_all.number_of_threads == 8
1✔
1127
        assert self.lobsterout_skipping_all.timing == {
1✔
1128
            "wall_time": {"h": "0", "min": "0", "s": "2", "ms": "117"},
1129
            "user_time": {"h": "0", "min": "0", "s": "16", "ms": "79"},
1130
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "320"},
1131
        }
1132
        assert self.lobsterout_skipping_all.total_spilling[0] == approx([0.044000000000000004][0])
1✔
1133
        assert self.lobsterout_skipping_all.warning_lines == [
1✔
1134
            "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.",
1135
            "Generally, this is not a critical error. But to help you analyze it,",
1136
            "I dumped the band overlap matrices to the file bandOverlaps.lobster.",
1137
            "Please check how much they deviate from the identity matrix and decide to",
1138
            "use your results only, if you are sure that this is ok.",
1139
        ]
1140

1141
        assert self.lobsterout_twospins.basis_functions == [
1✔
1142
            [
1143
                "4s",
1144
                "4p_y",
1145
                "4p_z",
1146
                "4p_x",
1147
                "3d_xy",
1148
                "3d_yz",
1149
                "3d_z^2",
1150
                "3d_xz",
1151
                "3d_x^2-y^2",
1152
            ]
1153
        ]
1154
        assert self.lobsterout_twospins.basis_type == ["pbeVaspFit2015"]
1✔
1155
        assert self.lobsterout_twospins.charge_spilling[0] == approx(0.36619999999999997)
1✔
1156
        assert self.lobsterout_twospins.charge_spilling[1] == approx(0.36619999999999997)
1✔
1157
        assert self.lobsterout_twospins.dft_program == "VASP"
1✔
1158
        assert self.lobsterout_twospins.elements == ["Ti"]
1✔
1159
        assert self.lobsterout_twospins.has_charge
1✔
1160
        assert self.lobsterout_twospins.has_cohpcar
1✔
1161
        assert self.lobsterout_twospins.has_coopcar
1✔
1162
        assert self.lobsterout_twospins.has_doscar
1✔
1163
        assert not self.lobsterout_twospins.has_projection
1✔
1164
        assert self.lobsterout_twospins.has_bandoverlaps
1✔
1165
        assert not self.lobsterout_twospins.has_density_of_energies
1✔
1166
        assert not self.lobsterout_twospins.has_fatbands
1✔
1167
        assert not self.lobsterout_twospins.has_grosspopulation
1✔
1168
        assert self.lobsterout_twospins.info_lines == [
1✔
1169
            "There are more PAW bands than local basis functions available.",
1170
            "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
1171
            "the PAW bands from 19 and upwards will be ignored.",
1172
        ]
1173
        assert self.lobsterout_twospins.info_orthonormalization == [
1✔
1174
            "60 of 294 k-points could not be orthonormalized with an accuracy of 1.0E-5."
1175
        ]
1176
        assert not self.lobsterout_twospins.is_restart_from_projection
1✔
1177
        assert self.lobsterout_twospins.lobster_version == "v3.1.0"
1✔
1178
        assert self.lobsterout_twospins.number_of_spins == 2
1✔
1179
        assert self.lobsterout_twospins.number_of_threads == 8
1✔
1180
        assert self.lobsterout_twospins.timing == {
1✔
1181
            "wall_time": {"h": "0", "min": "0", "s": "3", "ms": "71"},
1182
            "user_time": {"h": "0", "min": "0", "s": "22", "ms": "660"},
1183
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "310"},
1184
        }
1185
        assert self.lobsterout_twospins.total_spilling[0] == approx([0.2567][0])
1✔
1186
        assert self.lobsterout_twospins.total_spilling[1] == approx([0.2567][0])
1✔
1187
        assert self.lobsterout_twospins.warning_lines == [
1✔
1188
            "60 of 294 k-points could not be orthonormalized with an accuracy of 1.0E-5.",
1189
            "Generally, this is not a critical error. But to help you analyze it,",
1190
            "I dumped the band overlap matrices to the file bandOverlaps.lobster.",
1191
            "Please check how much they deviate from the identity matrix and decide to",
1192
            "use your results only, if you are sure that this is ok.",
1193
        ]
1194

1195
        assert self.lobsterout_from_projection.basis_functions == []
1✔
1196
        assert self.lobsterout_from_projection.basis_type == []
1✔
1197
        assert self.lobsterout_from_projection.charge_spilling[0] == approx(0.0177)
1✔
1198
        assert self.lobsterout_from_projection.dft_program is None
1✔
1199
        assert self.lobsterout_from_projection.elements == []
1✔
1200
        assert self.lobsterout_from_projection.has_charge
1✔
1201
        assert self.lobsterout_from_projection.has_cohpcar
1✔
1202
        assert self.lobsterout_from_projection.has_coopcar
1✔
1203
        assert self.lobsterout_from_projection.has_doscar
1✔
1204
        assert not self.lobsterout_from_projection.has_projection
1✔
1205
        assert not self.lobsterout_from_projection.has_bandoverlaps
1✔
1206
        assert not self.lobsterout_from_projection.has_density_of_energies
1✔
1207
        assert not self.lobsterout_from_projection.has_fatbands
1✔
1208
        assert not self.lobsterout_from_projection.has_grosspopulation
1✔
1209
        assert self.lobsterout_from_projection.info_lines == []
1✔
1210
        assert self.lobsterout_from_projection.info_orthonormalization == []
1✔
1211
        assert self.lobsterout_from_projection.is_restart_from_projection
1✔
1212
        assert self.lobsterout_from_projection.lobster_version == "v3.1.0"
1✔
1213
        assert self.lobsterout_from_projection.number_of_spins == 1
1✔
1214
        assert self.lobsterout_from_projection.number_of_threads == 8
1✔
1215
        assert self.lobsterout_from_projection.timing == {
1✔
1216
            "wall_time": {"h": "0", "min": "2", "s": "1", "ms": "890"},
1217
            "user_time": {"h": "0", "min": "15", "s": "10", "ms": "530"},
1218
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "400"},
1219
        }
1220
        assert self.lobsterout_from_projection.total_spilling[0] == approx([0.1543][0])
1✔
1221
        assert self.lobsterout_from_projection.warning_lines == []
1✔
1222

1223
        assert self.lobsterout_GaAs.basis_functions == [
1✔
1224
            ["4s", "4p_y", "4p_z", "4p_x"],
1225
            [
1226
                "4s",
1227
                "4p_y",
1228
                "4p_z",
1229
                "4p_x",
1230
                "3d_xy",
1231
                "3d_yz",
1232
                "3d_z^2",
1233
                "3d_xz",
1234
                "3d_x^2-y^2",
1235
            ],
1236
        ]
1237
        assert self.lobsterout_GaAs.basis_type == ["Bunge", "Bunge"]
1✔
1238
        assert self.lobsterout_GaAs.charge_spilling[0] == approx(0.0089)
1✔
1239
        assert self.lobsterout_GaAs.dft_program == "VASP"
1✔
1240
        assert self.lobsterout_GaAs.elements == ["As", "Ga"]
1✔
1241
        assert self.lobsterout_GaAs.has_charge
1✔
1242
        assert self.lobsterout_GaAs.has_cohpcar
1✔
1243
        assert self.lobsterout_GaAs.has_coopcar
1✔
1244
        assert self.lobsterout_GaAs.has_doscar
1✔
1245
        assert not self.lobsterout_GaAs.has_projection
1✔
1246
        assert not self.lobsterout_GaAs.has_bandoverlaps
1✔
1247
        assert not self.lobsterout_GaAs.has_density_of_energies
1✔
1248
        assert not self.lobsterout_GaAs.has_fatbands
1✔
1249
        assert not self.lobsterout_GaAs.has_grosspopulation
1✔
1250
        assert self.lobsterout_GaAs.info_lines == [
1✔
1251
            "There are more PAW bands than local basis functions available.",
1252
            "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
1253
            "the PAW bands from 14 and upwards will be ignored.",
1254
        ]
1255
        assert self.lobsterout_GaAs.info_orthonormalization == []
1✔
1256
        assert not self.lobsterout_GaAs.is_restart_from_projection
1✔
1257
        assert self.lobsterout_GaAs.lobster_version == "v3.1.0"
1✔
1258
        assert self.lobsterout_GaAs.number_of_spins == 1
1✔
1259
        assert self.lobsterout_GaAs.number_of_threads == 8
1✔
1260
        assert self.lobsterout_GaAs.timing == {
1✔
1261
            "wall_time": {"h": "0", "min": "0", "s": "2", "ms": "726"},
1262
            "user_time": {"h": "0", "min": "0", "s": "12", "ms": "370"},
1263
            "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "180"},
1264
        }
1265
        assert self.lobsterout_GaAs.total_spilling[0] == approx([0.0859][0])
1✔
1266

1267
        assert self.lobsterout_onethread.number_of_threads == 1
1✔
1268
        # Test lobsterout of lobster-4.1.0
1269
        assert self.lobsterout_cobi_madelung.has_cobicar is True
1✔
1270
        assert self.lobsterout_cobi_madelung.has_cohpcar is True
1✔
1271
        assert self.lobsterout_cobi_madelung.has_madelung is True
1✔
1272
        assert not self.lobsterout_cobi_madelung.has_doscar_lso
1✔
1273

1274
        assert self.lobsterout_doscar_lso.has_doscar_lso
1✔
1275

1276
        assert self.lobsterout_skipping_cobi_madelung.has_cobicar is False
1✔
1277
        assert self.lobsterout_skipping_cobi_madelung.has_madelung is False
1✔
1278

1279
    def test_get_doc(self):
1✔
1280
        comparedict = {
1✔
1281
            "restart_from_projection": False,
1282
            "lobster_version": "v3.1.0",
1283
            "threads": 8,
1284
            "dft_program": "VASP",
1285
            "charge_spilling": [0.0268],
1286
            "total_spilling": [0.044000000000000004],
1287
            "elements": ["Ti"],
1288
            "basis_type": ["pbeVaspFit2015"],
1289
            "basis_functions": [
1290
                [
1291
                    "3s",
1292
                    "4s",
1293
                    "3p_y",
1294
                    "3p_z",
1295
                    "3p_x",
1296
                    "3d_xy",
1297
                    "3d_yz",
1298
                    "3d_z^2",
1299
                    "3d_xz",
1300
                    "3d_x^2-y^2",
1301
                ]
1302
            ],
1303
            "timing": {
1304
                "wall_time": {"h": "0", "min": "0", "s": "2", "ms": "702"},
1305
                "user_time": {"h": "0", "min": "0", "s": "20", "ms": "330"},
1306
                "sys_time": {"h": "0", "min": "0", "s": "0", "ms": "310"},
1307
            },
1308
            "warning_lines": [
1309
                "3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5.",
1310
                "Generally, this is not a critical error. But to help you analyze it,",
1311
                "I dumped the band overlap matrices to the file bandOverlaps.lobster.",
1312
                "Please check how much they deviate from the identity matrix and decide to",
1313
                "use your results only, if you are sure that this is ok.",
1314
            ],
1315
            "info_orthonormalization": ["3 of 147 k-points could not be orthonormalized with an accuracy of 1.0E-5."],
1316
            "info_lines": [
1317
                "There are more PAW bands than local basis functions available.",
1318
                "To prevent trouble in orthonormalization and Hamiltonian reconstruction",
1319
                "the PAW bands from 21 and upwards will be ignored.",
1320
            ],
1321
            "has_doscar": True,
1322
            "has_doscar_lso": False,
1323
            "has_cohpcar": True,
1324
            "has_coopcar": True,
1325
            "has_charge": True,
1326
            "has_projection": False,
1327
            "has_bandoverlaps": True,
1328
            "has_fatbands": False,
1329
            "has_grosspopulation": False,
1330
            "has_density_of_energies": False,
1331
        }
1332
        for key, item in self.lobsterout_normal.get_doc().items():
1✔
1333
            if key not in ["has_cobicar", "has_madelung"]:
1✔
1334
                if isinstance(item, str):
1✔
1335
                    assert comparedict[key], item
1✔
1336
                elif isinstance(item, int):
1✔
1337
                    assert comparedict[key] == item
1✔
1338
                elif key in ("charge_spilling", "total_spilling"):
1✔
1339
                    assert item[0] == approx(comparedict[key][0])
1✔
1340
                elif isinstance(item, list):
1✔
1341
                    assert item == comparedict[key]
1✔
1342
                elif isinstance(item, dict):
1✔
1343
                    assert item == comparedict[key]
1✔
1344

1345

1346
class FatbandTest(PymatgenTest):
1✔
1347
    def setUp(self):
1✔
1348
        warnings.simplefilter("ignore")
1✔
1349
        self.fatband_SiO2_p_x = Fatband(
1✔
1350
            filenames=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x"),
1351
            Kpointsfile=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x/KPOINTS"),
1352
            vasprun=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x/vasprun.xml"),
1353
        )
1354
        self.vasprun_SiO2_p_x = Vasprun(
1✔
1355
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x/vasprun.xml")
1356
        )
1357
        self.bs_symmline = self.vasprun_SiO2_p_x.get_band_structure(line_mode=True, force_hybrid_mode=True)
1✔
1358
        self.fatband_SiO2_p = Fatband(
1✔
1359
            filenames=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p"),
1360
            Kpointsfile=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p/KPOINTS"),
1361
            vasprun=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p/vasprun.xml"),
1362
        )
1363
        self.vasprun_SiO2_p = Vasprun(
1✔
1364
            filename=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p/vasprun.xml")
1365
        )
1366
        self.bs_symmline2 = self.vasprun_SiO2_p.get_band_structure(line_mode=True, force_hybrid_mode=True)
1✔
1367
        self.fatband_SiO2_spin = Fatband(
1✔
1368
            filenames=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_Spin"),
1369
            Kpointsfile=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_Spin/KPOINTS"),
1370
            vasprun=os.path.join(
1371
                PymatgenTest.TEST_FILES_DIR,
1372
                "cohp",
1373
                "Fatband_SiO2/Test_Spin/vasprun.xml",
1374
            ),
1375
        )
1376
        self.vasprun_SiO2_spin = Vasprun(
1✔
1377
            filename=os.path.join(
1378
                PymatgenTest.TEST_FILES_DIR,
1379
                "cohp",
1380
                "Fatband_SiO2/Test_Spin/vasprun.xml",
1381
            )
1382
        )
1383
        self.bs_symmline_spin = self.vasprun_SiO2_p.get_band_structure(line_mode=True, force_hybrid_mode=True)
1✔
1384

1385
    def tearDown(self):
1✔
1386
        warnings.simplefilter("default")
1✔
1387

1388
    def test_attributes(self):
1✔
1389
        assert list(self.fatband_SiO2_p_x.label_dict["M"])[0] == approx(0.5)
1✔
1390
        assert list(self.fatband_SiO2_p_x.label_dict["M"])[1] == approx(0.0)
1✔
1391
        assert list(self.fatband_SiO2_p_x.label_dict["M"])[2] == approx(0.0)
1✔
1392
        assert self.fatband_SiO2_p_x.efermi == self.vasprun_SiO2_p_x.efermi
1✔
1393
        lattice1 = self.bs_symmline.lattice_rec.as_dict()
1✔
1394
        lattice2 = self.fatband_SiO2_p_x.lattice.as_dict()
1✔
1395
        assert lattice1["matrix"][0][0] == approx(lattice2["matrix"][0][0])
1✔
1396
        assert lattice1["matrix"][0][1] == approx(lattice2["matrix"][0][1])
1✔
1397
        assert lattice1["matrix"][0][2] == approx(lattice2["matrix"][0][2])
1✔
1398
        assert lattice1["matrix"][1][0] == approx(lattice2["matrix"][1][0])
1✔
1399
        assert lattice1["matrix"][1][1] == approx(lattice2["matrix"][1][1])
1✔
1400
        assert lattice1["matrix"][1][2] == approx(lattice2["matrix"][1][2])
1✔
1401
        assert lattice1["matrix"][2][0] == approx(lattice2["matrix"][2][0])
1✔
1402
        assert lattice1["matrix"][2][1] == approx(lattice2["matrix"][2][1])
1✔
1403
        assert lattice1["matrix"][2][2] == approx(lattice2["matrix"][2][2])
1✔
1404
        assert self.fatband_SiO2_p_x.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p_x.efermi == -18.245
1✔
1405
        assert self.fatband_SiO2_p_x.is_spinpolarized is False
1✔
1406
        assert self.fatband_SiO2_p_x.kpoints_array[3][0] == approx(0.03409091)
1✔
1407
        assert self.fatband_SiO2_p_x.kpoints_array[3][1] == 0.0
1✔
1408
        assert self.fatband_SiO2_p_x.kpoints_array[3][2] == 0.0
1✔
1409
        assert self.fatband_SiO2_p_x.nbands == 36
1✔
1410
        assert self.fatband_SiO2_p_x.p_eigenvals[Spin.up][2][1]["Si1"]["3p_x"] == 0.002
1✔
1411
        assert self.fatband_SiO2_p_x.structure[0].frac_coords[0] == approx(0.0)
1✔
1412
        assert self.fatband_SiO2_p_x.structure[0].frac_coords[1] == approx(0.47634315)
1✔
1413
        assert self.fatband_SiO2_p_x.structure[0].frac_coords[2] == approx(0.666667)
1✔
1414
        assert self.fatband_SiO2_p_x.structure[0].species_string == "Si"
1✔
1415
        assert self.fatband_SiO2_p_x.structure[0].coords[0] == approx(-1.19607309)
1✔
1416
        assert self.fatband_SiO2_p_x.structure[0].coords[1] == approx(2.0716597)
1✔
1417
        assert self.fatband_SiO2_p_x.structure[0].coords[2] == approx(3.67462144)
1✔
1418

1419
        assert list(self.fatband_SiO2_p.label_dict["M"])[0] == approx(0.5)
1✔
1420
        assert list(self.fatband_SiO2_p.label_dict["M"])[1] == approx(0.0)
1✔
1421
        assert list(self.fatband_SiO2_p.label_dict["M"])[2] == approx(0.0)
1✔
1422
        assert self.fatband_SiO2_p.efermi == self.vasprun_SiO2_p.efermi
1✔
1423
        lattice1 = self.bs_symmline2.lattice_rec.as_dict()
1✔
1424
        lattice2 = self.fatband_SiO2_p.lattice.as_dict()
1✔
1425
        assert lattice1["matrix"][0][0] == approx(lattice2["matrix"][0][0])
1✔
1426
        assert lattice1["matrix"][0][1] == approx(lattice2["matrix"][0][1])
1✔
1427
        assert lattice1["matrix"][0][2] == approx(lattice2["matrix"][0][2])
1✔
1428
        assert lattice1["matrix"][1][0] == approx(lattice2["matrix"][1][0])
1✔
1429
        assert lattice1["matrix"][1][1] == approx(lattice2["matrix"][1][1])
1✔
1430
        assert lattice1["matrix"][1][2] == approx(lattice2["matrix"][1][2])
1✔
1431
        assert lattice1["matrix"][2][0] == approx(lattice2["matrix"][2][0])
1✔
1432
        assert lattice1["matrix"][2][1] == approx(lattice2["matrix"][2][1])
1✔
1433
        assert lattice1["matrix"][2][2] == approx(lattice2["matrix"][2][2])
1✔
1434
        assert self.fatband_SiO2_p.eigenvals[Spin.up][1][1] - self.fatband_SiO2_p.efermi == -18.245
1✔
1435
        assert self.fatband_SiO2_p.is_spinpolarized is False
1✔
1436
        assert self.fatband_SiO2_p.kpoints_array[3][0] == approx(0.03409091)
1✔
1437
        assert self.fatband_SiO2_p.kpoints_array[3][1] == 0.0
1✔
1438
        assert self.fatband_SiO2_p.kpoints_array[3][2] == 0.0
1✔
1439
        assert self.fatband_SiO2_p.nbands == 36
1✔
1440
        assert self.fatband_SiO2_p.p_eigenvals[Spin.up][2][1]["Si1"]["3p"] == 0.042
1✔
1441
        assert self.fatband_SiO2_p.structure[0].frac_coords[0] == approx(0.0)
1✔
1442
        assert self.fatband_SiO2_p.structure[0].frac_coords[1] == approx(0.47634315)
1✔
1443
        assert self.fatband_SiO2_p.structure[0].frac_coords[2] == approx(0.666667)
1✔
1444
        assert self.fatband_SiO2_p.structure[0].species_string == "Si"
1✔
1445
        assert self.fatband_SiO2_p.structure[0].coords[0] == approx(-1.19607309)
1✔
1446
        assert self.fatband_SiO2_p.structure[0].coords[1] == approx(2.0716597)
1✔
1447
        assert self.fatband_SiO2_p.structure[0].coords[2] == approx(3.67462144)
1✔
1448

1449
        assert list(self.fatband_SiO2_spin.label_dict["M"])[0] == approx(0.5)
1✔
1450
        assert list(self.fatband_SiO2_spin.label_dict["M"])[1] == approx(0.0)
1✔
1451
        assert list(self.fatband_SiO2_spin.label_dict["M"])[2] == approx(0.0)
1✔
1452
        assert self.fatband_SiO2_spin.efermi == self.vasprun_SiO2_spin.efermi
1✔
1453
        lattice1 = self.bs_symmline_spin.lattice_rec.as_dict()
1✔
1454
        lattice2 = self.fatband_SiO2_spin.lattice.as_dict()
1✔
1455
        assert lattice1["matrix"][0][0] == approx(lattice2["matrix"][0][0])
1✔
1456
        assert lattice1["matrix"][0][1] == approx(lattice2["matrix"][0][1])
1✔
1457
        assert lattice1["matrix"][0][2] == approx(lattice2["matrix"][0][2])
1✔
1458
        assert lattice1["matrix"][1][0] == approx(lattice2["matrix"][1][0])
1✔
1459
        assert lattice1["matrix"][1][1] == approx(lattice2["matrix"][1][1])
1✔
1460
        assert lattice1["matrix"][1][2] == approx(lattice2["matrix"][1][2])
1✔
1461
        assert lattice1["matrix"][2][0] == approx(lattice2["matrix"][2][0])
1✔
1462
        assert lattice1["matrix"][2][1] == approx(lattice2["matrix"][2][1])
1✔
1463
        assert lattice1["matrix"][2][2] == approx(lattice2["matrix"][2][2])
1✔
1464
        assert self.fatband_SiO2_spin.eigenvals[Spin.up][1][1] - self.fatband_SiO2_spin.efermi == -18.245
1✔
1465
        assert self.fatband_SiO2_spin.eigenvals[Spin.down][1][1] - self.fatband_SiO2_spin.efermi == -18.245
1✔
1466
        assert self.fatband_SiO2_spin.is_spinpolarized is True
1✔
1467
        assert self.fatband_SiO2_spin.kpoints_array[3][0] == approx(0.03409091)
1✔
1468
        assert self.fatband_SiO2_spin.kpoints_array[3][1] == 0.0
1✔
1469
        assert self.fatband_SiO2_spin.kpoints_array[3][2] == 0.0
1✔
1470
        assert self.fatband_SiO2_spin.nbands == 36
1✔
1471

1472
        assert self.fatband_SiO2_spin.p_eigenvals[Spin.up][2][1]["Si1"]["3p"] == 0.042
1✔
1473
        assert self.fatband_SiO2_spin.structure[0].frac_coords[0] == approx(0.0)
1✔
1474
        assert self.fatband_SiO2_spin.structure[0].frac_coords[1] == approx(0.47634315)
1✔
1475
        assert self.fatband_SiO2_spin.structure[0].frac_coords[2] == approx(0.666667)
1✔
1476
        assert self.fatband_SiO2_spin.structure[0].species_string == "Si"
1✔
1477
        assert self.fatband_SiO2_spin.structure[0].coords[0] == approx(-1.19607309)
1✔
1478
        assert self.fatband_SiO2_spin.structure[0].coords[1] == approx(2.0716597)
1✔
1479
        assert self.fatband_SiO2_spin.structure[0].coords[2] == approx(3.67462144)
1✔
1480

1481
    def test_raises(self):
1✔
1482
        with pytest.raises(ValueError):
1✔
1483
            self.fatband_SiO2_p_x = Fatband(
1✔
1484
                filenames=[
1485
                    os.path.join(
1486
                        PymatgenTest.TEST_FILES_DIR,
1487
                        "cohp",
1488
                        "Fatband_SiO2/Test_p_x/FATBAND_si1_3p_x.lobster",
1489
                    ),
1490
                    os.path.join(
1491
                        PymatgenTest.TEST_FILES_DIR,
1492
                        "cohp",
1493
                        "Fatband_SiO2/Test_p_x/FATBAND_si1_3p_x.lobster",
1494
                    ),
1495
                ],
1496
                Kpointsfile=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x/KPOINTS"),
1497
                vasprun=os.path.join(
1498
                    PymatgenTest.TEST_FILES_DIR,
1499
                    "cohp",
1500
                    "Fatband_SiO2/Test_p_x/vasprun.xml",
1501
                ),
1502
            )
1503

1504
        with pytest.raises(ValueError):
1✔
1505
            self.fatband_SiO2_p_x = Fatband(
1✔
1506
                filenames=[
1507
                    os.path.join(
1508
                        PymatgenTest.TEST_FILES_DIR,
1509
                        "cohp",
1510
                        "Fatband_SiO2/Test_p_x/FATBAND_si1_3p_x.lobster",
1511
                    ),
1512
                    os.path.join(
1513
                        PymatgenTest.TEST_FILES_DIR,
1514
                        "cohp",
1515
                        "Fatband_SiO2/Test_p/FATBAND_si1_3p.lobster",
1516
                    ),
1517
                ],
1518
                Kpointsfile=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x/KPOINTS"),
1519
                vasprun=os.path.join(
1520
                    PymatgenTest.TEST_FILES_DIR,
1521
                    "cohp",
1522
                    "Fatband_SiO2/Test_p_x/vasprun.xml",
1523
                ),
1524
            )
1525

1526
        with pytest.raises(ValueError):
1✔
1527
            self.fatband_SiO2_p_x = Fatband(
1✔
1528
                filenames=".",
1529
                Kpointsfile=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "Fatband_SiO2/Test_p_x/KPOINTS"),
1530
                vasprun=os.path.join(
1531
                    PymatgenTest.TEST_FILES_DIR,
1532
                    "cohp",
1533
                    "Fatband_SiO2/Test_p_x/vasprun.xml",
1534
                ),
1535
            )
1536

1537
    def test_get_bandstructure(self):
1✔
1538
        bs_p = self.fatband_SiO2_p.get_bandstructure()
1✔
1539
        atom1 = bs_p.structure[0]
1✔
1540
        atom2 = self.bs_symmline2.structure[0]
1✔
1541
        assert atom1.frac_coords[0] == approx(atom2.frac_coords[0])
1✔
1542
        assert atom1.frac_coords[1] == approx(atom2.frac_coords[1])
1✔
1543
        assert atom1.frac_coords[2] == approx(atom2.frac_coords[2])
1✔
1544
        assert atom1.coords[0] == approx(atom2.coords[0])
1✔
1545
        assert atom1.coords[1] == approx(atom2.coords[1])
1✔
1546
        assert atom1.coords[2] == approx(atom2.coords[2])
1✔
1547
        assert atom1.species_string == atom2.species_string
1✔
1548
        assert bs_p.efermi == self.bs_symmline2.efermi
1✔
1549
        branch1 = bs_p.branches[0]
1✔
1550
        branch2 = self.bs_symmline2.branches[0]
1✔
1551
        assert branch2["name"] == branch1["name"]
1✔
1552
        assert branch2["start_index"] == branch1["start_index"]
1✔
1553
        assert branch2["end_index"] == branch1["end_index"]
1✔
1554

1555
        assert bs_p.distance[30] == approx(self.bs_symmline2.distance[30])
1✔
1556
        lattice1 = bs_p.lattice_rec.as_dict()
1✔
1557
        lattice2 = self.bs_symmline2.lattice_rec.as_dict()
1✔
1558
        assert lattice1["matrix"][0][0] == approx(lattice2["matrix"][0][0])
1✔
1559
        assert lattice1["matrix"][0][1] == approx(lattice2["matrix"][0][1])
1✔
1560
        assert lattice1["matrix"][0][2] == approx(lattice2["matrix"][0][2])
1✔
1561
        assert lattice1["matrix"][1][0] == approx(lattice2["matrix"][1][0])
1✔
1562
        assert lattice1["matrix"][1][1] == approx(lattice2["matrix"][1][1])
1✔
1563
        assert lattice1["matrix"][1][2] == approx(lattice2["matrix"][1][2])
1✔
1564
        assert lattice1["matrix"][2][0] == approx(lattice2["matrix"][2][0])
1✔
1565
        assert lattice1["matrix"][2][1] == approx(lattice2["matrix"][2][1])
1✔
1566
        assert lattice1["matrix"][2][2] == approx(lattice2["matrix"][2][2])
1✔
1567

1568
        assert bs_p.kpoints[8].frac_coords[0] == approx(self.bs_symmline2.kpoints[8].frac_coords[0])
1✔
1569
        assert bs_p.kpoints[8].frac_coords[1] == approx(self.bs_symmline2.kpoints[8].frac_coords[1])
1✔
1570
        assert bs_p.kpoints[8].frac_coords[2] == approx(self.bs_symmline2.kpoints[8].frac_coords[2])
1✔
1571
        assert bs_p.kpoints[8].cart_coords[0] == approx(self.bs_symmline2.kpoints[8].cart_coords[0])
1✔
1572
        assert bs_p.kpoints[8].cart_coords[1] == approx(self.bs_symmline2.kpoints[8].cart_coords[1])
1✔
1573
        assert bs_p.kpoints[8].cart_coords[2] == approx(self.bs_symmline2.kpoints[8].cart_coords[2])
1✔
1574
        assert bs_p.kpoints[50].frac_coords[0] == approx(self.bs_symmline2.kpoints[50].frac_coords[0])
1✔
1575
        assert bs_p.kpoints[50].frac_coords[1] == approx(self.bs_symmline2.kpoints[50].frac_coords[1])
1✔
1576
        assert bs_p.kpoints[50].frac_coords[2] == approx(self.bs_symmline2.kpoints[50].frac_coords[2])
1✔
1577
        assert bs_p.kpoints[50].cart_coords[0] == approx(self.bs_symmline2.kpoints[50].cart_coords[0])
1✔
1578
        assert bs_p.kpoints[50].cart_coords[1] == approx(self.bs_symmline2.kpoints[50].cart_coords[1])
1✔
1579
        assert bs_p.kpoints[50].cart_coords[2] == approx(self.bs_symmline2.kpoints[50].cart_coords[2])
1✔
1580
        assert bs_p.get_band_gap()["energy"] == approx(self.bs_symmline2.get_band_gap()["energy"], abs=1e-2)
1✔
1581
        assert bs_p.get_projection_on_elements()[Spin.up][0][0]["Si"] == approx(3 * (0.001 + 0.064))
1✔
1582
        assert bs_p.get_projections_on_elements_and_orbitals({"Si": ["3p"]})[Spin.up][0][0]["Si"]["3p"] == approx(0.003)
1✔
1583
        assert bs_p.get_projections_on_elements_and_orbitals({"O": ["2p"]})[Spin.up][0][0]["O"]["2p"] == approx(
1✔
1584
            0.002 * 3 + 0.003 * 3
1585
        )
1586
        dict_here = bs_p.get_projections_on_elements_and_orbitals({"Si": ["3s", "3p"], "O": ["2s", "2p"]})[Spin.up][0][
1✔
1587
            0
1588
        ]
1589
        assert dict_here["Si"]["3s"] == approx(0.192)
1✔
1590
        assert dict_here["Si"]["3p"] == approx(0.003)
1✔
1591
        assert dict_here["O"]["2s"] == approx(0.792)
1✔
1592
        assert dict_here["O"]["2p"] == approx(0.015)
1✔
1593

1594
        bs_spin = self.fatband_SiO2_spin.get_bandstructure()
1✔
1595
        assert bs_spin.get_projection_on_elements()[Spin.up][0][0]["Si"] == approx(3 * (0.001 + 0.064))
1✔
1596
        assert bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3p"]})[Spin.up][0][0]["Si"]["3p"] == approx(
1✔
1597
            0.003
1598
        )
1599
        assert bs_spin.get_projections_on_elements_and_orbitals({"O": ["2p"]})[Spin.up][0][0]["O"]["2p"] == approx(
1✔
1600
            0.002 * 3 + 0.003 * 3
1601
        )
1602
        dict_here = bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3s", "3p"], "O": ["2s", "2p"]})[Spin.up][
1✔
1603
            0
1604
        ][0]
1605
        assert dict_here["Si"]["3s"] == approx(0.192)
1✔
1606
        assert dict_here["Si"]["3p"] == approx(0.003)
1✔
1607
        assert dict_here["O"]["2s"] == approx(0.792)
1✔
1608
        assert dict_here["O"]["2p"] == approx(0.015)
1✔
1609

1610
        assert bs_spin.get_projection_on_elements()[Spin.up][0][0]["Si"] == approx(3 * (0.001 + 0.064))
1✔
1611
        assert bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3p"]})[Spin.down][0][0]["Si"]["3p"] == approx(
1✔
1612
            0.003
1613
        )
1614
        assert bs_spin.get_projections_on_elements_and_orbitals({"O": ["2p"]})[Spin.down][0][0]["O"]["2p"] == approx(
1✔
1615
            0.002 * 3 + 0.003 * 3
1616
        )
1617
        dict_here = bs_spin.get_projections_on_elements_and_orbitals({"Si": ["3s", "3p"], "O": ["2s", "2p"]})[
1✔
1618
            Spin.down
1619
        ][0][0]
1620
        assert dict_here["Si"]["3s"] == approx(0.192)
1✔
1621
        assert dict_here["Si"]["3p"] == approx(0.003)
1✔
1622
        assert dict_here["O"]["2s"] == approx(0.792)
1✔
1623
        assert dict_here["O"]["2p"] == approx(0.015)
1✔
1624
        bs_p_x = self.fatband_SiO2_p_x.get_bandstructure()
1✔
1625
        assert bs_p_x.get_projection_on_elements()[Spin.up][0][0]["Si"] == approx(3 * (0.001 + 0.064), abs=1e-2)
1✔
1626

1627

1628
class LobsterinTest(unittest.TestCase):
1✔
1629
    def setUp(self):
1✔
1630
        warnings.simplefilter("ignore")
1✔
1631
        self.Lobsterinfromfile = Lobsterin.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterin.1"))
1✔
1632
        self.Lobsterinfromfile2 = Lobsterin.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterin.2"))
1✔
1633
        self.Lobsterinfromfile3 = Lobsterin.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterin.3"))
1✔
1634
        self.Lobsterinfromfile4 = Lobsterin.from_file(
1✔
1635
            os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "lobsterin.4.gz")
1636
        )
1637

1638
    def test_from_file(self):
1✔
1639
        # test read from file
1640
        assert self.Lobsterinfromfile["cohpstartenergy"] == approx(-15.0)
1✔
1641
        assert self.Lobsterinfromfile["cohpendenergy"] == approx(5.0)
1✔
1642
        assert self.Lobsterinfromfile["basisset"] == "pbeVaspFit2015"
1✔
1643
        assert self.Lobsterinfromfile["gaussiansmearingwidth"] == approx(0.1)
1✔
1644
        assert self.Lobsterinfromfile["basisfunctions"][0] == "Fe 3d 4p 4s"
1✔
1645
        assert self.Lobsterinfromfile["basisfunctions"][1] == "Co 3d 4p 4s"
1✔
1646
        assert self.Lobsterinfromfile["skipdos"] is True
1✔
1647
        assert self.Lobsterinfromfile["skipcohp"] is True
1✔
1648
        assert self.Lobsterinfromfile["skipcoop"] is True
1✔
1649
        assert self.Lobsterinfromfile["skippopulationanalysis"] is True
1✔
1650
        assert self.Lobsterinfromfile["skipgrosspopulation"] is True
1✔
1651

1652
        # test if comments are correctly removed
1653
        assert self.Lobsterinfromfile == self.Lobsterinfromfile2
1✔
1654

1655
    def test_getitem(self):
1✔
1656
        # tests implementation of getitem, should be case independent
1657
        assert self.Lobsterinfromfile["COHPSTARTENERGY"] == approx(-15.0)
1✔
1658

1659
    def test_setitem(self):
1✔
1660
        # test implementation of setitem
1661
        self.Lobsterinfromfile["skipCOHP"] = False
1✔
1662
        assert self.Lobsterinfromfile["skipcohp"] is False
1✔
1663

1664
    def test_initialize_from_dict(self):
1✔
1665
        # initialize from dict
1666
        lobsterin1 = Lobsterin(
1✔
1667
            {
1668
                "cohpstartenergy": -15.0,
1669
                "cohpendenergy": 5.0,
1670
                "basisset": "pbeVaspFit2015",
1671
                "gaussiansmearingwidth": 0.1,
1672
                "basisfunctions": ["Fe 3d 4p 4s", "Co 3d 4p 4s"],
1673
                "skipdos": True,
1674
                "skipcohp": True,
1675
                "skipcoop": True,
1676
                "skippopulationanalysis": True,
1677
                "skipgrosspopulation": True,
1678
            }
1679
        )
1680
        assert lobsterin1["cohpstartenergy"] == approx(-15.0)
1✔
1681
        assert lobsterin1["cohpendenergy"] == approx(5.0)
1✔
1682
        assert lobsterin1["basisset"] == "pbeVaspFit2015"
1✔
1683
        assert lobsterin1["gaussiansmearingwidth"] == approx(0.1)
1✔
1684
        assert lobsterin1["basisfunctions"][0] == "Fe 3d 4p 4s"
1✔
1685
        assert lobsterin1["basisfunctions"][1] == "Co 3d 4p 4s"
1✔
1686
        assert lobsterin1["skipdos"] is True
1✔
1687
        assert lobsterin1["skipcohp"] is True
1✔
1688
        assert lobsterin1["skipcoop"] is True
1✔
1689
        assert lobsterin1["skippopulationanalysis"] is True
1✔
1690
        assert lobsterin1["skipgrosspopulation"] is True
1✔
1691
        with pytest.raises(IOError):
1✔
1692
            lobsterin2 = Lobsterin({"cohpstartenergy": -15.0, "cohpstartEnergy": -20.0})
1✔
1693
        lobsterin2 = Lobsterin({"cohpstartenergy": -15.0})
1✔
1694
        # can only calculate nbands if basis functions are provided
1695
        with pytest.raises(IOError):
1✔
1696
            lobsterin2._get_nbands(structure=Structure.from_file(os.path.join(test_dir_doscar, "POSCAR.Fe3O4")))
1✔
1697

1698
    def test_standard_settings(self):
1✔
1699
        # test standard settings
1700
        for option in [
1✔
1701
            "standard",
1702
            "standard_from_projection",
1703
            "standard_with_fatband",
1704
            "onlyprojection",
1705
            "onlydos",
1706
            "onlycohp",
1707
            "onlycoop",
1708
            "onlycobi",
1709
            "onlycohpcoop",
1710
            "onlycohpcoopcobi",
1711
        ]:
1712
            lobsterin1 = Lobsterin.standard_calculations_from_vasp_files(
1✔
1713
                os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1714
                os.path.join(test_dir_doscar, "INCAR.lobster"),
1715
                os.path.join(test_dir_doscar, "POTCAR.Fe3O4"),
1716
                option=option,
1717
            )
1718
            assert lobsterin1["cohpstartenergy"] == approx(-35.0)
1✔
1719
            assert lobsterin1["cohpendenergy"] == approx(5.0)
1✔
1720
            assert lobsterin1["basisset"] == "pbeVaspFit2015"
1✔
1721
            assert lobsterin1["gaussiansmearingwidth"] == approx(0.1)
1✔
1722
            assert lobsterin1["basisfunctions"][0] == "Fe 3d 4p 4s "
1✔
1723
            assert lobsterin1["basisfunctions"][1] == "O 2p 2s "
1✔
1724

1725
            if option in [
1✔
1726
                "standard",
1727
                "standard_with_fatband",
1728
                "onlyprojection",
1729
                "onlycohp",
1730
                "onlycoop",
1731
                "onlycohpcoop",
1732
            ]:
1733
                assert lobsterin1["saveProjectiontoFile"] is True
1✔
1734
            if option in [
1✔
1735
                "standard",
1736
                "standard_with_fatband",
1737
                "onlycohp",
1738
                "onlycoop",
1739
                "onlycohpcoop",
1740
            ]:
1741
                assert lobsterin1["cohpGenerator"] == "from 0.1 to 6.0 orbitalwise"
1✔
1742
            if option in ["standard"]:
1✔
1743
                assert ("skipdos" not in lobsterin1) is True
1✔
1744
                assert ("skipcohp" not in lobsterin1) is True
1✔
1745
                assert ("skipcoop" not in lobsterin1) is True
1✔
1746
            if option in ["standard_with_fatband"]:
1✔
1747
                assert lobsterin1["createFatband"] == ["Fe 3d 4p 4s ", "O 2p 2s "]
1✔
1748
                assert ("skipdos" not in lobsterin1) is True
1✔
1749
                assert ("skipcohp" not in lobsterin1) is True
1✔
1750
                assert ("skipcoop" not in lobsterin1) is True
1✔
1751
            if option in ["standard_from_projection"]:
1✔
1752
                assert lobsterin1["loadProjectionFromFile"], True
1✔
1753
            if option in [
1✔
1754
                "onlyprojection",
1755
                "onlycohp",
1756
                "onlycoop",
1757
                "onlycobi",
1758
                "onlycohpcoop",
1759
                "onlycohpcoopcobi",
1760
            ]:
1761
                assert lobsterin1["skipdos"], True
1✔
1762
                assert lobsterin1["skipPopulationAnalysis"], True
1✔
1763
                assert lobsterin1["skipGrossPopulation"], True
1✔
1764
                assert lobsterin1["skipMadelungEnergy"], True
1✔
1765

1766
            if option in ["onlydos"]:
1✔
1767
                assert lobsterin1["skipPopulationAnalysis"], True
1✔
1768
                assert lobsterin1["skipGrossPopulation"], True
1✔
1769
                assert lobsterin1["skipcohp"], True
1✔
1770
                assert lobsterin1["skipcoop"], True
1✔
1771
                assert lobsterin1["skipcobi"], True
1✔
1772
                assert lobsterin1["skipMadelungEnergy"], True
1✔
1773
            if option in ["onlycohp"]:
1✔
1774
                assert lobsterin1["skipcoop"], True
1✔
1775
                assert lobsterin1["skipcobi"], True
1✔
1776
            if option in ["onlycoop"]:
1✔
1777
                assert lobsterin1["skipcohp"], True
1✔
1778
                assert lobsterin1["skipcobi"], True
1✔
1779
            if option in ["onlyprojection"]:
1✔
1780
                assert lobsterin1["skipdos"], True
1✔
1781
            if option in ["onlymadelung"]:
1✔
1782
                assert lobsterin1["skipPopulationAnalysis"], True
×
1783
                assert lobsterin1["skipGrossPopulation"], True
×
1784
                assert lobsterin1["skipcohp"], True
×
1785
                assert lobsterin1["skipcoop"], True
×
1786
                assert lobsterin1["skipcobi"], True
×
1787
                assert lobsterin1["skipdos"], True
×
1788
        # test basis functions by dict
1789
        lobsterin_new = Lobsterin.standard_calculations_from_vasp_files(
1✔
1790
            os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1791
            os.path.join(test_dir_doscar, "INCAR.lobster"),
1792
            dict_for_basis={"Fe": "3d 4p 4s", "O": "2s 2p"},
1793
            option="standard",
1794
        )
1795
        assert lobsterin_new["basisfunctions"] == ["Fe 3d 4p 4s", "O 2s 2p"]
1✔
1796

1797
        # test gaussian smearing
1798
        lobsterin_new = Lobsterin.standard_calculations_from_vasp_files(
1✔
1799
            os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1800
            os.path.join(test_dir_doscar, "INCAR.lobster2"),
1801
            dict_for_basis={"Fe": "3d 4p 4s", "O": "2s 2p"},
1802
            option="standard",
1803
        )
1804
        assert "gaussiansmearingwidth" not in lobsterin_new
1✔
1805

1806
        # fatband and ISMEAR=-5 does not work together
1807
        with pytest.raises(ValueError):
1✔
1808
            lobsterin_new = Lobsterin.standard_calculations_from_vasp_files(
1✔
1809
                os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1810
                os.path.join(test_dir_doscar, "INCAR.lobster2"),
1811
                dict_for_basis={"Fe": "3d 4p 4s", "O": "2s 2p"},
1812
                option="standard_with_fatband",
1813
            )
1814

1815
    def test_standard_with_energy_range_from_vasprun(self):
1✔
1816
        # test standard_with_energy_range_from_vasprun
1817
        lobsterin_comp = Lobsterin.standard_calculations_from_vasp_files(
1✔
1818
            os.path.join(test_dir_doscar, "POSCAR.C2.gz"),
1819
            os.path.join(test_dir_doscar, "INCAR.C2.gz"),
1820
            os.path.join(test_dir_doscar, "POTCAR.C2.gz"),
1821
            os.path.join(test_dir_doscar, "vasprun.xml.C2.gz"),
1822
            option="standard_with_energy_range_from_vasprun",
1823
        )
1824
        assert lobsterin_comp["COHPstartEnergy"] == -28.3679
1✔
1825
        assert lobsterin_comp["COHPendEnergy"] == 32.8968
1✔
1826
        assert lobsterin_comp["COHPSteps"] == 301
1✔
1827

1828
    def test_diff(self):
1✔
1829
        # test diff
1830
        assert self.Lobsterinfromfile.diff(self.Lobsterinfromfile2)["Different"] == {}
1✔
1831
        assert self.Lobsterinfromfile.diff(self.Lobsterinfromfile2)["Same"]["COHPSTARTENERGY"] == approx(-15.0)
1✔
1832

1833
        # test diff in both directions
1834
        for entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Same"]:
1✔
1835
            assert entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Same"]
1✔
1836
        for entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Same"]:
1✔
1837
            assert entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Same"]
1✔
1838
        for entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Different"]:
1✔
1839
            assert entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Different"]
1✔
1840
        for entry in self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Different"]:
1✔
1841
            assert entry in self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Different"]
1✔
1842

1843
        assert (
1✔
1844
            self.Lobsterinfromfile.diff(self.Lobsterinfromfile3)["Different"]["SKIPCOHP"]["lobsterin1"]
1845
            == self.Lobsterinfromfile3.diff(self.Lobsterinfromfile)["Different"]["SKIPCOHP"]["lobsterin2"]
1846
        )
1847

1848
    def test_get_basis(self):
1✔
1849
        # get basis functions
1850
        lobsterin1 = Lobsterin({})
1✔
1851
        potcar = Potcar.from_file(os.path.join(test_dir_doscar, "POTCAR.Fe3O4"))
1✔
1852
        Potcar_names = [name["symbol"] for name in potcar.spec]
1✔
1853

1854
        assert lobsterin1.get_basis(
1✔
1855
            Structure.from_file(os.path.join(test_dir_doscar, "Fe3O4.cif")),
1856
            potcar_symbols=Potcar_names,
1857
        ) == ["Fe 3d 4p 4s ", "O 2p 2s "]
1858
        potcar = Potcar.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "POTCAR.GaAs"))
1✔
1859
        Potcar_names = [name["symbol"] for name in potcar.spec]
1✔
1860
        assert lobsterin1.get_basis(
1✔
1861
            Structure.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "POSCAR.GaAs")),
1862
            potcar_symbols=Potcar_names,
1863
        ) == ["Ga 3d 4p 4s ", "As 4p 4s "]
1864

1865
    def test_get_all_possible_basis_functions(self):
1✔
1866
        potcar = Potcar.from_file(os.path.join(test_dir_doscar, "POTCAR.Fe3O4"))
1✔
1867
        Potcar_names = [name["symbol"] for name in potcar.spec]
1✔
1868
        result = Lobsterin.get_all_possible_basis_functions(
1✔
1869
            Structure.from_file(os.path.join(test_dir_doscar, "Fe3O4.cif")),
1870
            potcar_symbols=Potcar_names,
1871
        )
1872
        assert result[0] == {"Fe": "3d 4s", "O": "2p 2s"}
1✔
1873
        assert result[1] == {"Fe": "3d 4s 4p", "O": "2p 2s"}
1✔
1874

1875
        potcar2 = Potcar.from_file(os.path.join(test_dir_doscar, "POT_GGA_PAW_PBE_54/POTCAR.Fe_pv.gz"))
1✔
1876
        Potcar_names2 = [name["symbol"] for name in potcar2.spec]
1✔
1877
        result2 = Lobsterin.get_all_possible_basis_functions(
1✔
1878
            Structure.from_file(os.path.join(test_dir_doscar, "Fe.cif")),
1879
            potcar_symbols=Potcar_names2,
1880
        )
1881
        assert result2[0] == {"Fe": "3d 3p 4s"}
1✔
1882

1883
    def test_get_potcar_symbols(self):
1✔
1884
        lobsterin1 = Lobsterin({})
1✔
1885
        assert lobsterin1._get_potcar_symbols(os.path.join(test_dir_doscar, "POTCAR.Fe3O4")) == ["Fe", "O"]
1✔
1886
        assert lobsterin1._get_potcar_symbols(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "POTCAR.GaAs")) == [
1✔
1887
            "Ga_d",
1888
            "As",
1889
        ]
1890

1891
    def test_write_lobsterin(self):
1✔
1892
        # write lobsterin, read it and compare it
1893
        outfile_path = tempfile.mkstemp()[1]
1✔
1894
        lobsterin1 = Lobsterin.standard_calculations_from_vasp_files(
1✔
1895
            os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1896
            os.path.join(test_dir_doscar, "INCAR.lobster"),
1897
            os.path.join(test_dir_doscar, "POTCAR.Fe3O4"),
1898
            option="standard",
1899
        )
1900
        lobsterin1.write_lobsterin(outfile_path)
1✔
1901
        lobsterin2 = Lobsterin.from_file(outfile_path)
1✔
1902
        assert lobsterin1.diff(lobsterin2)["Different"] == {}
1✔
1903

1904
    def test_write_INCAR(self):
1✔
1905
        # write INCAR and compare
1906
        outfile_path = tempfile.mkstemp()[1]
1✔
1907
        lobsterin1 = Lobsterin.standard_calculations_from_vasp_files(
1✔
1908
            os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1909
            os.path.join(test_dir_doscar, "INCAR.lobster"),
1910
            os.path.join(test_dir_doscar, "POTCAR.Fe3O4"),
1911
            option="standard",
1912
        )
1913
        lobsterin1.write_INCAR(
1✔
1914
            os.path.join(test_dir_doscar, "INCAR.lobster3"),
1915
            outfile_path,
1916
            os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1917
        )
1918

1919
        incar1 = Incar.from_file(os.path.join(test_dir_doscar, "INCAR.lobster3"))
1✔
1920
        incar2 = Incar.from_file(outfile_path)
1✔
1921

1922
        assert incar1.diff(incar2)["Different"] == {
1✔
1923
            "ISYM": {"INCAR1": 2, "INCAR2": -1},
1924
            "NBANDS": {"INCAR1": None, "INCAR2": 86},
1925
            "NSW": {"INCAR1": 500, "INCAR2": 0},
1926
            "LWAVE": {"INCAR1": False, "INCAR2": True},
1927
        }
1928

1929
    def test_write_KPOINTS(self):
1✔
1930
        # line mode
1931
        outfile_path = tempfile.mkstemp()[1]
1✔
1932
        outfile_path2 = tempfile.mkstemp(prefix="POSCAR")[1]
1✔
1933
        lobsterin1 = Lobsterin({})
1✔
1934
        # test writing primitive cell
1935
        lobsterin1.write_POSCAR_with_standard_primitive(
1✔
1936
            POSCAR_input=os.path.join(test_dir_doscar, "POSCAR.Fe3O4"),
1937
            POSCAR_output=outfile_path2,
1938
        )
1939

1940
        lobsterin1.write_KPOINTS(
1✔
1941
            POSCAR_input=outfile_path2,
1942
            KPOINTS_output=outfile_path,
1943
            kpoints_line_density=58,
1944
        )
1945
        kpoint = Kpoints.from_file(outfile_path)
1✔
1946
        assert kpoint.num_kpts == 562
1✔
1947
        assert kpoint.kpts[-1][0] == approx(-0.5)
1✔
1948
        assert kpoint.kpts[-1][1] == approx(0.5)
1✔
1949
        assert kpoint.kpts[-1][2] == approx(0.5)
1✔
1950
        assert kpoint.labels[-1] == "T"
1✔
1951
        kpoint2 = Kpoints.from_file(os.path.join(test_dir_doscar, "KPOINTS_band.lobster"))
1✔
1952

1953
        labels = []
1✔
1954
        number = 0
1✔
1955
        for label in kpoint.labels:
1✔
1956
            if label is not None:
1✔
1957
                if number != 0:
1✔
1958
                    if label != labels[number - 1]:
1✔
1959
                        labels.append(label)
1✔
1960
                        number += 1
1✔
1961
                else:
1962
                    labels.append(label)
1✔
1963
                    number += 1
1✔
1964

1965
        labels2 = []
1✔
1966
        number2 = 0
1✔
1967
        for label in kpoint2.labels:
1✔
1968
            if label is not None:
1✔
1969
                if number2 != 0:
1✔
1970
                    if label != labels2[number2 - 1]:
1✔
1971
                        labels2.append(label)
1✔
1972
                        number2 += 1
1✔
1973
                else:
1974
                    labels2.append(label)
1✔
1975
                    number2 += 1
1✔
1976
        assert labels == labels2
1✔
1977

1978
        # without line mode
1979
        lobsterin1.write_KPOINTS(POSCAR_input=outfile_path2, KPOINTS_output=outfile_path, line_mode=False)
1✔
1980
        kpoint = Kpoints.from_file(outfile_path)
1✔
1981
        kpoint2 = Kpoints.from_file(os.path.join(test_dir_doscar, "IBZKPT.lobster"))
1✔
1982

1983
        for num_kpt, list_kpoint in enumerate(kpoint.kpts):
1✔
1984
            assert list_kpoint[0] == approx(kpoint2.kpts[num_kpt][0])
1✔
1985
            assert list_kpoint[1] == approx(kpoint2.kpts[num_kpt][1])
1✔
1986
            assert list_kpoint[2] == approx(kpoint2.kpts[num_kpt][2])
1✔
1987

1988
        assert kpoint.num_kpts == 108
1✔
1989

1990
        # without line mode, use grid instead of reciprocal density
1991
        lobsterin1.write_KPOINTS(
1✔
1992
            POSCAR_input=outfile_path2,
1993
            KPOINTS_output=outfile_path,
1994
            line_mode=False,
1995
            from_grid=True,
1996
            input_grid=[6, 6, 3],
1997
        )
1998
        kpoint = Kpoints.from_file(outfile_path)
1✔
1999
        kpoint2 = Kpoints.from_file(os.path.join(test_dir_doscar, "IBZKPT.lobster"))
1✔
2000

2001
        for num_kpt, list_kpoint in enumerate(kpoint.kpts):
1✔
2002
            assert list_kpoint[0] == approx(kpoint2.kpts[num_kpt][0])
1✔
2003
            assert list_kpoint[1] == approx(kpoint2.kpts[num_kpt][1])
1✔
2004
            assert list_kpoint[2] == approx(kpoint2.kpts[num_kpt][2])
1✔
2005

2006
        assert kpoint.num_kpts == 108
1✔
2007

2008
        #
2009
        # #without line mode, using a certain grid, isym=0 instead of -1
2010
        lobsterin1.write_KPOINTS(
1✔
2011
            POSCAR_input=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "POSCAR.Li"),
2012
            KPOINTS_output=outfile_path,
2013
            line_mode=False,
2014
            from_grid=True,
2015
            input_grid=[3, 3, 3],
2016
            isym=0,
2017
        )
2018

2019
        kpoint1 = Kpoints.from_file(outfile_path)
1✔
2020
        kpoint2 = Kpoints.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "IBZKPT_3_3_3_Li"))
1✔
2021
        for ikpoint, kpoint in enumerate(kpoint1.kpts):
1✔
2022
            assert self.is_kpoint_in_list(
1✔
2023
                kpoint,
2024
                kpoint2.kpts,
2025
                kpoint1.kpts_weights[ikpoint],
2026
                kpoint2.kpts_weights,
2027
            )
2028
        for ikpoint, kpoint in enumerate(kpoint2.kpts):
1✔
2029
            assert self.is_kpoint_in_list(
1✔
2030
                kpoint,
2031
                kpoint1.kpts,
2032
                kpoint2.kpts_weights[ikpoint],
2033
                kpoint1.kpts_weights,
2034
            )
2035

2036
        lobsterin1.write_KPOINTS(
1✔
2037
            POSCAR_input=os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "POSCAR.Li"),
2038
            KPOINTS_output=outfile_path,
2039
            line_mode=False,
2040
            from_grid=True,
2041
            input_grid=[2, 2, 2],
2042
            isym=0,
2043
        )
2044

2045
        kpoint1 = Kpoints.from_file(outfile_path)
1✔
2046
        kpoint2 = Kpoints.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "IBZKPT_2_2_2_Li"))
1✔
2047
        for ikpoint, kpoint in enumerate(kpoint1.kpts):
1✔
2048
            assert self.is_kpoint_in_list(
1✔
2049
                kpoint,
2050
                kpoint2.kpts,
2051
                kpoint1.kpts_weights[ikpoint],
2052
                kpoint2.kpts_weights,
2053
            )
2054
        for ikpoint, kpoint in enumerate(kpoint2.kpts):
1✔
2055
            assert self.is_kpoint_in_list(
1✔
2056
                kpoint,
2057
                kpoint1.kpts,
2058
                kpoint2.kpts_weights[ikpoint],
2059
                kpoint1.kpts_weights,
2060
            )
2061

2062
    def is_kpoint_in_list(self, kpoint, kpointlist, weight, weightlist) -> bool:
1✔
2063
        found = 0
1✔
2064
        for ikpoint2, kpoint2 in enumerate(kpointlist):
1✔
2065
            if (
1✔
2066
                np.isclose(kpoint[0], kpoint2[0])
2067
                and np.isclose(kpoint[1], kpoint2[1])
2068
                and np.isclose(kpoint[2], kpoint2[2])
2069
            ):
2070
                if weight == weightlist[ikpoint2]:
1✔
2071
                    found += 1
1✔
2072
            elif (
1✔
2073
                np.isclose(-kpoint[0], kpoint2[0])
2074
                and np.isclose(-kpoint[1], kpoint2[1])
2075
                and np.isclose(-kpoint[2], kpoint2[2])
2076
            ):
2077
                if weight == weightlist[ikpoint2]:
×
2078
                    found += 1
×
2079
        if found == 1:
1✔
2080
            return True
1✔
2081
        else:
2082
            return False
×
2083

2084
    def test_MSONable_implementation(self):
1✔
2085
        # tests as dict and from dict methods
2086
        newLobsterin = Lobsterin.from_dict(self.Lobsterinfromfile.as_dict())
1✔
2087
        assert newLobsterin == self.Lobsterinfromfile
1✔
2088
        newLobsterin.to_json()
1✔
2089

2090
    def tearDown(self):
1✔
2091
        warnings.simplefilter("default")
1✔
2092

2093

2094
class BandoverlapsTest(unittest.TestCase):
1✔
2095
    def setUp(self):
1✔
2096
        warnings.simplefilter("ignore")
1✔
2097
        # test spin polarlized calc and non spinpolarized calc
2098

2099
        self.bandoverlaps1 = Bandoverlaps(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "bandOverlaps.lobster.1"))
1✔
2100
        self.bandoverlaps2 = Bandoverlaps(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "bandOverlaps.lobster.2"))
1✔
2101

2102
        self.bandoverlaps1_new = Bandoverlaps(
1✔
2103
            os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "bandOverlaps.lobster.new.1")
2104
        )
2105
        self.bandoverlaps2_new = Bandoverlaps(
1✔
2106
            os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "bandOverlaps.lobster.new.2")
2107
        )
2108

2109
    def test_attributes(self):
1✔
2110
        # bandoverlapsdict
2111
        assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["maxDeviation"] == approx(0.000278953)
1✔
2112
        assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["0 0 0"]["maxDeviation"] == approx(0.0640933)
1✔
2113
        assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["matrix"][-1][-1] == approx(0.0188058)
1✔
2114
        assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["0 0 0"]["matrix"][-1][-1] == approx(1.0)
1✔
2115
        assert self.bandoverlaps1.bandoverlapsdict[Spin.up]["0.5 0 0"]["matrix"][0][0] == approx(1)
1✔
2116
        assert self.bandoverlaps1_new.bandoverlapsdict[Spin.up]["0 0 0"]["matrix"][0][0] == approx(0.995849)
1✔
2117

2118
        assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["0.0261194 0.0261194 0.473881"]["maxDeviation"] == approx(
1✔
2119
            4.31567e-05
2120
        )
2121
        assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["0 0 0"]["maxDeviation"] == approx(0.064369)
1✔
2122
        assert self.bandoverlaps1.bandoverlapsdict[Spin.down]["0.0261194 0.0261194 0.473881"]["matrix"][0][
1✔
2123
            -1
2124
        ] == approx(4.0066e-07)
2125
        assert self.bandoverlaps1_new.bandoverlapsdict[Spin.down]["0 0 0"]["matrix"][0][-1] == approx(1.37447e-09)
1✔
2126

2127
        # maxDeviation
2128
        assert self.bandoverlaps1.max_deviation[0] == approx(0.000278953)
1✔
2129
        assert self.bandoverlaps1_new.max_deviation[0] == approx(0.39824)
1✔
2130
        assert self.bandoverlaps1.max_deviation[-1] == approx(4.31567e-05)
1✔
2131
        assert self.bandoverlaps1_new.max_deviation[-1] == approx(0.324898)
1✔
2132

2133
        assert self.bandoverlaps2.max_deviation[0] == approx(0.000473319)
1✔
2134
        assert self.bandoverlaps2_new.max_deviation[0] == approx(0.403249)
1✔
2135
        assert self.bandoverlaps2.max_deviation[-1] == approx(1.48451e-05)
1✔
2136
        assert self.bandoverlaps2_new.max_deviation[-1] == approx(0.45154)
1✔
2137

2138
    def test_has_good_quality(self):
1✔
2139
        assert not self.bandoverlaps1.has_good_quality_maxDeviation(limit_maxDeviation=0.1)
1✔
2140
        assert not self.bandoverlaps1_new.has_good_quality_maxDeviation(limit_maxDeviation=0.1)
1✔
2141
        assert not self.bandoverlaps1.has_good_quality_check_occupied_bands(
1✔
2142
            number_occ_bands_spin_up=9,
2143
            number_occ_bands_spin_down=5,
2144
            limit_deviation=0.1,
2145
            spin_polarized=True,
2146
        )
2147
        assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands(
1✔
2148
            number_occ_bands_spin_up=9,
2149
            number_occ_bands_spin_down=5,
2150
            limit_deviation=0.1,
2151
            spin_polarized=True,
2152
        )
2153
        assert self.bandoverlaps1.has_good_quality_check_occupied_bands(
1✔
2154
            number_occ_bands_spin_up=3,
2155
            number_occ_bands_spin_down=0,
2156
            limit_deviation=0.001,
2157
            spin_polarized=True,
2158
        )
2159
        assert self.bandoverlaps1_new.has_good_quality_check_occupied_bands(
1✔
2160
            number_occ_bands_spin_up=3,
2161
            number_occ_bands_spin_down=0,
2162
            limit_deviation=0.01,
2163
            spin_polarized=True,
2164
        )
2165
        assert not self.bandoverlaps1.has_good_quality_check_occupied_bands(
1✔
2166
            number_occ_bands_spin_up=1,
2167
            number_occ_bands_spin_down=1,
2168
            limit_deviation=0.000001,
2169
            spin_polarized=True,
2170
        )
2171
        assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands(
1✔
2172
            number_occ_bands_spin_up=1,
2173
            number_occ_bands_spin_down=1,
2174
            limit_deviation=0.000001,
2175
            spin_polarized=True,
2176
        )
2177
        assert not self.bandoverlaps1.has_good_quality_check_occupied_bands(
1✔
2178
            number_occ_bands_spin_up=1,
2179
            number_occ_bands_spin_down=0,
2180
            limit_deviation=0.000001,
2181
            spin_polarized=True,
2182
        )
2183
        assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands(
1✔
2184
            number_occ_bands_spin_up=1,
2185
            number_occ_bands_spin_down=0,
2186
            limit_deviation=0.000001,
2187
            spin_polarized=True,
2188
        )
2189
        assert not self.bandoverlaps1.has_good_quality_check_occupied_bands(
1✔
2190
            number_occ_bands_spin_up=0,
2191
            number_occ_bands_spin_down=1,
2192
            limit_deviation=0.000001,
2193
            spin_polarized=True,
2194
        )
2195
        assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands(
1✔
2196
            number_occ_bands_spin_up=0,
2197
            number_occ_bands_spin_down=1,
2198
            limit_deviation=0.000001,
2199
            spin_polarized=True,
2200
        )
2201
        assert not self.bandoverlaps1.has_good_quality_check_occupied_bands(
1✔
2202
            number_occ_bands_spin_up=4,
2203
            number_occ_bands_spin_down=4,
2204
            limit_deviation=0.001,
2205
            spin_polarized=True,
2206
        )
2207
        assert not self.bandoverlaps1_new.has_good_quality_check_occupied_bands(
1✔
2208
            number_occ_bands_spin_up=4,
2209
            number_occ_bands_spin_down=4,
2210
            limit_deviation=0.001,
2211
            spin_polarized=True,
2212
        )
2213

2214
        assert self.bandoverlaps1.has_good_quality_maxDeviation(limit_maxDeviation=100)
1✔
2215
        assert self.bandoverlaps1_new.has_good_quality_maxDeviation(limit_maxDeviation=100)
1✔
2216
        assert self.bandoverlaps2.has_good_quality_maxDeviation()
1✔
2217
        assert not self.bandoverlaps2_new.has_good_quality_maxDeviation()
1✔
2218
        assert not self.bandoverlaps2.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001)
1✔
2219
        assert not self.bandoverlaps2_new.has_good_quality_maxDeviation(limit_maxDeviation=0.0000001)
1✔
2220
        assert not self.bandoverlaps2.has_good_quality_check_occupied_bands(
1✔
2221
            number_occ_bands_spin_up=10, limit_deviation=0.0000001
2222
        )
2223
        assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands(
1✔
2224
            number_occ_bands_spin_up=10, limit_deviation=0.0000001
2225
        )
2226
        assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=0.1)
1✔
2227
        assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands(
1✔
2228
            number_occ_bands_spin_up=1, limit_deviation=0.1
2229
        )
2230

2231
        assert not self.bandoverlaps2.has_good_quality_check_occupied_bands(
1✔
2232
            number_occ_bands_spin_up=1, limit_deviation=1e-8
2233
        )
2234
        assert not self.bandoverlaps2_new.has_good_quality_check_occupied_bands(
1✔
2235
            number_occ_bands_spin_up=1, limit_deviation=1e-8
2236
        )
2237
        assert self.bandoverlaps2.has_good_quality_check_occupied_bands(
1✔
2238
            number_occ_bands_spin_up=10, limit_deviation=0.1
2239
        )
2240
        assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands(
1✔
2241
            number_occ_bands_spin_up=2, limit_deviation=0.1
2242
        )
2243

2244
        assert self.bandoverlaps2.has_good_quality_check_occupied_bands(number_occ_bands_spin_up=1, limit_deviation=0.1)
1✔
2245
        assert self.bandoverlaps2_new.has_good_quality_check_occupied_bands(
1✔
2246
            number_occ_bands_spin_up=1, limit_deviation=0.1
2247
        )
2248

2249

2250
class GrosspopTest(unittest.TestCase):
1✔
2251
    def setUp(self):
1✔
2252
        self.grosspop1 = Grosspop(os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "GROSSPOP.lobster"))
1✔
2253

2254
    def testattributes(self):
1✔
2255
        assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3s"] == approx(0.52)
1✔
2256
        assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_y"] == approx(0.38)
1✔
2257
        assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_z"] == approx(0.37)
1✔
2258
        assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["3p_x"] == approx(0.37)
1✔
2259
        assert self.grosspop1.list_dict_grosspop[0]["Mulliken GP"]["total"] == approx(1.64)
1✔
2260
        assert self.grosspop1.list_dict_grosspop[0]["element"] == "Si"
1✔
2261
        assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3s"] == approx(0.61)
1✔
2262
        assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_y"] == approx(0.52)
1✔
2263
        assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_z"] == approx(0.52)
1✔
2264
        assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["3p_x"] == approx(0.52)
1✔
2265
        assert self.grosspop1.list_dict_grosspop[0]["Loewdin GP"]["total"] == approx(2.16)
1✔
2266
        assert self.grosspop1.list_dict_grosspop[5]["Mulliken GP"]["2s"] == approx(1.80)
1✔
2267
        assert self.grosspop1.list_dict_grosspop[5]["Loewdin GP"]["2s"] == approx(1.60)
1✔
2268
        assert self.grosspop1.list_dict_grosspop[5]["element"] == "O"
1✔
2269
        assert self.grosspop1.list_dict_grosspop[8]["Mulliken GP"]["2s"] == approx(1.80)
1✔
2270
        assert self.grosspop1.list_dict_grosspop[8]["Loewdin GP"]["2s"] == approx(1.60)
1✔
2271
        assert self.grosspop1.list_dict_grosspop[8]["element"] == "O"
1✔
2272

2273
    def test_structure_with_grosspop(self):
1✔
2274
        struct_dict = {
1✔
2275
            "@module": "pymatgen.core.structure",
2276
            "@class": "Structure",
2277
            "charge": None,
2278
            "lattice": {
2279
                "matrix": [
2280
                    [5.021897888834907, 4.53806e-11, 0.0],
2281
                    [-2.5109484443388332, 4.349090983701526, 0.0],
2282
                    [0.0, 0.0, 5.511929408565514],
2283
                ],
2284
                "a": 5.021897888834907,
2285
                "b": 5.0218974974248045,
2286
                "c": 5.511929408565514,
2287
                "alpha": 90.0,
2288
                "beta": 90.0,
2289
                "gamma": 119.99999598960493,
2290
                "volume": 120.38434608659402,
2291
            },
2292
            "sites": [
2293
                {
2294
                    "species": [{"element": "Si", "occu": 1}],
2295
                    "abc": [-3e-16, 0.4763431475490085, 0.6666669999999968],
2296
                    "xyz": [-1.1960730853096477, 2.0716596881533986, 3.674621443020128],
2297
                    "label": "Si",
2298
                    "properties": {"Total Mulliken GP": 1.64, "Total Loewdin GP": 2.16},
2299
                },
2300
                {
2301
                    "species": [{"element": "Si", "occu": 1}],
2302
                    "abc": [0.5236568524509936, 0.5236568524509926, 0.0],
2303
                    "xyz": [1.3148758827683875, 2.277431295571896, 0.0],
2304
                    "label": "Si",
2305
                    "properties": {"Total Mulliken GP": 1.64, "Total Loewdin GP": 2.16},
2306
                },
2307
                {
2308
                    "species": [{"element": "Si", "occu": 1}],
2309
                    "abc": [0.4763431475490066, -1.2e-15, 0.3333330000000032],
2310
                    "xyz": [
2311
                        2.392146647037334,
2312
                        2.1611518932482004e-11,
2313
                        1.8373079655453863,
2314
                    ],
2315
                    "label": "Si",
2316
                    "properties": {"Total Mulliken GP": 1.64, "Total Loewdin GP": 2.16},
2317
                },
2318
                {
2319
                    "species": [{"element": "O", "occu": 1}],
2320
                    "abc": [0.1589037798059321, 0.7440031622164922, 0.4613477252144715],
2321
                    "xyz": [-1.0701550264153763, 3.235737444648381, 2.5429160941844473],
2322
                    "label": "O",
2323
                    "properties": {"Total Mulliken GP": 7.18, "Total Loewdin GP": 6.92},
2324
                },
2325
                {
2326
                    "species": [{"element": "O", "occu": 1}],
2327
                    "abc": [0.2559968377835071, 0.4149006175894398, 0.7946807252144676],
2328
                    "xyz": [0.2437959189219816, 1.8044405351020447, 4.380224059729795],
2329
                    "label": "O",
2330
                    "properties": {"Total Mulliken GP": 7.18, "Total Loewdin GP": 6.92},
2331
                },
2332
                {
2333
                    "species": [{"element": "O", "occu": 1}],
2334
                    "abc": [0.5850993824105679, 0.8410962201940679, 0.1280147252144683],
2335
                    "xyz": [0.8263601076506712, 3.6580039876980064, 0.7056081286390611],
2336
                    "label": "O",
2337
                    "properties": {"Total Mulliken GP": 7.18, "Total Loewdin GP": 6.92},
2338
                },
2339
                {
2340
                    "species": [{"element": "O", "occu": 1}],
2341
                    "abc": [0.7440031622164928, 0.1589037798059326, 0.5386522747855285],
2342
                    "xyz": [3.337308710918233, 0.6910869960638374, 2.969013314381067],
2343
                    "label": "O",
2344
                    "properties": {"Total Mulliken GP": 7.18, "Total Loewdin GP": 6.92},
2345
                },
2346
                {
2347
                    "species": [{"element": "O", "occu": 1}],
2348
                    "abc": [0.4149006175894392, 0.2559968377835, 0.2053192747855324],
2349
                    "xyz": [1.4407936739605638, 1.1133535390791505, 1.13170534883572],
2350
                    "label": "O",
2351
                    "properties": {"Total Mulliken GP": 7.18, "Total Loewdin GP": 6.92},
2352
                },
2353
                {
2354
                    "species": [{"element": "O", "occu": 1}],
2355
                    "abc": [0.841096220194068, 0.5850993824105675, 0.8719852747855317],
2356
                    "xyz": [2.754744948452184, 2.5446504486493, 4.806321279926453],
2357
                    "label": "O",
2358
                    "properties": {"Total Mulliken GP": 7.18, "Total Loewdin GP": 6.92},
2359
                },
2360
            ],
2361
        }
2362

2363
        newstructure = self.grosspop1.get_structure_with_total_grosspop(
1✔
2364
            os.path.join(PymatgenTest.TEST_FILES_DIR, "cohp", "POSCAR.SiO2")
2365
        )
2366
        for coords, coords2 in zip(newstructure.frac_coords, Structure.from_dict(struct_dict).frac_coords):
1✔
2367
            for xyz, xyz2 in zip(coords, coords2):
1✔
2368
                assert xyz == approx(xyz2)
1✔
2369

2370

2371
class TestUtils(PymatgenTest):
1✔
2372
    def test_get_all_possible_basis_combinations(self):
1✔
2373
        # this basis is just for testing (not correct)
2374
        min_basis = ["Li 1s 2s ", "Na 1s 2s", "Si 1s 2s"]
1✔
2375
        max_basis = ["Li 1s 2p 2s ", "Na 1s 2p 2s", "Si 1s 2s"]
1✔
2376
        combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
1✔
2377
        assert combinations_basis == [
1✔
2378
            ["Li 1s 2s", "Na 1s 2s", "Si 1s 2s"],
2379
            ["Li 1s 2s", "Na 1s 2s 2p", "Si 1s 2s"],
2380
            ["Li 1s 2s 2p", "Na 1s 2s", "Si 1s 2s"],
2381
            ["Li 1s 2s 2p", "Na 1s 2s 2p", "Si 1s 2s"],
2382
        ]
2383

2384
        min_basis = ["Li 1s 2s"]
1✔
2385
        max_basis = ["Li 1s 2s 2p 3s"]
1✔
2386
        combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
1✔
2387
        assert combinations_basis == [["Li 1s 2s"], ["Li 1s 2s 2p"], ["Li 1s 2s 3s"], ["Li 1s 2s 2p 3s"]]
1✔
2388

2389
        min_basis = ["Li 1s 2s", "Na 1s 2s"]
1✔
2390
        max_basis = ["Li 1s 2s 2p 3s", "Na 1s 2s 2p 3s"]
1✔
2391
        combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
1✔
2392
        assert combinations_basis == [
1✔
2393
            ["Li 1s 2s", "Na 1s 2s"],
2394
            ["Li 1s 2s", "Na 1s 2s 2p"],
2395
            ["Li 1s 2s", "Na 1s 2s 3s"],
2396
            ["Li 1s 2s", "Na 1s 2s 2p 3s"],
2397
            ["Li 1s 2s 2p", "Na 1s 2s"],
2398
            ["Li 1s 2s 2p", "Na 1s 2s 2p"],
2399
            ["Li 1s 2s 2p", "Na 1s 2s 3s"],
2400
            ["Li 1s 2s 2p", "Na 1s 2s 2p 3s"],
2401
            ["Li 1s 2s 3s", "Na 1s 2s"],
2402
            ["Li 1s 2s 3s", "Na 1s 2s 2p"],
2403
            ["Li 1s 2s 3s", "Na 1s 2s 3s"],
2404
            ["Li 1s 2s 3s", "Na 1s 2s 2p 3s"],
2405
            ["Li 1s 2s 2p 3s", "Na 1s 2s"],
2406
            ["Li 1s 2s 2p 3s", "Na 1s 2s 2p"],
2407
            ["Li 1s 2s 2p 3s", "Na 1s 2s 3s"],
2408
            ["Li 1s 2s 2p 3s", "Na 1s 2s 2p 3s"],
2409
        ]
2410

2411
        min_basis = ["Si 1s 2s 2p", "Na 1s 2s"]
1✔
2412
        max_basis = ["Si 1s 2s 2p 3s", "Na 1s 2s 2p 3s"]
1✔
2413
        combinations_basis = get_all_possible_basis_combinations(min_basis, max_basis)
1✔
2414
        assert combinations_basis == [
1✔
2415
            ["Si 1s 2s 2p", "Na 1s 2s"],
2416
            ["Si 1s 2s 2p", "Na 1s 2s 2p"],
2417
            ["Si 1s 2s 2p", "Na 1s 2s 3s"],
2418
            ["Si 1s 2s 2p", "Na 1s 2s 2p 3s"],
2419
            ["Si 1s 2s 2p 3s", "Na 1s 2s"],
2420
            ["Si 1s 2s 2p 3s", "Na 1s 2s 2p"],
2421
            ["Si 1s 2s 2p 3s", "Na 1s 2s 3s"],
2422
            ["Si 1s 2s 2p 3s", "Na 1s 2s 2p 3s"],
2423
        ]
2424

2425

2426
class WavefunctionTest(PymatgenTest):
1✔
2427
    def test_parse_file(self):
1✔
2428
        grid, points, real, imaginary, distance = Wavefunction._parse_file(
1✔
2429
            os.path.join(
2430
                test_dir_doscar,
2431
                "cohp",
2432
                "LCAOWaveFunctionAfterLSO1PlotOfSpin1Kpoint1band1.gz",
2433
            )
2434
        )
2435
        self.assertArrayEqual([41, 41, 41], grid)
1✔
2436
        assert points[4][0] == approx(0.0000)
1✔
2437
        assert points[4][1] == approx(0.0000)
1✔
2438
        assert points[4][2] == approx(0.4000)
1✔
2439
        assert real[8] == approx(1.38863e-01)
1✔
2440
        assert imaginary[8] == approx(2.89645e-01)
1✔
2441
        assert len(imaginary) == 41 * 41 * 41
1✔
2442
        assert len(real) == 41 * 41 * 41
1✔
2443
        assert len(points) == 41 * 41 * 41
1✔
2444
        assert distance[0] == approx(0.0000)
1✔
2445

2446
    def test_set_volumetric_data(self):
1✔
2447
        wave1 = Wavefunction(
1✔
2448
            filename=os.path.join(
2449
                test_dir_doscar,
2450
                "cohp",
2451
                "LCAOWaveFunctionAfterLSO1PlotOfSpin1Kpoint1band1" ".gz",
2452
            ),
2453
            structure=Structure.from_file(os.path.join(test_dir_doscar, "cohp", "POSCAR_O.gz")),
2454
        )
2455

2456
        wave1.set_volumetric_data(grid=wave1.grid, structure=wave1.structure)
1✔
2457
        assert hasattr(wave1, "volumetricdata_real")
1✔
2458
        assert hasattr(wave1, "volumetricdata_imaginary")
1✔
2459

2460
    def test_get_volumetricdata_real(self):
1✔
2461
        wave1 = Wavefunction(
1✔
2462
            filename=os.path.join(
2463
                test_dir_doscar,
2464
                "cohp",
2465
                "LCAOWaveFunctionAfterLSO1PlotOfSpin1Kpoint1band1.gz",
2466
            ),
2467
            structure=Structure.from_file(os.path.join(test_dir_doscar, "cohp", "POSCAR_O.gz")),
2468
        )
2469
        volumetricdata_real = wave1.get_volumetricdata_real()
1✔
2470
        assert volumetricdata_real.data["total"][0, 0, 0] == approx(-3.0966)
1✔
2471

2472
    def test_get_volumetricdata_imaginary(self):
1✔
2473
        wave1 = Wavefunction(
1✔
2474
            filename=os.path.join(
2475
                test_dir_doscar,
2476
                "cohp",
2477
                "LCAOWaveFunctionAfterLSO1PlotOfSpin1Kpoint1band1.gz",
2478
            ),
2479
            structure=Structure.from_file(os.path.join(test_dir_doscar, "cohp", "POSCAR_O.gz")),
2480
        )
2481
        volumetricdata_imaginary = wave1.get_volumetricdata_imaginary()
1✔
2482
        assert volumetricdata_imaginary.data["total"][0, 0, 0] == approx(-6.45895e00)
1✔
2483

2484
    def test_get_volumetricdata_density(self):
1✔
2485
        wave1 = Wavefunction(
1✔
2486
            filename=os.path.join(
2487
                test_dir_doscar,
2488
                "cohp",
2489
                "LCAOWaveFunctionAfterLSO1PlotOfSpin1Kpoint1band1.gz",
2490
            ),
2491
            structure=Structure.from_file(os.path.join(test_dir_doscar, "cohp", "POSCAR_O.gz")),
2492
        )
2493
        volumetricdata_density = wave1.get_volumetricdata_density()
1✔
2494
        assert volumetricdata_density.data["total"][0, 0, 0] == approx((-3.0966 * -3.0966) + (-6.45895 * -6.45895))
1✔
2495

2496
    def test_write_file(self):
1✔
2497
        wave1 = Wavefunction(
1✔
2498
            filename=os.path.join(
2499
                test_dir_doscar,
2500
                "cohp",
2501
                "LCAOWaveFunctionAfterLSO1PlotOfSpin1Kpoint1band1.gz",
2502
            ),
2503
            structure=Structure.from_file(os.path.join(test_dir_doscar, "cohp", "POSCAR_O.gz")),
2504
        )
2505
        wave1.write_file(filename=os.path.join("wavecar_test.vasp"), part="real")
1✔
2506
        assert os.path.isfile("wavecar_test.vasp")
1✔
2507

2508
        wave1.write_file(filename=os.path.join("wavecar_test.vasp"), part="imaginary")
1✔
2509
        assert os.path.isfile("wavecar_test.vasp")
1✔
2510
        os.remove("wavecar_test.vasp")
1✔
2511
        wave1.write_file(filename=os.path.join("density.vasp"), part="density")
1✔
2512
        assert os.path.isfile("density.vasp")
1✔
2513
        os.remove("density.vasp")
1✔
2514

2515
    def tearDown(self):
1✔
2516
        warnings.simplefilter("default")
1✔
2517

2518

2519
class SitePotentialsTest(PymatgenTest):
1✔
2520
    def setUp(self) -> None:
1✔
2521
        self.sitepotential = SitePotential(
1✔
2522
            filename=os.path.join(test_dir_doscar, "cohp", "SitePotentials.lobster.perovskite")
2523
        )
2524

2525
    def test_attributes(self):
1✔
2526
        assert self.sitepotential.sitepotentials_Loewdin == [-8.77, -17.08, 9.57, 9.57, 8.45]
1✔
2527
        assert self.sitepotential.sitepotentials_Mulliken == [-11.38, -19.62, 11.18, 11.18, 10.09]
1✔
2528
        assert self.sitepotential.madelungenergies_Loewdin == approx(-28.64)
1✔
2529
        assert self.sitepotential.madelungenergies_Mulliken == approx(-40.02)
1✔
2530
        assert self.sitepotential.atomlist == ["La1", "Ta2", "N3", "N4", "O5"]
1✔
2531
        assert self.sitepotential.types == ["La", "Ta", "N", "N", "O"]
1✔
2532
        assert self.sitepotential.num_atoms == 5
1✔
2533
        assert self.sitepotential.ewald_splitting == approx(3.14)
1✔
2534

2535
    def test_get_structure(self):
1✔
2536
        structure = self.sitepotential.get_structure_with_site_potentials(
1✔
2537
            os.path.join(test_dir_doscar, "cohp", "POSCAR.perovskite")
2538
        )
2539
        assert structure.site_properties["Loewdin Site Potentials (eV)"] == [-8.77, -17.08, 9.57, 9.57, 8.45]
1✔
2540
        assert structure.site_properties["Mulliken Site Potentials (eV)"] == [-11.38, -19.62, 11.18, 11.18, 10.09]
1✔
2541

2542

2543
class MadelungEnergiesTest(PymatgenTest):
1✔
2544
    def setUp(self) -> None:
1✔
2545
        self.madelungenergies = MadelungEnergies(
1✔
2546
            filename=os.path.join(test_dir_doscar, "cohp", "MadelungEnergies.lobster.perovskite")
2547
        )
2548

2549
    def test_attributes(self):
1✔
2550
        assert self.madelungenergies.madelungenergies_Loewdin == approx(-28.64)
1✔
2551
        assert self.madelungenergies.madelungenergies_Mulliken == approx(-40.02)
1✔
2552
        assert self.madelungenergies.ewald_splitting == approx(3.14)
1✔
2553

2554

2555
if __name__ == "__main__":
1✔
2556
    unittest.main()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc