1import os
2import pytest
3import phonopy
4import numpy as np
5from phonopy.structure.atoms import PhonopyAtoms
6
7current_dir = os.path.dirname(os.path.abspath(__file__))
8
9
10@pytest.fixture(scope='session')
11def ph_nacl():
12    yaml_filename = os.path.join(current_dir, "phonopy_disp_NaCl.yaml")
13    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_NaCl")
14    born_filename = os.path.join(current_dir, "BORN_NaCl")
15    return phonopy.load(yaml_filename,
16                        force_sets_filename=force_sets_filename,
17                        born_filename=born_filename,
18                        is_compact_fc=False,
19                        log_level=1, produce_fc=True)
20
21
22@pytest.fixture(scope='session')
23def ph_nacl_nofcsym():
24    yaml_filename = os.path.join(current_dir, "phonopy_disp_NaCl.yaml")
25    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_NaCl")
26    born_filename = os.path.join(current_dir, "BORN_NaCl")
27    return phonopy.load(yaml_filename,
28                        force_sets_filename=force_sets_filename,
29                        born_filename=born_filename,
30                        symmetrize_fc=False,
31                        log_level=1, produce_fc=True)
32
33
34@pytest.fixture(scope='session')
35def ph_nacl_compact_fcsym():
36    yaml_filename = os.path.join(current_dir, "phonopy_disp_NaCl.yaml")
37    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_NaCl")
38    born_filename = os.path.join(current_dir, "BORN_NaCl")
39    return phonopy.load(yaml_filename,
40                        force_sets_filename=force_sets_filename,
41                        born_filename=born_filename,
42                        is_compact_fc=True,
43                        log_level=1, produce_fc=True)
44
45
46@pytest.fixture(scope='session')
47def ph_nacl_nonac():
48    yaml_filename = os.path.join(current_dir, "phonopy_disp_NaCl.yaml")
49    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_NaCl")
50    return phonopy.load(yaml_filename,
51                        force_sets_filename=force_sets_filename,
52                        is_nac=False,
53                        is_compact_fc=False,
54                        log_level=1, produce_fc=True)
55
56
57@pytest.fixture(scope='session')
58def ph_nacl_nonac_compact_fc():
59    yaml_filename = os.path.join(current_dir, "phonopy_disp_NaCl.yaml")
60    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_NaCl")
61    return phonopy.load(yaml_filename,
62                        force_sets_filename=force_sets_filename,
63                        is_nac=False,
64                        is_compact_fc=True,
65                        log_level=1, produce_fc=True)
66
67
68@pytest.fixture(scope='session')
69def ph_nacl_nonac_dense_svecs():
70    yaml_filename = os.path.join(current_dir, "phonopy_disp_NaCl.yaml")
71    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_NaCl")
72    return phonopy.load(yaml_filename,
73                        force_sets_filename=force_sets_filename,
74                        is_nac=False,
75                        is_compact_fc=True,
76                        store_dense_svecs=True,
77                        log_level=1, produce_fc=True)
78
79
80@pytest.fixture(scope='session')
81def ph_sno2():
82    yaml_filename = os.path.join(current_dir, "phonopy_disp_SnO2.yaml")
83    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_SnO2")
84    born_filename = os.path.join(current_dir, "BORN_SnO2")
85    return phonopy.load(yaml_filename,
86                        force_sets_filename=force_sets_filename,
87                        born_filename=born_filename,
88                        is_compact_fc=False,
89                        log_level=1, produce_fc=True)
90
91
92@pytest.fixture(scope='session')
93def ph_tio2():
94    yaml_filename = os.path.join(current_dir, "phonopy_disp_TiO2.yaml")
95    force_sets_filename = os.path.join(current_dir, "FORCE_SETS_TiO2")
96    born_filename = os.path.join(current_dir, "BORN_TiO2")
97    return phonopy.load(yaml_filename,
98                        force_sets_filename=force_sets_filename,
99                        born_filename=born_filename,
100                        is_compact_fc=False,
101                        log_level=1, produce_fc=True)
102
103
104@pytest.fixture(scope='session')
105def ph_zr3n4():
106    yaml_filename = os.path.join(current_dir, "phonopy_params_Zr3N4.yaml")
107    return phonopy.load(yaml_filename,
108                        is_compact_fc=False,
109                        log_level=1, produce_fc=True)
110
111
112@pytest.fixture(scope='session')
113def ph_tipn3():
114    yaml_filename = os.path.join(current_dir, "phonopy_params_TiPN3.yaml.xz")
115    return phonopy.load(yaml_filename,
116                        is_compact_fc=False,
117                        log_level=1, produce_fc=True)
118
119
120@pytest.fixture(scope='session')
121def convcell_sio2():
122    symbols = ['Si'] * 2 + ['O'] * 4
123    lattice = [[4.65, 0, 0],
124               [0, 4.75, 0],
125               [0, 0, 3.25]]
126    points = [[0.0, 0.0, 0.0],
127              [0.5, 0.5, 0.5],
128              [0.3, 0.3, 0.0],
129              [0.7, 0.7, 0.0],
130              [0.2, 0.8, 0.5],
131              [0.8, 0.2, 0.5]]
132    return PhonopyAtoms(cell=lattice,
133                        scaled_positions=points,
134                        symbols=symbols)
135
136
137@pytest.fixture(scope='session')
138def primcell_si():
139    symbols = ['Si'] * 2
140    lattice = [[0, 2.73, 2.73],
141               [2.73, 0, 2.73],
142               [2.73, 2.73, 0]]
143    points = [[0.75, 0.75, 0.75],
144              [0.5, 0.5, 0.5]]
145    return PhonopyAtoms(cell=lattice,
146                        scaled_positions=points,
147                        symbols=symbols)
148
149
150@pytest.fixture(scope='session')
151def convcell_nacl():
152    symbols = ['Na'] * 4 + ['Cl'] * 4
153    a = 5.6903014761756712
154    lattice = [[a, 0, 0], [0, a, 0], [0, 0, a]]
155    points = [[0.0, 0.0, 0.0],
156              [0.0, 0.5, 0.5],
157              [0.5, 0.0, 0.5],
158              [0.5, 0.5, 0.0],
159              [0.5, 0.5, 0.5],
160              [0.5, 0.0, 0.0],
161              [0.0, 0.5, 0.0],
162              [0.0, 0.0, 0.5]]
163    return PhonopyAtoms(cell=lattice,
164                        scaled_positions=points,
165                        symbols=symbols)
166
167
168@pytest.fixture(scope='session')
169def primcell_nacl():
170    symbols = ['Na', 'Cl']
171    x = 5.6903014761756712 / 2
172    lattice = [[0, x, x], [x, 0, x], [x, x, 0]]
173    points = [[0, 0, 0], [0.5, 0.5, 0.5]]
174    return PhonopyAtoms(cell=lattice,
175                        scaled_positions=points,
176                        symbols=symbols)
177
178
179@pytest.fixture(scope='session')
180def convcell_cr():
181    symbols = ['Cr'] * 2
182    a = 2.812696943681890
183    lattice = [[a, 0, 0], [0, a, 0], [0, 0, a]]
184    points = [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]
185    return PhonopyAtoms(cell=lattice,
186                        scaled_positions=points,
187                        symbols=symbols)
188
189
190@pytest.fixture(scope='session')
191def helper_methods():
192    class HelperMethods(object):
193        @classmethod
194        def compare_cells_with_order(cls, cell, cell_ref):
195            np.testing.assert_allclose(cell.cell, cell_ref.cell, atol=1e-5)
196            cls.compare_positions_with_order(
197                cell.scaled_positions, cell_ref.scaled_positions, cell.cell)
198            np.testing.assert_array_equal(cell.numbers, cell_ref.numbers)
199            np.testing.assert_allclose(cell.masses, cell_ref.masses, atol=1e-5)
200
201        @classmethod
202        def compare_positions_with_order(cls, pos, pos_ref, lattice):
203            """lattice : basis vectors in row vectors"""
204            diff = pos - pos_ref
205            diff -= np.rint(diff)
206            dist = (np.dot(diff, lattice) ** 2).sum(axis=1)
207            assert (dist < 1e-5).all()
208
209        @classmethod
210        def compare_cells(cls, cell, cell_ref):
211            np.testing.assert_allclose(cell.cell, cell_ref.cell, atol=1e-5)
212
213            indices = cls.compare_positions_in_arbitrary_order(
214                cell.scaled_positions,
215                cell_ref.scaled_positions,
216                cell.cell)
217            np.testing.assert_array_equal(cell.numbers,
218                                          cell_ref.numbers[indices])
219            np.testing.assert_allclose(cell.masses, cell_ref.masses[indices],
220                                       atol=1e-5)
221
222        @classmethod
223        def compare_positions_in_arbitrary_order(
224                cls, pos_in, pos_ref, lattice):
225            indices = []
226            for pos in pos_in:
227                diff = pos_ref - pos
228                diff -= np.rint(diff)
229                dist = (np.dot(diff, lattice) ** 2).sum(axis=1)
230                matches = np.where(dist < 1e-5)[0]
231                assert len(matches) == 1
232                indices.append(matches[0])
233            return indices
234
235    return HelperMethods
236