• 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.42
/pymatgen/io/feff/tests/test_sets.py
1
# Copyright (c) Pymatgen Development Team.
2
# Distributed under the terms of the MIT License.
3

4

5
from __future__ import annotations
1✔
6

7
import os
1✔
8
import shutil
1✔
9
import unittest
1✔
10

11
import numpy as np
1✔
12
import pytest
1✔
13

14
from pymatgen.core.structure import Molecule, Structure
1✔
15
from pymatgen.io.cif import CifParser
1✔
16
from pymatgen.io.feff.inputs import Atoms, Header, Potential, Tags
1✔
17
from pymatgen.io.feff.sets import FEFFDictSet, MPELNESSet, MPEXAFSSet, MPXANESSet
1✔
18
from pymatgen.util.testing import PymatgenTest
1✔
19

20

21
class FeffInputSetTest(unittest.TestCase):
1✔
22
    @classmethod
1✔
23
    def setUpClass(cls):
1✔
24
        cls.header_string = """* This FEFF.inp file generated by pymatgen
1✔
25
TITLE comment: From cif file
26
TITLE Source:  CoO19128.cif
27
TITLE Structure Summary:  Co2 O2
28
TITLE Reduced formula:  CoO
29
TITLE space group: (P6_3mc), space number:  (186)
30
TITLE abc:  3.297078   3.297078   5.254213
31
TITLE angles: 90.000000  90.000000 120.000000
32
TITLE sites: 4
33
* 1 Co     0.333333     0.666667     0.503676
34
* 2 Co     0.666667     0.333333     0.003676
35
* 3 O     0.333333     0.666667     0.121324
36
* 4 O     0.666667     0.333333     0.621325"""
37
        cif_file = os.path.join(PymatgenTest.TEST_FILES_DIR, "CoO19128.cif")
1✔
38
        cls.structure = CifParser(cif_file).get_structures()[0]
1✔
39
        cls.absorbing_atom = "O"
1✔
40
        cls.mp_xanes = MPXANESSet(cls.absorbing_atom, cls.structure)
1✔
41

42
    def test_get_header(self):
1✔
43
        comment = "From cif file"
1✔
44
        header = str(self.mp_xanes.header(source="CoO19128.cif", comment=comment))
1✔
45
        print(header)
1✔
46

47
        ref = self.header_string.splitlines()
1✔
48
        last4 = [" ".join(l.split()[2:]) for l in ref[-4:]]
1✔
49
        for i, l in enumerate(header.splitlines()):
1✔
50
            if i < 9:
1✔
51
                assert l == ref[i]
1✔
52
            else:
53
                s = " ".join(l.split()[2:])
1✔
54
                assert s in last4
1✔
55

56
    def test_getfefftags(self):
1✔
57
        tags = self.mp_xanes.tags.as_dict()
1✔
58
        assert tags["COREHOLE"] == "FSR", "Failed to generate PARAMETERS string"
1✔
59

60
    def test_get_feffPot(self):
1✔
61
        POT = str(self.mp_xanes.potential)
1✔
62
        d, dr = Potential.pot_dict_from_string(POT)
1✔
63
        assert d["Co"] == 1, "Wrong symbols read in for Potential"
1✔
64

65
    def test_get_feff_atoms(self):
1✔
66
        atoms = str(self.mp_xanes.atoms)
1✔
67
        assert atoms.splitlines()[3].split()[4] == self.absorbing_atom, "failed to create ATOMS string"
1✔
68

69
    def test_to_and_from_dict(self):
1✔
70
        f1_dict = self.mp_xanes.as_dict()
1✔
71
        f2 = MPXANESSet.from_dict(f1_dict)
1✔
72
        assert f1_dict == f2.as_dict()
1✔
73

74
    def test_user_tag_settings(self):
1✔
75
        tags_dict_ans = self.mp_xanes.tags.as_dict()
1✔
76
        tags_dict_ans["COREHOLE"] = "RPA"
1✔
77
        tags_dict_ans["EDGE"] = "L1"
1✔
78
        user_tag_settings = {"COREHOLE": "RPA", "EDGE": "L1"}
1✔
79
        mp_xanes_2 = MPXANESSet(self.absorbing_atom, self.structure, user_tag_settings=user_tag_settings)
1✔
80
        assert mp_xanes_2.tags.as_dict() == tags_dict_ans
1✔
81

82
    def test_eels_to_from_dict(self):
1✔
83
        elnes = MPELNESSet(
1✔
84
            self.absorbing_atom,
85
            self.structure,
86
            radius=5.0,
87
            beam_energy=100,
88
            beam_direction=[1, 0, 0],
89
            collection_angle=7,
90
            convergence_angle=6,
91
        )
92
        elnes_dict = elnes.as_dict()
1✔
93
        elnes_2 = MPELNESSet.from_dict(elnes_dict)
1✔
94
        assert elnes_dict == elnes_2.as_dict()
1✔
95

96
    def test_eels_tags_set(self):
1✔
97
        radius = 5.0
1✔
98
        user_eels_settings = {
1✔
99
            "ENERGY": "4 0.04 0.1",
100
            "BEAM_ENERGY": "200 1 0 1",
101
            "ANGLES": "2 3",
102
        }
103
        elnes = MPELNESSet(
1✔
104
            self.absorbing_atom,
105
            self.structure,
106
            radius=radius,
107
            user_eels_settings=user_eels_settings,
108
        )
109
        elnes_2 = MPELNESSet(
1✔
110
            self.absorbing_atom,
111
            self.structure,
112
            radius=radius,
113
            beam_energy=100,
114
            beam_direction=[1, 0, 0],
115
            collection_angle=7,
116
            convergence_angle=6,
117
        )
118
        assert elnes.tags["ELNES"]["ENERGY"] == user_eels_settings["ENERGY"]
1✔
119
        assert elnes.tags["ELNES"]["BEAM_ENERGY"] == user_eels_settings["BEAM_ENERGY"]
1✔
120
        assert elnes.tags["ELNES"]["ANGLES"] == user_eels_settings["ANGLES"]
1✔
121
        assert elnes_2.tags["ELNES"]["BEAM_ENERGY"] == [100, 0, 1, 1]
1✔
122
        assert elnes_2.tags["ELNES"]["BEAM_DIRECTION"] == [1, 0, 0]
1✔
123
        assert elnes_2.tags["ELNES"]["ANGLES"] == [7, 6]
1✔
124

125
    def test_charged_structure(self):
1✔
126
        # one Zn+2, 9 triflate, plus water
127
        # Molecule, net charge of -7
128
        xyz = os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_radial_shell.xyz")
1✔
129
        m = Molecule.from_file(xyz)
1✔
130
        m.set_charge_and_spin(-7)
1✔
131
        # Zn should not appear in the pot_dict
132
        with pytest.warns(UserWarning, match="ION tags"):
1✔
133
            MPXANESSet("Zn", m)
1✔
134
        s = self.structure.copy()
1✔
135
        s.set_charge(1)
1✔
136
        with pytest.raises(ValueError, match="not supported"):
1✔
137
            MPXANESSet("Co", s)
1✔
138

139
    def test_reciprocal_tags_and_input(self):
1✔
140
        user_tag_settings = {"RECIPROCAL": "", "KMESH": "1000"}
1✔
141
        elnes = MPELNESSet(self.absorbing_atom, self.structure, user_tag_settings=user_tag_settings)
1✔
142
        assert "RECIPROCAL" in elnes.tags
1✔
143
        assert elnes.tags["TARGET"] == 3
1✔
144
        assert elnes.tags["KMESH"] == "1000"
1✔
145
        assert elnes.tags["CIF"] == "Co2O2.cif"
1✔
146
        assert elnes.tags["COREHOLE"] == "RPA"
1✔
147
        all_input = elnes.all_input()
1✔
148
        assert "ATOMS" not in all_input
1✔
149
        assert "POTENTIALS" not in all_input
1✔
150
        elnes.write_input()
1✔
151
        structure = Structure.from_file("Co2O2.cif")
1✔
152
        assert self.structure.matches(structure)
1✔
153
        os.remove("HEADER")
1✔
154
        os.remove("PARAMETERS")
1✔
155
        os.remove("feff.inp")
1✔
156
        os.remove("Co2O2.cif")
1✔
157

158
    def test_small_system_EXAFS(self):
1✔
159
        exafs_settings = MPEXAFSSet(self.absorbing_atom, self.structure)
1✔
160
        assert not exafs_settings.small_system
1✔
161
        assert "RECIPROCAL" not in exafs_settings.tags
1✔
162

163
        user_tag_settings = {"RECIPROCAL": ""}
1✔
164
        exafs_settings_2 = MPEXAFSSet(
1✔
165
            self.absorbing_atom,
166
            self.structure,
167
            nkpts=1000,
168
            user_tag_settings=user_tag_settings,
169
        )
170
        assert not exafs_settings_2.small_system
1✔
171
        assert "RECIPROCAL" not in exafs_settings_2.tags
1✔
172

173
    def test_number_of_kpoints(self):
1✔
174
        user_tag_settings = {"RECIPROCAL": ""}
1✔
175
        elnes = MPELNESSet(
1✔
176
            self.absorbing_atom,
177
            self.structure,
178
            nkpts=1000,
179
            user_tag_settings=user_tag_settings,
180
        )
181
        assert elnes.tags["KMESH"] == [12, 12, 7]
1✔
182

183
    def test_large_systems(self):
1✔
184
        struct = Structure.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "La4Fe4O12.cif"))
1✔
185
        user_tag_settings = {"RECIPROCAL": "", "KMESH": "1000"}
1✔
186
        elnes = MPELNESSet("Fe", struct, user_tag_settings=user_tag_settings)
1✔
187
        assert "RECIPROCAL" not in elnes.tags
1✔
188
        assert "KMESH" not in elnes.tags
1✔
189
        assert "CIF" not in elnes.tags
1✔
190
        assert "TARGET" not in elnes.tags
1✔
191

192
    def test_postfeffset(self):
1✔
193
        self.mp_xanes.write_input(os.path.join(".", "xanes_3"))
1✔
194
        feff_dict_input = FEFFDictSet.from_directory(os.path.join(".", "xanes_3"))
1✔
195
        assert feff_dict_input.tags == Tags.from_file(os.path.join(".", "xanes_3/feff.inp"))
1✔
196
        assert str(feff_dict_input.header()) == str(Header.from_file(os.path.join(".", "xanes_3/HEADER")))
1✔
197
        feff_dict_input.write_input("xanes_3_regen")
1✔
198
        origin_tags = Tags.from_file(os.path.join(".", "xanes_3/PARAMETERS"))
1✔
199
        output_tags = Tags.from_file(os.path.join(".", "xanes_3_regen/PARAMETERS"))
1✔
200
        origin_mole = Atoms.cluster_from_file(os.path.join(".", "xanes_3/feff.inp"))
1✔
201
        output_mole = Atoms.cluster_from_file(os.path.join(".", "xanes_3_regen/feff.inp"))
1✔
202
        original_mole_dist = np.array(origin_mole.distance_matrix[0, :]).astype(np.float64)
1✔
203
        output_mole_dist = np.array(output_mole.distance_matrix[0, :]).astype(np.float64)
1✔
204
        original_mole_shell = [x.species_string for x in origin_mole]
1✔
205
        output_mole_shell = [x.species_string for x in output_mole]
1✔
206

207
        assert np.allclose(original_mole_dist, output_mole_dist)
1✔
208
        assert origin_tags == output_tags
1✔
209
        assert original_mole_shell == output_mole_shell
1✔
210

211
        shutil.rmtree(os.path.join(".", "xanes_3"))
1✔
212
        shutil.rmtree(os.path.join(".", "xanes_3_regen"))
1✔
213

214
        reci_mp_xanes = MPXANESSet(self.absorbing_atom, self.structure, user_tag_settings={"RECIPROCAL": ""})
1✔
215
        reci_mp_xanes.write_input("xanes_reci")
1✔
216
        feff_reci_input = FEFFDictSet.from_directory(os.path.join(".", "xanes_reci"))
1✔
217
        assert "RECIPROCAL" in feff_reci_input.tags
1✔
218

219
        feff_reci_input.write_input("Dup_reci")
1✔
220
        assert os.path.exists(os.path.join(".", "Dup_reci", "HEADER"))
1✔
221
        assert os.path.exists(os.path.join(".", "Dup_reci", "feff.inp"))
1✔
222
        assert os.path.exists(os.path.join(".", "Dup_reci", "PARAMETERS"))
1✔
223
        assert not os.path.exists(os.path.join(".", "Dup_reci", "ATOMS"))
1✔
224
        assert not os.path.exists(os.path.join(".", "Dup_reci", "POTENTIALS"))
1✔
225

226
        tags_original = Tags.from_file(os.path.join(".", "xanes_reci/feff.inp"))
1✔
227
        tags_output = Tags.from_file(os.path.join(".", "Dup_reci/feff.inp"))
1✔
228
        assert tags_original == tags_output
1✔
229

230
        stru_orig = Structure.from_file(os.path.join(".", "xanes_reci/Co2O2.cif"))
1✔
231
        stru_reci = Structure.from_file(os.path.join(".", "Dup_reci/Co2O2.cif"))
1✔
232
        assert stru_orig == stru_reci
1✔
233

234
        shutil.rmtree(os.path.join(".", "Dup_reci"))
1✔
235
        shutil.rmtree(os.path.join(".", "xanes_reci"))
1✔
236

237
    def test_post_distdiff(self):
1✔
238
        feff_dict_input = FEFFDictSet.from_directory(os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_dist_test"))
1✔
239
        assert feff_dict_input.tags == Tags.from_file(
1✔
240
            os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_dist_test/feff.inp")
241
        )
242
        assert str(feff_dict_input.header()) == str(
1✔
243
            Header.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_dist_test/HEADER"))
244
        )
245
        feff_dict_input.write_input("feff_dist_regen")
1✔
246
        origin_tags = Tags.from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_dist_test/PARAMETERS"))
1✔
247
        output_tags = Tags.from_file(os.path.join(".", "feff_dist_regen/PARAMETERS"))
1✔
248
        origin_mole = Atoms.cluster_from_file(os.path.join(PymatgenTest.TEST_FILES_DIR, "feff_dist_test/feff.inp"))
1✔
249
        output_mole = Atoms.cluster_from_file(os.path.join(".", "feff_dist_regen/feff.inp"))
1✔
250
        original_mole_dist = np.array(origin_mole.distance_matrix[0, :]).astype(np.float64)
1✔
251
        output_mole_dist = np.array(output_mole.distance_matrix[0, :]).astype(np.float64)
1✔
252
        original_mole_shell = [x.species_string for x in origin_mole]
1✔
253
        output_mole_shell = [x.species_string for x in output_mole]
1✔
254

255
        assert np.allclose(original_mole_dist, output_mole_dist)
1✔
256
        assert origin_tags == output_tags
1✔
257
        assert original_mole_shell == output_mole_shell
1✔
258

259
        shutil.rmtree(os.path.join(".", "feff_dist_regen"))
1✔
260

261

262
if __name__ == "__main__":
1✔
263
    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