guohanghui commited on
Commit
e1d0ffd
·
verified ·
1 Parent(s): 772fea7

Upload 845 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +6 -0
  2. Dockerfile +18 -0
  3. README.md +27 -5
  4. app.py +45 -0
  5. phonopy/mcp_output/README_MCP.md +51 -0
  6. phonopy/mcp_output/analysis.json +1051 -0
  7. phonopy/mcp_output/diff_report.md +63 -0
  8. phonopy/mcp_output/mcp_plugin/__init__.py +0 -0
  9. phonopy/mcp_output/mcp_plugin/adapter.py +132 -0
  10. phonopy/mcp_output/mcp_plugin/main.py +13 -0
  11. phonopy/mcp_output/mcp_plugin/mcp_service.py +97 -0
  12. phonopy/mcp_output/requirements.txt +11 -0
  13. phonopy/mcp_output/start_mcp.py +30 -0
  14. phonopy/mcp_output/workflow_summary.json +194 -0
  15. phonopy/source/.pre-commit-config.yaml +26 -0
  16. phonopy/source/CMakeLists.txt +119 -0
  17. phonopy/source/LICENSE +26 -0
  18. phonopy/source/MANIFEST.in +6 -0
  19. phonopy/source/README.md +74 -0
  20. phonopy/source/__init__.py +4 -0
  21. phonopy/source/build-wheels.sh +33 -0
  22. phonopy/source/c/_phonopy.cpp +599 -0
  23. phonopy/source/c/derivative_dynmat.c +341 -0
  24. phonopy/source/c/derivative_dynmat.h +50 -0
  25. phonopy/source/c/dynmat.c +822 -0
  26. phonopy/source/c/dynmat.h +81 -0
  27. phonopy/source/c/phonopy.c +899 -0
  28. phonopy/source/c/phonopy.h +160 -0
  29. phonopy/source/c/rgrid.c +115 -0
  30. phonopy/source/c/rgrid.h +82 -0
  31. phonopy/source/c/tetrahedron_method.c +1455 -0
  32. phonopy/source/c/tetrahedron_method.h +50 -0
  33. phonopy/source/cmake-format.py +4 -0
  34. phonopy/source/dev-requirements.txt +1 -0
  35. phonopy/source/doc/Al-QHA.png +3 -0
  36. phonopy/source/doc/Cu-QHA.png +0 -0
  37. phonopy/source/doc/Fleur.rst +76 -0
  38. phonopy/source/doc/Makefile +20 -0
  39. phonopy/source/doc/NaCl-PDOS-nac.png +0 -0
  40. phonopy/source/doc/NaCl-PDOS.png +0 -0
  41. phonopy/source/doc/NaCl-VASPdfpt.png +0 -0
  42. phonopy/source/doc/NaCl-band-NAC.png +0 -0
  43. phonopy/source/doc/NaCl-band-PDOS-NAC.png +0 -0
  44. phonopy/source/doc/NaCl-band.png +0 -0
  45. phonopy/source/doc/NaCl-crystal-band-NAC.png +0 -0
  46. phonopy/source/doc/NaCl-disp-dist.png +0 -0
  47. phonopy/source/doc/NaCl-pwscf-band-NAC.png +0 -0
  48. phonopy/source/doc/NaCl-pwscf-band.png +0 -0
  49. phonopy/source/doc/NaCl-q2r-band-NAC.png +0 -0
  50. phonopy/source/doc/QHA.png +3 -0
.gitattributes CHANGED
@@ -33,3 +33,9 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ phonopy/source/doc/Al-QHA.png filter=lfs diff=lfs merge=lfs -text
37
+ phonopy/source/doc/band.png filter=lfs diff=lfs merge=lfs -text
38
+ phonopy/source/doc/pdos.png filter=lfs diff=lfs merge=lfs -text
39
+ phonopy/source/doc/QHA.png filter=lfs diff=lfs merge=lfs -text
40
+ phonopy/source/doc/thermalprop.png filter=lfs diff=lfs merge=lfs -text
41
+ phonopy/source/doc/Ubuntu-install.png filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10
2
+
3
+ RUN useradd -m -u 1000 user && python -m pip install --upgrade pip
4
+ USER user
5
+ ENV PATH="/home/user/.local/bin:$PATH"
6
+
7
+ WORKDIR /app
8
+
9
+ COPY --chown=user ./requirements.txt requirements.txt
10
+ RUN pip install --no-cache-dir --upgrade -r requirements.txt
11
+
12
+ COPY --chown=user . /app
13
+ ENV MCP_TRANSPORT=http
14
+ ENV MCP_PORT=7860
15
+
16
+ EXPOSE 7860
17
+
18
+ CMD ["python", "phonopy/mcp_output/start_mcp.py"]
README.md CHANGED
@@ -1,10 +1,32 @@
1
  ---
2
- title: Phonopy
3
- emoji: 🐠
4
- colorFrom: green
5
- colorTo: gray
6
  sdk: docker
 
 
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: Phonopy MCP
3
+ emoji: 🤖
4
+ colorFrom: blue
5
+ colorTo: purple
6
  sdk: docker
7
+ sdk_version: "4.26.0"
8
+ app_file: app.py
9
  pinned: false
10
  ---
11
 
12
+ # Phonopy MCP Service
13
+
14
+ Auto-generated MCP service for phonopy.
15
+
16
+ ## Usage
17
+
18
+ ```
19
+ https://None-phonopy-mcp.hf.space/mcp
20
+ ```
21
+
22
+ ## Connect with Cursor
23
+
24
+ ```json
25
+ {
26
+ "mcpServers": {
27
+ "phonopy": {
28
+ "url": "https://None-phonopy-mcp.hf.space/mcp"
29
+ }
30
+ }
31
+ }
32
+ ```
app.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ import os
3
+ import sys
4
+
5
+ mcp_plugin_path = os.path.join(os.path.dirname(__file__), "phonopy", "mcp_output", "mcp_plugin")
6
+ sys.path.insert(0, mcp_plugin_path)
7
+
8
+ app = FastAPI(
9
+ title="Phonopy MCP Service",
10
+ description="Auto-generated MCP service for phonopy",
11
+ version="1.0.0"
12
+ )
13
+
14
+ @app.get("/")
15
+ def root():
16
+ return {
17
+ "service": "Phonopy MCP Service",
18
+ "version": "1.0.0",
19
+ "status": "running",
20
+ "transport": os.environ.get("MCP_TRANSPORT", "http")
21
+ }
22
+
23
+ @app.get("/health")
24
+ def health_check():
25
+ return {"status": "healthy", "service": "phonopy MCP"}
26
+
27
+ @app.get("/tools")
28
+ def list_tools():
29
+ try:
30
+ from mcp_service import create_app
31
+ mcp_app = create_app()
32
+ tools = []
33
+ for tool_name, tool_func in mcp_app.tools.items():
34
+ tools.append({
35
+ "name": tool_name,
36
+ "description": tool_func.__doc__ or "No description available"
37
+ })
38
+ return {"tools": tools}
39
+ except Exception as e:
40
+ return {"error": f"Failed to load tools: {str(e)}"}
41
+
42
+ if __name__ == "__main__":
43
+ import uvicorn
44
+ port = int(os.environ.get("PORT", 7860))
45
+ uvicorn.run(app, host="0.0.0.0", port=port)
phonopy/mcp_output/README_MCP.md ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Phonopy MCP (Model Context Protocol) Service
2
+
3
+ ## Project Introduction
4
+
5
+ Phonopy is a Python package designed for phonon calculations in the harmonic approximation. It is used to compute phonon frequencies, band structures, density of states, and thermodynamic properties by solving the lattice dynamics eigenvalue problem from interatomic force constants. Phonopy supports a wide range of calculator interfaces and file formats, making it a versatile tool for researchers and developers working with crystal structures and atomic forces.
6
+
7
+ ## Installation Method
8
+
9
+ To install Phonopy, ensure you have the following dependencies: `numpy`, `scipy`, and `matplotlib`. Optionally, you can also install `ase` and `spglib` for additional functionalities.
10
+
11
+ You can install Phonopy using pip:
12
+
13
+ ```
14
+ pip install phonopy
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ To quickly get started with Phonopy, you can use the following example to perform basic phonon calculations:
20
+
21
+ 1. Import the Phonopy class and create an instance:
22
+ - `from phonopy import Phonopy`
23
+ - `phonopy_instance = Phonopy(unitcell, supercell_matrix)`
24
+
25
+ 2. Generate displacements:
26
+ - `phonopy_instance.generate_displacements()`
27
+
28
+ 3. Calculate force constants:
29
+ - `phonopy_instance.produce_force_constants()`
30
+
31
+ 4. Run phonon band structure calculations:
32
+ - `phonopy_instance.run_band_structure()`
33
+
34
+ 5. Compute thermal properties:
35
+ - `phonopy_instance.run_thermal_properties()`
36
+
37
+ ## Available Tools and Endpoints List
38
+
39
+ - **Phonopy CLI**: Main command-line interface for phonon calculations.
40
+ - **Phonopy-bandplot**: Tool for plotting phonon band structures.
41
+ - **Phonopy-gruneisen**: Tool for Gruneisen parameter calculations.
42
+
43
+ ## Common Issues and Notes
44
+
45
+ - Ensure all dependencies are correctly installed to avoid import errors.
46
+ - The performance of calculations can vary based on the complexity of the crystal structures and the computational resources available.
47
+ - For large-scale calculations, consider using optimized computational resources to improve performance.
48
+
49
+ ## Reference Links or Documentation
50
+
51
+ For more detailed information, please refer to the [Phonopy GitHub Repository](https://github.com/phonopy/phonopy) and the official documentation available within the repository. This includes comprehensive guides on installation, usage, and advanced topics related to phonon calculations.
phonopy/mcp_output/analysis.json ADDED
@@ -0,0 +1,1051 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "summary": {
3
+ "repository_url": "https://github.com/phonopy/phonopy",
4
+ "summary": "Imported via zip fallback, file count: 310",
5
+ "file_tree": {
6
+ ".github/workflows/phonopy-pytest-conda.yml": {
7
+ "size": 1253
8
+ },
9
+ ".github/workflows/phonopy-pytest-pip-windows-macos.yml": {
10
+ "size": 962
11
+ },
12
+ ".github/workflows/publish-gh-pages.yml": {
13
+ "size": 1145
14
+ },
15
+ ".github/workflows/publish-to-test-pypi.yml": {
16
+ "size": 1135
17
+ },
18
+ ".github/workflows/wheels.yml": {
19
+ "size": 2913
20
+ },
21
+ ".pre-commit-config.yaml": {
22
+ "size": 641
23
+ },
24
+ "CMakeLists.txt": {
25
+ "size": 4139
26
+ },
27
+ "README.md": {
28
+ "size": 2421
29
+ },
30
+ "cmake-format.py": {
31
+ "size": 81
32
+ },
33
+ "dev-requirements.txt": {
34
+ "size": 6
35
+ },
36
+ "doc/README.md": {
37
+ "size": 798
38
+ },
39
+ "doc/animation.md": {
40
+ "size": 1359
41
+ },
42
+ "doc/auxiliary-tools.md": {
43
+ "size": 2420
44
+ },
45
+ "doc/changelog.md": {
46
+ "size": 50169
47
+ },
48
+ "doc/citation.md": {
49
+ "size": 3797
50
+ },
51
+ "doc/command-options.md": {
52
+ "size": 15498
53
+ },
54
+ "doc/conf.py": {
55
+ "size": 9301
56
+ },
57
+ "doc/documentation.md": {
58
+ "size": 292
59
+ },
60
+ "doc/dynamic-structure-factor.md": {
61
+ "size": 8729
62
+ },
63
+ "doc/examples.md": {
64
+ "size": 16429
65
+ },
66
+ "doc/external-tools.md": {
67
+ "size": 2378
68
+ },
69
+ "doc/formulation.md": {
70
+ "size": 21886
71
+ },
72
+ "doc/gruneisen.md": {
73
+ "size": 4671
74
+ },
75
+ "doc/index.md": {
76
+ "size": 3354
77
+ },
78
+ "doc/input-files.md": {
79
+ "size": 18032
80
+ },
81
+ "doc/install.md": {
82
+ "size": 6604
83
+ },
84
+ "doc/interfaces.md": {
85
+ "size": 4756
86
+ },
87
+ "doc/lammps.md": {
88
+ "size": 7422
89
+ },
90
+ "doc/mlp-sscha.md": {
91
+ "size": 22878
92
+ },
93
+ "doc/output-files.md": {
94
+ "size": 8411
95
+ },
96
+ "doc/phonopy-load.md": {
97
+ "size": 2601
98
+ },
99
+ "doc/phonopy-module.md": {
100
+ "size": 25291
101
+ },
102
+ "doc/phonopy-yaml.md": {
103
+ "size": 1363
104
+ },
105
+ "doc/qe.md": {
106
+ "size": 11122
107
+ },
108
+ "doc/qha.md": {
109
+ "size": 10044
110
+ },
111
+ "doc/qlm.md": {
112
+ "size": 2047
113
+ },
114
+ "doc/random-displacements.md": {
115
+ "size": 8990
116
+ },
117
+ "doc/reference.md": {
118
+ "size": 7384
119
+ },
120
+ "doc/setting-tags.md": {
121
+ "size": 50129
122
+ },
123
+ "doc/symmetry.md": {
124
+ "size": 2389
125
+ },
126
+ "doc/vasp-dfpt.md": {
127
+ "size": 4022
128
+ },
129
+ "doc/vasp.md": {
130
+ "size": 5280
131
+ },
132
+ "doc/workflow.md": {
133
+ "size": 1017
134
+ },
135
+ "example/Al-ABACUS/abacus-lcao/band.yaml": {
136
+ "size": 63428
137
+ },
138
+ "example/Al-ABACUS/abacus-lcao/mesh.yaml": {
139
+ "size": 14819
140
+ },
141
+ "example/Al-ABACUS/abacus-lcao/phonopy.yaml": {
142
+ "size": 8206
143
+ },
144
+ "example/Al-ABACUS/abacus-lcao/phonopy_disp.yaml": {
145
+ "size": 8425
146
+ },
147
+ "example/Al-ABACUS/abacus-pw/band.yaml": {
148
+ "size": 63428
149
+ },
150
+ "example/Al-ABACUS/abacus-pw/mesh.yaml": {
151
+ "size": 14819
152
+ },
153
+ "example/Al-ABACUS/abacus-pw/phonopy.yaml": {
154
+ "size": 8206
155
+ },
156
+ "example/Al-ABACUS/abacus-pw/phonopy_disp.yaml": {
157
+ "size": 8425
158
+ },
159
+ "example/Al-Fleur/phonopy_disp.yaml": {
160
+ "size": 3028
161
+ },
162
+ "example/Al-QHA/Al-QHA.py": {
163
+ "size": 1366
164
+ },
165
+ "example/Al2O3/Al2O3.py": {
166
+ "size": 1374
167
+ },
168
+ "example/Al2O3/README.md": {
169
+ "size": 634
170
+ },
171
+ "example/Al2O3/phonopy_disp.yaml": {
172
+ "size": 26770
173
+ },
174
+ "example/CaTiO3/phonopy_disp.yaml": {
175
+ "size": 8808
176
+ },
177
+ "example/Cr/README.md": {
178
+ "size": 1049
179
+ },
180
+ "example/Cr/phonopy_disp.yaml": {
181
+ "size": 5130
182
+ },
183
+ "example/KCl-SSCHA/README.md": {
184
+ "size": 3227
185
+ },
186
+ "example/KCl-SSCHA/embed_sscha_fc.py": {
187
+ "size": 1069
188
+ },
189
+ "example/LiF-nosym/README.md": {
190
+ "size": 561
191
+ },
192
+ "example/MgB2/MgB2.py": {
193
+ "size": 593
194
+ },
195
+ "example/MgB2/README.md": {
196
+ "size": 393
197
+ },
198
+ "example/MgB2/phonopy_disp.yaml": {
199
+ "size": 9982
200
+ },
201
+ "example/MgO/README.md": {
202
+ "size": 311
203
+ },
204
+ "example/MgO/phonopy_disp.yaml": {
205
+ "size": 12692
206
+ },
207
+ "example/NaCl-CP2K/README.md": {
208
+ "size": 989
209
+ },
210
+ "example/NaCl-CP2K/phonopy_disp.yaml": {
211
+ "size": 12733
212
+ },
213
+ "example/NaCl-QE-q2r/make_born_q2r.py": {
214
+ "size": 723
215
+ },
216
+ "example/NaCl-QE-q2r/make_fc_q2r.py": {
217
+ "size": 308
218
+ },
219
+ "example/NaCl-QE/README.md": {
220
+ "size": 1335
221
+ },
222
+ "example/NaCl-QE/phonopy_disp.yaml": {
223
+ "size": 12219
224
+ },
225
+ "example/NaCl-VASPdfpt/README.md": {
226
+ "size": 580
227
+ },
228
+ "example/NaCl-abinit/disp.yaml": {
229
+ "size": 6433
230
+ },
231
+ "example/NaCl-rd/README.md": {
232
+ "size": 733
233
+ },
234
+ "example/NaCl-rd/phonopy_disp.yaml": {
235
+ "size": 73476
236
+ },
237
+ "example/NaCl-wien2k-P1/README.md": {
238
+ "size": 602
239
+ },
240
+ "example/NaCl-wien2k-P1/phonopy_disp.yaml": {
241
+ "size": 12207
242
+ },
243
+ "example/NaCl-wien2k/README.md": {
244
+ "size": 519
245
+ },
246
+ "example/NaCl-wien2k/phonopy_disp.yaml": {
247
+ "size": 12207
248
+ },
249
+ "example/NaCl/NaCl-band-gv.py": {
250
+ "size": 1132
251
+ },
252
+ "example/NaCl/NaCl-band.py": {
253
+ "size": 586
254
+ },
255
+ "example/NaCl/NaCl-dynmat.py": {
256
+ "size": 1100
257
+ },
258
+ "example/NaCl/NaCl-gv.py": {
259
+ "size": 814
260
+ },
261
+ "example/NaCl/NaCl-read_write_fc.py": {
262
+ "size": 670
263
+ },
264
+ "example/NaCl/NaCl-yaml.py": {
265
+ "size": 502
266
+ },
267
+ "example/NaCl/NaCl.py": {
268
+ "size": 4078
269
+ },
270
+ "example/NaCl/README.md": {
271
+ "size": 872
272
+ },
273
+ "example/NaCl/phonopy_disp.yaml": {
274
+ "size": 12203
275
+ },
276
+ "example/Si-CP2K/README.md": {
277
+ "size": 833
278
+ },
279
+ "example/Si-PWmat/README.md": {
280
+ "size": 900
281
+ },
282
+ "example/Si-PWmat/mesh.yaml": {
283
+ "size": 291996
284
+ },
285
+ "example/Si-QE/README.md": {
286
+ "size": 773
287
+ },
288
+ "example/Si-QE/phonopy_disp.yaml": {
289
+ "size": 12097
290
+ },
291
+ "example/Si-QHA/Si.py": {
292
+ "size": 2003
293
+ },
294
+ "example/Si-QHA/disp.yaml": {
295
+ "size": 211
296
+ },
297
+ "example/Si-abinit/disp.yaml": {
298
+ "size": 6249
299
+ },
300
+ "example/Si-elk/disp.yaml": {
301
+ "size": 6249
302
+ },
303
+ "example/Si-gruneisen/Si-gruneisen.py": {
304
+ "size": 1980
305
+ },
306
+ "example/Si-gruneisen/minus/disp.yaml": {
307
+ "size": 6249
308
+ },
309
+ "example/Si-gruneisen/orig/disp.yaml": {
310
+ "size": 6249
311
+ },
312
+ "example/Si-gruneisen/plus/disp.yaml": {
313
+ "size": 6249
314
+ },
315
+ "example/Si-lammps/README.md": {
316
+ "size": 2510
317
+ },
318
+ "example/Si-lammps/generate_displacements.py": {
319
+ "size": 551
320
+ },
321
+ "example/Si-lammps/phonopy_disp.yaml": {
322
+ "size": 4427
323
+ },
324
+ "example/Si-lammps/phonopy_unitcell.yaml": {
325
+ "size": 432
326
+ },
327
+ "example/Si-nosym/disp.yaml": {
328
+ "size": 4301
329
+ },
330
+ "example/Si/README.md": {
331
+ "size": 529
332
+ },
333
+ "example/Si/phonopy_disp.yaml": {
334
+ "size": 4592
335
+ },
336
+ "example/SiO2-CP2K-xyz/README.md": {
337
+ "size": 1472
338
+ },
339
+ "example/SiO2-CP2K-xyz/gen_supercell_xyz.py": {
340
+ "size": 6490
341
+ },
342
+ "example/SiO2-CP2K-xyz/get_born_cp2k.py": {
343
+ "size": 8020
344
+ },
345
+ "example/SiO2-HP/README.md": {
346
+ "size": 730
347
+ },
348
+ "example/SiO2-HP/phonopy_disp.yaml": {
349
+ "size": 10059
350
+ },
351
+ "example/SnO2/README.md": {
352
+ "size": 1036
353
+ },
354
+ "example/SnO2/phonopy_disp.yaml": {
355
+ "size": 13427
356
+ },
357
+ "example/Ti-lammps/README.md": {
358
+ "size": 2715
359
+ },
360
+ "example/Ti-lammps/phonopy_disp.yaml": {
361
+ "size": 15528
362
+ },
363
+ "example/TiO2-anatase/README.md": {
364
+ "size": 293
365
+ },
366
+ "example/TiO2-anatase/phonopy_disp.yaml": {
367
+ "size": 31890
368
+ },
369
+ "example/ZnO/README.md": {
370
+ "size": 224
371
+ },
372
+ "example/ZnO/phonopy_disp.yaml": {
373
+ "size": 7641
374
+ },
375
+ "example/diamond-FHI-aims/README.md": {
376
+ "size": 818
377
+ },
378
+ "phonopy/__init__.py": {
379
+ "size": 1907
380
+ },
381
+ "phonopy/api_gruneisen.py": {
382
+ "size": 7884
383
+ },
384
+ "phonopy/api_phonopy.py": {
385
+ "size": 134219
386
+ },
387
+ "phonopy/api_qha.py": {
388
+ "size": 17431
389
+ },
390
+ "phonopy/cui/collect_cell_info.py": {
391
+ "size": 20559
392
+ },
393
+ "phonopy/cui/create_force_sets.py": {
394
+ "size": 10783
395
+ },
396
+ "phonopy/cui/load.py": {
397
+ "size": 14364
398
+ },
399
+ "phonopy/cui/load_helper.py": {
400
+ "size": 19077
401
+ },
402
+ "phonopy/cui/phonopy_argparse.py": {
403
+ "size": 28408
404
+ },
405
+ "phonopy/cui/phonopy_bandplot_script.py": {
406
+ "size": 19662
407
+ },
408
+ "phonopy/cui/phonopy_gruneisen_script.py": {
409
+ "size": 14439
410
+ },
411
+ "phonopy/cui/phonopy_qha_script.py": {
412
+ "size": 12066
413
+ },
414
+ "phonopy/cui/phonopy_script.py": {
415
+ "size": 80359
416
+ },
417
+ "phonopy/cui/phonopy_vasp_efe_script.py": {
418
+ "size": 5780
419
+ },
420
+ "phonopy/cui/settings.py": {
421
+ "size": 81854
422
+ },
423
+ "phonopy/cui/show_symmetry.py": {
424
+ "size": 8377
425
+ },
426
+ "phonopy/exception.py": {
427
+ "size": 2814
428
+ },
429
+ "phonopy/file_IO.py": {
430
+ "size": 30976
431
+ },
432
+ "phonopy/gruneisen/band_structure.py": {
433
+ "size": 11360
434
+ },
435
+ "phonopy/gruneisen/core.py": {
436
+ "size": 5836
437
+ },
438
+ "phonopy/gruneisen/mesh.py": {
439
+ "size": 8790
440
+ },
441
+ "phonopy/harmonic/derivative_dynmat.py": {
442
+ "size": 12781
443
+ },
444
+ "phonopy/harmonic/displacement.py": {
445
+ "size": 11529
446
+ },
447
+ "phonopy/harmonic/dynamical_matrix.py": {
448
+ "size": 39772
449
+ },
450
+ "phonopy/harmonic/dynmat_to_fc.py": {
451
+ "size": 17407
452
+ },
453
+ "phonopy/harmonic/force_constants.py": {
454
+ "size": 29448
455
+ },
456
+ "phonopy/interface/abacus.py": {
457
+ "size": 13287
458
+ },
459
+ "phonopy/interface/abinit.py": {
460
+ "size": 9781
461
+ },
462
+ "phonopy/interface/aims.py": {
463
+ "size": 7935
464
+ },
465
+ "phonopy/interface/alm.py": {
466
+ "size": 13943
467
+ },
468
+ "phonopy/interface/calculator.py": {
469
+ "size": 40720
470
+ },
471
+ "phonopy/interface/castep.py": {
472
+ "size": 9449
473
+ },
474
+ "phonopy/interface/cif.py": {
475
+ "size": 3820
476
+ },
477
+ "phonopy/interface/cp2k.py": {
478
+ "size": 14478
479
+ },
480
+ "phonopy/interface/crystal.py": {
481
+ "size": 14085
482
+ },
483
+ "phonopy/interface/dftbp.py": {
484
+ "size": 6674
485
+ },
486
+ "phonopy/interface/elk.py": {
487
+ "size": 7589
488
+ },
489
+ "phonopy/interface/fc_calculator.py": {
490
+ "size": 12689
491
+ },
492
+ "phonopy/interface/fleur.py": {
493
+ "size": 10058
494
+ },
495
+ "phonopy/interface/lammps.py": {
496
+ "size": 13809
497
+ },
498
+ "phonopy/interface/mlp.py": {
499
+ "size": 3421
500
+ },
501
+ "phonopy/interface/phonopy_yaml.py": {
502
+ "size": 42053
503
+ },
504
+ "phonopy/interface/pwmat.py": {
505
+ "size": 5803
506
+ },
507
+ "phonopy/interface/pypolymlp.py": {
508
+ "size": 15197
509
+ },
510
+ "phonopy/interface/qe.py": {
511
+ "size": 24153
512
+ },
513
+ "phonopy/interface/qlm.py": {
514
+ "size": 6874
515
+ },
516
+ "phonopy/interface/siesta.py": {
517
+ "size": 9549
518
+ },
519
+ "phonopy/interface/symfc.py": {
520
+ "size": 16920
521
+ },
522
+ "phonopy/interface/turbomole.py": {
523
+ "size": 8835
524
+ },
525
+ "phonopy/interface/vasp.py": {
526
+ "size": 57527
527
+ },
528
+ "phonopy/interface/wien2k.py": {
529
+ "size": 14256
530
+ },
531
+ "phonopy/phonon/animation.py": {
532
+ "size": 12257
533
+ },
534
+ "phonopy/phonon/band_structure.py": {
535
+ "size": 36609
536
+ },
537
+ "phonopy/phonon/character_table.py": {
538
+ "size": 42462
539
+ },
540
+ "phonopy/phonon/degeneracy.py": {
541
+ "size": 5702
542
+ },
543
+ "phonopy/phonon/dos.py": {
544
+ "size": 20985
545
+ },
546
+ "phonopy/phonon/group_velocity.py": {
547
+ "size": 11359
548
+ },
549
+ "phonopy/phonon/irreps.py": {
550
+ "size": 26033
551
+ },
552
+ "phonopy/phonon/mesh.py": {
553
+ "size": 16041
554
+ },
555
+ "phonopy/phonon/modulation.py": {
556
+ "size": 11866
557
+ },
558
+ "phonopy/phonon/moment.py": {
559
+ "size": 4214
560
+ },
561
+ "phonopy/phonon/qpoints.py": {
562
+ "size": 10579
563
+ },
564
+ "phonopy/phonon/random_displacements.py": {
565
+ "size": 21609
566
+ },
567
+ "phonopy/phonon/tetrahedron_mesh.py": {
568
+ "size": 10236
569
+ },
570
+ "phonopy/phonon/thermal_displacement.py": {
571
+ "size": 17368
572
+ },
573
+ "phonopy/phonon/thermal_properties.py": {
574
+ "size": 24661
575
+ },
576
+ "phonopy/physical_units.py": {
577
+ "size": 7741
578
+ },
579
+ "phonopy/qha/core.py": {
580
+ "size": 42678
581
+ },
582
+ "phonopy/qha/electron.py": {
583
+ "size": 7371
584
+ },
585
+ "phonopy/qha/eos.py": {
586
+ "size": 4712
587
+ },
588
+ "phonopy/scripts/phonopy.py": {
589
+ "size": 1765
590
+ },
591
+ "phonopy/scripts/phonopy_bandplot.py": {
592
+ "size": 1695
593
+ },
594
+ "phonopy/scripts/phonopy_calc_convert.py": {
595
+ "size": 8279
596
+ },
597
+ "phonopy/scripts/phonopy_crystal_born.py": {
598
+ "size": 5781
599
+ },
600
+ "phonopy/scripts/phonopy_gruneisen.py": {
601
+ "size": 1697
602
+ },
603
+ "phonopy/scripts/phonopy_gruneisenplot.py": {
604
+ "size": 9210
605
+ },
606
+ "phonopy/scripts/phonopy_load.py": {
607
+ "size": 1792
608
+ },
609
+ "phonopy/scripts/phonopy_pdosplot.py": {
610
+ "size": 6975
611
+ },
612
+ "phonopy/scripts/phonopy_propplot.py": {
613
+ "size": 7263
614
+ },
615
+ "phonopy/scripts/phonopy_qe_born.py": {
616
+ "size": 5333
617
+ },
618
+ "phonopy/scripts/phonopy_qha.py": {
619
+ "size": 1685
620
+ },
621
+ "phonopy/scripts/phonopy_tdplot.py": {
622
+ "size": 7327
623
+ },
624
+ "phonopy/scripts/phonopy_vasp_born.py": {
625
+ "size": 5983
626
+ },
627
+ "phonopy/scripts/phonopy_vasp_efe.py": {
628
+ "size": 1696
629
+ },
630
+ "phonopy/spectrum/dynamic_structure_factor.py": {
631
+ "size": 11697
632
+ },
633
+ "phonopy/spectrum/velocity.py": {
634
+ "size": 7807
635
+ },
636
+ "phonopy/sscha/core.py": {
637
+ "size": 8404
638
+ },
639
+ "phonopy/structure/atoms.py": {
640
+ "size": 43239
641
+ },
642
+ "phonopy/structure/brillouin_zone.py": {
643
+ "size": 5659
644
+ },
645
+ "phonopy/structure/cells.py": {
646
+ "size": 61680
647
+ },
648
+ "phonopy/structure/dataset.py": {
649
+ "size": 3848
650
+ },
651
+ "phonopy/structure/grid_points.py": {
652
+ "size": 24021
653
+ },
654
+ "phonopy/structure/snf.py": {
655
+ "size": 11479
656
+ },
657
+ "phonopy/structure/symmetry.py": {
658
+ "size": 23251
659
+ },
660
+ "phonopy/structure/tetrahedron_method.py": {
661
+ "size": 23214
662
+ },
663
+ "phonopy/unfolding/core.py": {
664
+ "size": 14179
665
+ },
666
+ "phonopy/units.py": {
667
+ "size": 3770
668
+ },
669
+ "phonopy/utils.py": {
670
+ "size": 2433
671
+ },
672
+ "phonopy/version.py": {
673
+ "size": 1641
674
+ },
675
+ "pyproject.toml": {
676
+ "size": 2448
677
+ },
678
+ "requirements.txt": {
679
+ "size": 76
680
+ },
681
+ "test/api/test_api_phonopy.py": {
682
+ "size": 14759
683
+ },
684
+ "test/conftest.py": {
685
+ "size": 17038
686
+ },
687
+ "test/cui/phonopy_command/test_phonopy_script.py": {
688
+ "size": 26894
689
+ },
690
+ "test/cui/phonopy_gruneisen/test_phonopy_gruneisen_script.py": {
691
+ "size": 3395
692
+ },
693
+ "test/cui/phonopy_qha/test_phonopy_qha_script.py": {
694
+ "size": 4923
695
+ },
696
+ "test/cui/phonopy_vasp_efe/test_phonopy_vasp_efe_script.py": {
697
+ "size": 1707
698
+ },
699
+ "test/gruneisen/test_gruneisen.py": {
700
+ "size": 5051
701
+ },
702
+ "test/harmonic/test_derivative_dynmat.py": {
703
+ "size": 3866
704
+ },
705
+ "test/harmonic/test_displacements.py": {
706
+ "size": 9356
707
+ },
708
+ "test/harmonic/test_dynamical_matrix.py": {
709
+ "size": 26441
710
+ },
711
+ "test/harmonic/test_dynmat_to_fc.py": {
712
+ "size": 5222
713
+ },
714
+ "test/harmonic/test_force_constants.py": {
715
+ "size": 4757
716
+ },
717
+ "test/interface/BaGa2-wien2k.yaml": {
718
+ "size": 591
719
+ },
720
+ "test/interface/NaCl-abacus-mag-noncolin.yaml": {
721
+ "size": 17712
722
+ },
723
+ "test/interface/NaCl-abacus-mag.yaml": {
724
+ "size": 15189
725
+ },
726
+ "test/interface/NaCl-abinit-pwscf.yaml": {
727
+ "size": 1155
728
+ },
729
+ "test/interface/NaCl-castep.yaml": {
730
+ "size": 1152
731
+ },
732
+ "test/interface/NaCl-vasp.yaml": {
733
+ "size": 1155
734
+ },
735
+ "test/interface/Si-CP2K.yaml": {
736
+ "size": 1155
737
+ },
738
+ "test/interface/Si-CRYSTAL.yaml": {
739
+ "size": 477
740
+ },
741
+ "test/interface/Si-TURBOMOLE.yaml": {
742
+ "size": 1155
743
+ },
744
+ "test/interface/Si-pwmat.yaml": {
745
+ "size": 14460
746
+ },
747
+ "test/interface/nac.yaml": {
748
+ "size": 780
749
+ },
750
+ "test/interface/phonopy.yaml": {
751
+ "size": 12534
752
+ },
753
+ "test/interface/phonopy_symcells_NaCl.yaml": {
754
+ "size": 1739
755
+ },
756
+ "test/interface/test_CP2K.py": {
757
+ "size": 968
758
+ },
759
+ "test/interface/test_CRYSTAL.py": {
760
+ "size": 770
761
+ },
762
+ "test/interface/test_TURBOMOLE.py": {
763
+ "size": 774
764
+ },
765
+ "test/interface/test_abacus.py": {
766
+ "size": 3247
767
+ },
768
+ "test/interface/test_abinit.py": {
769
+ "size": 1004
770
+ },
771
+ "test/interface/test_castep.py": {
772
+ "size": 757
773
+ },
774
+ "test/interface/test_conversion.py": {
775
+ "size": 3861
776
+ },
777
+ "test/interface/test_lammps.py": {
778
+ "size": 3567
779
+ },
780
+ "test/interface/test_phonopy_yaml.py": {
781
+ "size": 7596
782
+ },
783
+ "test/interface/test_pwmat.py": {
784
+ "size": 1143
785
+ },
786
+ "test/interface/test_pypolymlp.py": {
787
+ "size": 14419
788
+ },
789
+ "test/interface/test_qe.py": {
790
+ "size": 3427
791
+ },
792
+ "test/interface/test_qlm.py": {
793
+ "size": 2388
794
+ },
795
+ "test/interface/test_symfc.py": {
796
+ "size": 2916
797
+ },
798
+ "test/interface/test_vasp.py": {
799
+ "size": 7703
800
+ },
801
+ "test/interface/test_wien2k.py": {
802
+ "size": 813
803
+ },
804
+ "test/phonon/eigvecs_ii_TiPN3.txt": {
805
+ "size": 22923
806
+ },
807
+ "test/phonon/eigvecs_ij_TiPN3.txt": {
808
+ "size": 73570
809
+ },
810
+ "test/phonon/test_band_structure.py": {
811
+ "size": 7145
812
+ },
813
+ "test/phonon/test_dos.py": {
814
+ "size": 4028
815
+ },
816
+ "test/phonon/test_group_velocity.py": {
817
+ "size": 2563
818
+ },
819
+ "test/phonon/test_irreps.py": {
820
+ "size": 63607
821
+ },
822
+ "test/phonon/test_mesh.py": {
823
+ "size": 6271
824
+ },
825
+ "test/phonon/test_modulation.py": {
826
+ "size": 1621
827
+ },
828
+ "test/phonon/test_moment.py": {
829
+ "size": 1831
830
+ },
831
+ "test/phonon/test_qpoints.py": {
832
+ "size": 3955
833
+ },
834
+ "test/phonon/test_random_displacements.py": {
835
+ "size": 19456
836
+ },
837
+ "test/phonon/test_tetrahedron_mesh.py": {
838
+ "size": 2896
839
+ },
840
+ "test/phonon/test_thermal_displacement.py": {
841
+ "size": 6109
842
+ },
843
+ "test/phonon/test_thermal_properties.py": {
844
+ "size": 1775
845
+ },
846
+ "test/phonon/test_thermal_properties_classical.py": {
847
+ "size": 1832
848
+ },
849
+ "test/phonopy_KCl.yaml": {
850
+ "size": 12596
851
+ },
852
+ "test/phonopy_NaCl_unitcell1.yaml": {
853
+ "size": 1184
854
+ },
855
+ "test/phonopy_NaCl_unitcell2.yaml": {
856
+ "size": 1152
857
+ },
858
+ "test/phonopy_disp_NaCl.yaml": {
859
+ "size": 12203
860
+ },
861
+ "test/phonopy_disp_SnO2.yaml": {
862
+ "size": 13647
863
+ },
864
+ "test/phonopy_disp_TiO2.yaml": {
865
+ "size": 19499
866
+ },
867
+ "test/phonopy_load/test_phonopy_load.py": {
868
+ "size": 1011
869
+ },
870
+ "test/phonopy_params_Si.yaml": {
871
+ "size": 5187
872
+ },
873
+ "test/phonopy_params_Zr3N4.yaml": {
874
+ "size": 22776
875
+ },
876
+ "test/polymlp_KCL-120.yaml": {
877
+ "size": 195626
878
+ },
879
+ "test/qha/test_QHA.py": {
880
+ "size": 8235
881
+ },
882
+ "test/qha/test_QHA_efe.py": {
883
+ "size": 8662
884
+ },
885
+ "test/qha/test_electron.py": {
886
+ "size": 10737
887
+ },
888
+ "test/spectrum/test_dynamic_structure_factor.py": {
889
+ "size": 9502
890
+ },
891
+ "test/spectrum/test_velocity.py": {
892
+ "size": 770
893
+ },
894
+ "test/sscha/test_core.py": {
895
+ "size": 805
896
+ },
897
+ "test/structure/Si-conv.yaml": {
898
+ "size": 1155
899
+ },
900
+ "test/structure/SiO2-123.yaml": {
901
+ "size": 4346
902
+ },
903
+ "test/structure/test_atoms.py": {
904
+ "size": 11715
905
+ },
906
+ "test/structure/test_brillouin_zone.py": {
907
+ "size": 1985
908
+ },
909
+ "test/structure/test_cells.py": {
910
+ "size": 15821
911
+ },
912
+ "test/structure/test_grid_points.py": {
913
+ "size": 16981
914
+ },
915
+ "test/structure/test_symmetry.py": {
916
+ "size": 11280
917
+ },
918
+ "test/structure/test_tetrahedron_method.py": {
919
+ "size": 11232
920
+ },
921
+ "test/structure/tio2_qpoints.yaml": {
922
+ "size": 2469
923
+ },
924
+ "test/test_exception.py": {
925
+ "size": 395
926
+ },
927
+ "test/test_file_IO.py": {
928
+ "size": 2315
929
+ },
930
+ "test/unfolding/plot_band.py": {
931
+ "size": 379
932
+ },
933
+ "test/unfolding/test_unfolding.py": {
934
+ "size": 4763
935
+ }
936
+ },
937
+ "processed_by": "zip_fallback",
938
+ "success": true
939
+ },
940
+ "structure": {
941
+ "packages": [
942
+ "source.phonopy"
943
+ ]
944
+ },
945
+ "dependencies": {
946
+ "has_environment_yml": false,
947
+ "has_requirements_txt": true,
948
+ "pyproject": true,
949
+ "setup_cfg": false,
950
+ "setup_py": false
951
+ },
952
+ "entry_points": {
953
+ "imports": [],
954
+ "cli": [],
955
+ "modules": []
956
+ },
957
+ "llm_analysis": {
958
+ "core_modules": [
959
+ {
960
+ "package": "phonopy",
961
+ "module": "api_phonopy",
962
+ "functions": [
963
+ "Phonopy",
964
+ "PhonopyAtoms"
965
+ ],
966
+ "classes": [
967
+ "Phonopy",
968
+ "PhonopyAtoms"
969
+ ],
970
+ "description": "Core module for phonon calculations and handling atomic structures."
971
+ },
972
+ {
973
+ "package": "phonopy",
974
+ "module": "api_gruneisen",
975
+ "functions": [
976
+ "Gruneisen"
977
+ ],
978
+ "classes": [
979
+ "Gruneisen"
980
+ ],
981
+ "description": "Module for Gruneisen parameter calculations."
982
+ },
983
+ {
984
+ "package": "phonopy",
985
+ "module": "api_qha",
986
+ "functions": [
987
+ "QHA"
988
+ ],
989
+ "classes": [
990
+ "QHA"
991
+ ],
992
+ "description": "Module for quasi-harmonic approximation calculations."
993
+ }
994
+ ],
995
+ "cli_commands": [
996
+ {
997
+ "name": "phonopy",
998
+ "module": "phonopy.scripts.phonopy",
999
+ "description": "Main command-line interface for phonopy."
1000
+ },
1001
+ {
1002
+ "name": "phonopy-bandplot",
1003
+ "module": "phonopy.scripts.phonopy_bandplot",
1004
+ "description": "Command-line tool for plotting phonon band structures."
1005
+ },
1006
+ {
1007
+ "name": "phonopy-gruneisen",
1008
+ "module": "phonopy.scripts.phonopy_gruneisen",
1009
+ "description": "Command-line tool for Gruneisen parameter calculations."
1010
+ }
1011
+ ],
1012
+ "import_strategy": {
1013
+ "primary": "import",
1014
+ "fallback": "cli",
1015
+ "confidence": 0.9
1016
+ },
1017
+ "dependencies": {
1018
+ "required": [
1019
+ "numpy",
1020
+ "scipy",
1021
+ "matplotlib"
1022
+ ],
1023
+ "optional": [
1024
+ "ase",
1025
+ "spglib"
1026
+ ]
1027
+ },
1028
+ "risk_assessment": {
1029
+ "import_feasibility": 0.8,
1030
+ "intrusiveness_risk": "medium",
1031
+ "complexity": "medium"
1032
+ }
1033
+ },
1034
+ "deepwiki_analysis": {
1035
+ "repo_url": "https://github.com/phonopy/phonopy",
1036
+ "repo_name": "phonopy",
1037
+ "content": "phonopy/phonopy\nGetting Started\nInstallation\nQuick Start Tutorial\nCore Concepts\nCrystal Structures and Cells\nSymmetry Operations\nForce Constants\nDynamical Matrices\nAPI Reference\nPhonopy Class\nCommand-Line Interface\nSettings and Configuration\nFile I/O and Data Formats\nPhonon Calculations\nBand Structure\nMesh Sampling and Reciprocal Space\nDensity of States\nThermal Properties\nGroup Velocities and Derivatives\nCalculator Interfaces\nInterface Architecture\nVASP Interface\nQuantum ESPRESSO Interface\nAbinit and Wien2k Interfaces\nOther Calculator Interfaces\nForce Constant Methods\nTraditional Finite Difference\nSymfc Interface\nALM Interface\nMethod Comparison and Selection\nAdvanced Topics\nNon-Analytic Term Correction\nIrreducible Representations\nDerivative Dynamical Matrix\nGrüneisen Parameters\nQuasi-Harmonic Approximation\nRandom Displacements and Modulations\nMachine Learning Potentials\nPyPolymlp Integration\nMLP Training and Evaluation\nC Extensions and Performance\nDevelopment Guide\nBuild System and Compilation\nCode Quality Tools\nTesting Framework\nContributing Guidelines\nCMakeLists.txt\ndoc/changelog.md\ndoc/conf.py\ndoc/install.md\nget_nanoversion.sh\nphonopy/__init__.py\nphonopy/api_phonopy.py\nphonopy/cui/load.py\nphonopy/cui/load_helper.py\nphonopy/cui/phonopy_argparse.py\nphonopy/cui/phonopy_script.py\nphonopy/cui/settings.py\nphonopy/file_IO.py\nphonopy/interface/phonopy_yaml.py\nphonopy/version.py\npyproject.toml\nrequirements.txt\nPhonopy is a Python package for phonon calculations in the harmonic approximation. The software computes phonon frequencies, band structures, density of states, and thermodynamic properties by solving the lattice dynamics eigenvalue problem from interatomic force constants. Current version is 2.46.1.\nPurpose and Scope\nPhonopy processes crystal structures and atomic forces to calculate phonon properties through a four-stage workflow:\nDisplacement Generation: Create supercells with atomic displacements (systematic or random)\nForce Calculation: Compute forces using external DFT/force calculators (user performs this step)\nForce Constant Calculation: Derive force constants from displacement-force datasets using finite difference, symfc (default since v2.30.0), or ALM methods\nPhonon Property Calculation: Solve dynamical matrix eigenvalue problem to obtain frequencies and thermodynamic properties\nThe package provides two user interfaces:\nCommand-line:phonopyandphonopy-loadcommands\nphonopy-load\nPython API:Phonopyclass andload()function\nPhonopy supports 18+ calculator interfaces (VASP, Quantum ESPRESSO, ABINIT, Wien2k, CRYSTAL, etc.) and multiple file formats (traditional text files, YAML, HDF5).\nSources:phonopy/version.py37phonopy/api_phonopy.py109phonopy/cui/load.py55doc/changelog.md1-200\nHigh-Level Architecture\nPhonopy follows a layered architecture with thePhonopyclass (phonopy/api_phonopy.py109) as the central orchestrator. The system is organized into six major subsystems:\nPhonopy System Architecture\nFile_IOCalculator_InterfacesPhonon_AnalysisDynamical_Matrix_SystemForce_Constant_CalculationCrystal_Structure_SystemCore_OrchestrationUser_Interfacesphonopy commandphonopy_script.pyphonopy-load commandscripts/phonopy_load.pyPhonopy classapi_phonopy.py:109load functioncui/load.py:55Phonopy Coreapi_phonopy.py:109State ManagementMethod OrchestrationPhonopyAtomsstructure/atoms.py:50Supercellstructure/cells.py:94Primitivestructure/cells.py:450Symmetrystructure/symmetry.pyget_fc2fc_calculator.py:71FDFCSolverTraditional FDSymfcFCSolverSymfc defaultALMFCSolverALM higher-orderDynamicalMatrixdynamical_matrix.py:48DynamicalMatrixNACdynamical_matrix.py:248Polar materialsBandStructureband_structure.py:49Mesh/IterMeshmesh.py:49ThermalPropertiesthermal_properties.py:39TotalDos/ProjectedDosdos.py:40GroupVelocitygroup_velocity.py:40Calculator Dispatchercalculator.pyVASPvasp.pyQuantum ESPRESSOqe.py15+ Other Calculatorsabinit, wien2k, etc.phonopy.yamlphonopy_yaml.py:374FORCE_SETS, BORNfile_IO.pyHDF5 Formatforce_constants.hdf5\nCalculator_Interfaces\nPhonon_Analysis\nDynamical_Matrix_System\nForce_Constant_Calculation\nCrystal_Structure_System\nCore_Orchestration\nUser_Interfaces\nphonopy commandphonopy_script.py\nphonopy-load commandscripts/phonopy_load.py\nPhonopy classapi_phonopy.py:109\nload functioncui/load.py:55\nPhonopy Coreapi_phonopy.py:109State ManagementMethod Orchestration\nPhonopyAtomsstructure/atoms.py:50\nSupercellstructure/cells.py:94\nPrimitivestructure/cells.py:450\nSymmetrystructure/symmetry.py\nget_fc2fc_calculator.py:71\nFDFCSolverTraditional FD\nSymfcFCSolverSymfc default\nALMFCSolverALM higher-order\nDynamicalMatrixdynamical_matrix.py:48\nDynamicalMatrixNACdynamical_matrix.py:248Polar materials\nBandStructureband_structure.py:49\nMesh/IterMeshmesh.py:49\nThermalPropertiesthermal_properties.py:39\nTotalDos/ProjectedDosdos.py:40\nGroupVelocitygroup_velocity.py:40\nCalculator Dispatchercalculator.py\nVASPvasp.py\nQuantum ESPRESSOqe.py\n15+ Other Calculatorsabinit, wien2k, etc.\nphonopy.yamlphonopy_yaml.py:374\nFORCE_SETS, BORNfile_IO.py\nHDF5 Formatforce_constants.hdf5\nSubsystem Descriptions\nPhonopyAtoms\nSymfcFCSolver\nALMFCSolver\nDynamicalMatrix\nDynamicalMatrixNAC\nBandStructure\nThermalProperties\nGroupVelocity\nPhonopyYaml\nSources:phonopy/api_phonopy.py109phonopy/structure/cells.py94phonopy/structure/cells.py450phonopy/interface/fc_calculator.py71phonopy/harmonic/dynamical_matrix.py48phonopy/phonon/band_structure.py49phonopy/interface/calculator.py\nComputational Pipeline\nThe typical phonon calculation workflow proceeds through five phases:\nPhonopy Computational Pipeline\nPhase5_Phonon_CalculationsPhase4_Force_ProcessingPhase3_External_CalculationPhase2_Displacement_GenerationPhase1_Structure_ProcessingInput StructurePOSCAR/phonopy.yamlParse Structureread_crystal_structurePhonopyAtomsunitcellBuild Supercell_build_supercellBuild Primitive_build_primitive_cellAnalyze SymmetrySymmetry classSupercell InstancePrimitive Instancegenerate_displacementsapi_phonopy.py:883Systematic FDget_least_displacementsRandom Displacementsget_random_displacementsWrite Displaced SupercellsPOSCAR-001, etc.User Runs DFT/Force CalculatorVASP, QE, etc.Parse ForcesCalculator InterfaceCreate Datasetdisplacements + forcesCalculate FCproduce_force_constantsFCSolversymfc defaultSymmetrize FCsymmetrize_force_constantsSetup Dynamical Matrix_set_dynamical_matrixApply NAC if neededDynamicalMatrixNACBand Structurerun_band_structureMesh Samplingrun_meshThermal Propertiesrun_thermal_propertiesDOS Calculationrun_total_dos\nPhase5_Phonon_Calculations\nPhase4_Force_Processing\nPhase3_External_Calculation\nPhase2_Displacement_Generation\nPhase1_Structure_Processing\nInput StructurePOSCAR/phonopy.yaml\nParse Structureread_crystal_structure\nPhonopyAtomsunitcell\nBuild Supercell_build_supercell\nBuild Primitive_build_primitive_cell\nAnalyze SymmetrySymmetry class\nSupercell Instance\nPrimitive Instance\ngenerate_displacementsapi_phonopy.py:883\nSystematic FDget_least_displacements\nRandom Displacementsget_random_displacements\nWrite Displaced SupercellsPOSCAR-001, etc.\nUser Runs DFT/Force CalculatorVASP, QE, etc.\nParse ForcesCalculator Interface\nCreate Datasetdisplacements + forces\nCalculate FCproduce_force_constants\nFCSolversymfc default\nSymmetrize FCsymmetrize_force_constants\nSetup Dynamical Matrix_set_dynamical_matrix\nApply NAC if neededDynamicalMatrixNAC\nBand Structurerun_band_structure\nMesh Samplingrun_mesh\nThermal Propertiesrun_thermal_properties\nDOS Calculationrun_total_dos\nKey Pipeline Stages:\nStructure Processing(Page 3.1): Parse input structure → build supercell/primitive → analyze symmetry\nDisplacement Generation(Page 4.1): Create systematic (FD) or random displacements usinggenerate_displacements()\ngenerate_displacements()\nExternal Calculation: User performs force calculations (external to Phonopy)\nForce Processing(Page 7): Parse forces → create dataset → calculate force constants using symfc/traditional/ALM\nPhonon Calculations(Page 5): Setup dynamical matrix → apply NAC → compute band structure, DOS, thermal properties\nSources:phonopy/api_phonopy.py883phonopy/api_phonopy.py1120phonopy/api_phonopy.py1355phonopy/api_phonopy.py1452phonopy/api_phonopy.py1721phonopy/api_phonopy.py2346phonopy/api_phonopy.py2374phonopy/interface/calculator.py104phonopy/interface/fc_calculator.py71\nCore Components\nPhonopy Class\nThePhonopyclass (phonopy/api_phonopy.py109) serves as the main API and central orchestrator. Detailed documentation is in Page 4.1.\nKey State Attributes:\nPhonopyAtoms\nforce_constants\ndynamical_matrix\nDynamicalMatrix\nKey Workflow Methods:\ngenerate_displacements()\nproduce_force_constants()\nrun_band_structure()\nrun_thermal_properties()\nSources:phonopy/api_phonopy.py109phonopy/api_phonopy.py883phonopy/api_phonopy.py1120phonopy/api_phonopy.py1355phonopy/api_phonopy.py1452phonopy/api_phonopy.py1721\nConfiguration and Settings\nConfiguration is managed through theSettingsclass (phonopy/cui/settings.py57) andConfParserclass (phonopy/cui/settings.py129). Settings control:\nCalculation mode (band structure, mesh, DOS, thermal properties)\nForce constants calculator selection (traditional, symfc, ALM)\nDisplacement generation parameters\nFile I/O options\nSymmetry handling\nSee Page 4.3 for detailed configuration documentation.\nSources:phonopy/cui/settings.py57phonopy/cui/settings.py129\nFile I/O System\nPhonopy supports three file format categories:\nTraditional text files:FORCE_SETS,FORCE_CONSTANTS,BORN(parsers inphonopy/file_IO.py)\nFORCE_CONSTANTS\nYAML format:phonopy.yaml,phonopy_disp.yaml(handled byPhonopyYamlclass atphonopy/interface/phonopy_yaml.py374)\nphonopy.yaml\nphonopy_disp.yaml\nPhonopyYaml\nHDF5 format:force_constants.hdf5,mesh.hdf5,band.hdf5(binary with compression support since v2.46.0)\nforce_constants.hdf5",
1038
+ "model": "gpt-4o-2024-08-06",
1039
+ "source": "selenium",
1040
+ "success": true
1041
+ },
1042
+ "deepwiki_options": {
1043
+ "enabled": true,
1044
+ "model": "gpt-4o-2024-08-06"
1045
+ },
1046
+ "risk": {
1047
+ "import_feasibility": 0.8,
1048
+ "intrusiveness_risk": "medium",
1049
+ "complexity": "medium"
1050
+ }
1051
+ }
phonopy/mcp_output/diff_report.md ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Phonopy Project Difference Report
2
+
3
+ **Repository:** phonopy
4
+ **Project Type:** Python Library
5
+ **Main Features:** Basic Functionality
6
+ **Report Generated On:** 2026-01-31 12:45:56
7
+ **Intrusiveness:** None
8
+ **Workflow Status:** Success
9
+ **Test Status:** Failed
10
+
11
+ ## Project Overview
12
+
13
+ Phonopy is a Python library designed to provide basic functionalities for phonon calculations. It is widely used in computational materials science for analyzing vibrational properties of crystals. The project is open-source and continually evolving to incorporate new features and improvements.
14
+
15
+ ## Difference Analysis
16
+
17
+ ### New Files Added
18
+
19
+ In this update, 8 new files have been introduced to the repository. These files are likely to contain new features, enhancements, or additional documentation. However, no existing files were modified, indicating that the new additions are non-intrusive and do not alter the current functionality of the library.
20
+
21
+ ### Modified Files
22
+
23
+ There were no modifications to existing files in this update. This suggests that the core functionality remains unchanged, and the focus was on expanding the library's capabilities or adding supplementary resources.
24
+
25
+ ## Technical Analysis
26
+
27
+ ### Workflow Status
28
+
29
+ The workflow status is marked as "success," indicating that the integration and deployment processes were executed without any issues. This suggests that the new files were correctly integrated into the existing codebase.
30
+
31
+ ### Test Status
32
+
33
+ The test status is marked as "failed," which is a critical issue that needs immediate attention. This failure indicates that the new additions may have introduced bugs or that the existing test suite is not comprehensive enough to cover the new functionalities.
34
+
35
+ ## Recommendations and Improvements
36
+
37
+ 1. **Investigate Test Failures:** Conduct a thorough investigation to identify the cause of the test failures. This may involve reviewing the new files for potential bugs or updating the test suite to accommodate new features.
38
+
39
+ 2. **Enhance Test Coverage:** Ensure that the test suite is comprehensive and covers all new functionalities introduced by the recent update. This will help in maintaining the reliability and stability of the library.
40
+
41
+ 3. **Documentation Update:** If the new files include new features or enhancements, update the documentation to reflect these changes. This will assist users in understanding and utilizing the new functionalities effectively.
42
+
43
+ 4. **Code Review:** Conduct a code review of the new files to ensure they adhere to the project's coding standards and best practices. This will help in maintaining code quality and consistency.
44
+
45
+ ## Deployment Information
46
+
47
+ The deployment of the new files was successful, as indicated by the workflow status. However, due to the test failures, it is advisable to hold off on any production deployment until the issues are resolved.
48
+
49
+ ## Future Planning
50
+
51
+ 1. **Bug Fixes:** Prioritize resolving the test failures and any identified bugs in the new files.
52
+
53
+ 2. **Feature Expansion:** Consider planning for future updates that expand on the newly introduced functionalities, ensuring they align with the project's goals and user needs.
54
+
55
+ 3. **Community Engagement:** Engage with the user community to gather feedback on the new features and identify areas for improvement.
56
+
57
+ 4. **Regular Updates:** Establish a regular update schedule to ensure the library remains up-to-date with the latest advancements in phonon calculations and computational materials science.
58
+
59
+ ## Conclusion
60
+
61
+ The recent update to the Phonopy project introduced new files that expand the library's capabilities. However, the test failures highlight the need for immediate attention to ensure the stability and reliability of the library. By addressing these issues and following the recommendations outlined in this report, the project can continue to provide valuable tools for the scientific community.
62
+
63
+ ---
phonopy/mcp_output/mcp_plugin/__init__.py ADDED
File without changes
phonopy/mcp_output/mcp_plugin/adapter.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ # Path settings
5
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
6
+ sys.path.insert(0, source_path)
7
+
8
+ # Import statements
9
+ from phonopy.api_phonopy import Phonopy
10
+ from phonopy.cui.load import load
11
+ from phonopy.cui.settings import Settings
12
+ from phonopy.interface.calculator import Calculator
13
+ from phonopy.interface.phonopy_yaml import PhonopyYaml
14
+
15
+ class Adapter:
16
+ """
17
+ Adapter class for MCP plugin to interact with the Phonopy library.
18
+ This class provides methods to utilize Phonopy's functionalities.
19
+ """
20
+
21
+ def __init__(self):
22
+ self.mode = "import"
23
+
24
+ # -------------------------------------------------------------------------
25
+ # Instance Methods
26
+ # -------------------------------------------------------------------------
27
+
28
+ def create_phonopy_instance(self, unitcell, supercell_matrix, primitive_matrix=None):
29
+ """
30
+ Create an instance of the Phonopy class.
31
+
32
+ Parameters:
33
+ - unitcell: Unit cell structure
34
+ - supercell_matrix: Supercell transformation matrix
35
+ - primitive_matrix: Primitive cell transformation matrix (optional)
36
+
37
+ Returns:
38
+ - dict: {'status': 'success', 'phonopy_instance': Phonopy object} or {'status': 'error', 'message': str}
39
+ """
40
+ try:
41
+ phonopy_instance = Phonopy(unitcell, supercell_matrix, primitive_matrix)
42
+ return {'status': 'success', 'phonopy_instance': phonopy_instance}
43
+ except Exception as e:
44
+ return {'status': 'error', 'message': f"Failed to create Phonopy instance: {str(e)}"}
45
+
46
+ def create_settings_instance(self, config):
47
+ """
48
+ Create an instance of the Settings class.
49
+
50
+ Parameters:
51
+ - config: Configuration dictionary
52
+
53
+ Returns:
54
+ - dict: {'status': 'success', 'settings_instance': Settings object} or {'status': 'error', 'message': str}
55
+ """
56
+ try:
57
+ settings_instance = Settings(config)
58
+ return {'status': 'success', 'settings_instance': settings_instance}
59
+ except Exception as e:
60
+ return {'status': 'error', 'message': f"Failed to create Settings instance: {str(e)}"}
61
+
62
+ def create_calculator_instance(self, calculator_type, **kwargs):
63
+ """
64
+ Create an instance of the Calculator class.
65
+
66
+ Parameters:
67
+ - calculator_type: Type of calculator (e.g., 'vasp', 'qe')
68
+ - kwargs: Additional parameters for the calculator
69
+
70
+ Returns:
71
+ - dict: {'status': 'success', 'calculator_instance': Calculator object} or {'status': 'error', 'message': str}
72
+ """
73
+ try:
74
+ calculator_instance = Calculator(calculator_type, **kwargs)
75
+ return {'status': 'success', 'calculator_instance': calculator_instance}
76
+ except Exception as e:
77
+ return {'status': 'error', 'message': f"Failed to create Calculator instance: {str(e)}"}
78
+
79
+ def create_phonopy_yaml_instance(self, yaml_file):
80
+ """
81
+ Create an instance of the PhonopyYaml class.
82
+
83
+ Parameters:
84
+ - yaml_file: Path to the YAML file
85
+
86
+ Returns:
87
+ - dict: {'status': 'success', 'phonopy_yaml_instance': PhonopyYaml object} or {'status': 'error', 'message': str}
88
+ """
89
+ try:
90
+ phonopy_yaml_instance = PhonopyYaml(yaml_file)
91
+ return {'status': 'success', 'phonopy_yaml_instance': phonopy_yaml_instance}
92
+ except Exception as e:
93
+ return {'status': 'error', 'message': f"Failed to create PhonopyYaml instance: {str(e)}"}
94
+
95
+ # -------------------------------------------------------------------------
96
+ # Call Methods
97
+ # -------------------------------------------------------------------------
98
+
99
+ def call_load_function(self, filename):
100
+ """
101
+ Call the load function from the Phonopy library.
102
+
103
+ Parameters:
104
+ - filename: Path to the file to be loaded
105
+
106
+ Returns:
107
+ - dict: {'status': 'success', 'data': loaded data} or {'status': 'error', 'message': str}
108
+ """
109
+ try:
110
+ data = load(filename)
111
+ return {'status': 'success', 'data': data}
112
+ except Exception as e:
113
+ return {'status': 'error', 'message': f"Failed to load data: {str(e)}"}
114
+
115
+ # -------------------------------------------------------------------------
116
+ # Error Handling and Fallback
117
+ # -------------------------------------------------------------------------
118
+
119
+ def handle_import_failure(self):
120
+ """
121
+ Handle import failure cases and provide a graceful fallback.
122
+
123
+ Returns:
124
+ - dict: {'status': 'error', 'message': str}
125
+ """
126
+ return {'status': 'error', 'message': "Import failed. Please ensure all dependencies are installed and accessible."}
127
+
128
+ # Example usage
129
+ if __name__ == "__main__":
130
+ adapter = Adapter()
131
+ result = adapter.create_phonopy_instance(unitcell="unitcell", supercell_matrix="supercell_matrix")
132
+ print(result)
phonopy/mcp_output/mcp_plugin/main.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ MCP Service Auto-Wrapper - Auto-generated
3
+ """
4
+ from mcp_service import create_app
5
+
6
+ def main():
7
+ """Main entry point"""
8
+ app = create_app()
9
+ return app
10
+
11
+ if __name__ == "__main__":
12
+ app = main()
13
+ app.run()
phonopy/mcp_output/mcp_plugin/mcp_service.py ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import sys
3
+
4
+ # Add the local source directory to sys.path
5
+ source_path = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "source")
6
+ if source_path not in sys.path:
7
+ sys.path.insert(0, source_path)
8
+
9
+ from fastmcp import FastMCP
10
+ from phonopy.api_phonopy import Phonopy
11
+ from phonopy.cui.load import load
12
+ from phonopy.cui.settings import Settings
13
+
14
+ # Create the FastMCP service application
15
+ mcp = FastMCP("phonopy_service")
16
+
17
+ @mcp.tool(name="generate_displacements", description="Generate atomic displacements for phonon calculations.")
18
+ def generate_displacements(structure_file: str) -> dict:
19
+ """
20
+ Generates atomic displacements for phonon calculations.
21
+
22
+ Parameters:
23
+ - structure_file (str): Path to the input structure file.
24
+
25
+ Returns:
26
+ - dict: A dictionary containing success, result, or error fields.
27
+ """
28
+ try:
29
+ phonopy_instance = load(structure_file)
30
+ displacements = phonopy_instance.generate_displacements()
31
+ return {"success": True, "result": displacements}
32
+ except Exception as e:
33
+ return {"success": False, "error": str(e)}
34
+
35
+ @mcp.tool(name="calculate_force_constants", description="Calculate force constants from displacement-force datasets.")
36
+ def calculate_force_constants(displacement_file: str, force_file: str) -> dict:
37
+ """
38
+ Calculates force constants from displacement-force datasets.
39
+
40
+ Parameters:
41
+ - displacement_file (str): Path to the displacement data file.
42
+ - force_file (str): Path to the force data file.
43
+
44
+ Returns:
45
+ - dict: A dictionary containing success, result, or error fields.
46
+ """
47
+ try:
48
+ phonopy_instance = load(displacement_file)
49
+ phonopy_instance.produce_force_constants(force_file)
50
+ return {"success": True, "result": "Force constants calculated successfully."}
51
+ except Exception as e:
52
+ return {"success": False, "error": str(e)}
53
+
54
+ @mcp.tool(name="run_band_structure", description="Run phonon band structure calculations.")
55
+ def run_band_structure(structure_file: str) -> dict:
56
+ """
57
+ Runs phonon band structure calculations.
58
+
59
+ Parameters:
60
+ - structure_file (str): Path to the input structure file.
61
+
62
+ Returns:
63
+ - dict: A dictionary containing success, result, or error fields.
64
+ """
65
+ try:
66
+ phonopy_instance = load(structure_file)
67
+ band_structure = phonopy_instance.run_band_structure()
68
+ return {"success": True, "result": band_structure}
69
+ except Exception as e:
70
+ return {"success": False, "error": str(e)}
71
+
72
+ @mcp.tool(name="run_thermal_properties", description="Calculate thermal properties of the material.")
73
+ def run_thermal_properties(structure_file: str) -> dict:
74
+ """
75
+ Calculates thermal properties of the material.
76
+
77
+ Parameters:
78
+ - structure_file (str): Path to the input structure file.
79
+
80
+ Returns:
81
+ - dict: A dictionary containing success, result, or error fields.
82
+ """
83
+ try:
84
+ phonopy_instance = load(structure_file)
85
+ thermal_properties = phonopy_instance.run_thermal_properties()
86
+ return {"success": True, "result": thermal_properties}
87
+ except Exception as e:
88
+ return {"success": False, "error": str(e)}
89
+
90
+ def create_app() -> FastMCP:
91
+ """
92
+ Creates and returns the FastMCP application instance.
93
+
94
+ Returns:
95
+ - FastMCP: The FastMCP application instance.
96
+ """
97
+ return mcp
phonopy/mcp_output/requirements.txt ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastmcp
2
+ fastapi
3
+ uvicorn[standard]
4
+ pydantic>=2.0.0
5
+ numpy >= 1.17.0
6
+ PyYAML >= 5.3
7
+ matplotlib >= 2.2.2
8
+ h5py >= 3.0
9
+ spglib >= 2.5
10
+ symfc>=1.5
11
+ scipy
phonopy/mcp_output/start_mcp.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """
3
+ MCP Service Startup Entry
4
+ """
5
+ import sys
6
+ import os
7
+
8
+ project_root = os.path.dirname(os.path.abspath(__file__))
9
+ mcp_plugin_dir = os.path.join(project_root, "mcp_plugin")
10
+ if mcp_plugin_dir not in sys.path:
11
+ sys.path.insert(0, mcp_plugin_dir)
12
+
13
+ from mcp_service import create_app
14
+
15
+ def main():
16
+ """Start FastMCP service"""
17
+ app = create_app()
18
+ # Use environment variable to configure port, default 8000
19
+ port = int(os.environ.get("MCP_PORT", "8000"))
20
+
21
+ # Choose transport mode based on environment variable
22
+ transport = os.environ.get("MCP_TRANSPORT", "stdio")
23
+ if transport == "http":
24
+ app.run(transport="http", host="0.0.0.0", port=port)
25
+ else:
26
+ # Default to STDIO mode
27
+ app.run()
28
+
29
+ if __name__ == "__main__":
30
+ main()
phonopy/mcp_output/workflow_summary.json ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "repository": {
3
+ "name": "phonopy",
4
+ "url": "https://github.com/phonopy/phonopy",
5
+ "local_path": "/export/zxcpu1/shiweijie/code/ghh/Code2MCP/workspace/phonopy",
6
+ "description": "Python library",
7
+ "features": "Basic functionality",
8
+ "tech_stack": "Python",
9
+ "stars": 0,
10
+ "forks": 0,
11
+ "language": "Python",
12
+ "last_updated": "",
13
+ "complexity": "medium",
14
+ "intrusiveness_risk": "medium"
15
+ },
16
+ "execution": {
17
+ "start_time": 1769834614.195348,
18
+ "end_time": 1769834692.488752,
19
+ "duration": 78.29340410232544,
20
+ "status": "success",
21
+ "workflow_status": "success",
22
+ "nodes_executed": [
23
+ "download",
24
+ "analysis",
25
+ "env",
26
+ "generate",
27
+ "run",
28
+ "review",
29
+ "finalize"
30
+ ],
31
+ "total_files_processed": 1,
32
+ "environment_type": "unknown",
33
+ "llm_calls": 0,
34
+ "deepwiki_calls": 0
35
+ },
36
+ "tests": {
37
+ "original_project": {
38
+ "passed": false,
39
+ "details": {},
40
+ "test_coverage": "100%",
41
+ "execution_time": 0,
42
+ "test_files": []
43
+ },
44
+ "mcp_plugin": {
45
+ "passed": true,
46
+ "details": {},
47
+ "service_health": "healthy",
48
+ "startup_time": 0,
49
+ "transport_mode": "stdio",
50
+ "fastmcp_version": "unknown",
51
+ "mcp_version": "unknown"
52
+ }
53
+ },
54
+ "analysis": {
55
+ "structure": {
56
+ "packages": [
57
+ "source.phonopy"
58
+ ]
59
+ },
60
+ "dependencies": {
61
+ "has_environment_yml": false,
62
+ "has_requirements_txt": true,
63
+ "pyproject": true,
64
+ "setup_cfg": false,
65
+ "setup_py": false
66
+ },
67
+ "entry_points": {
68
+ "imports": [],
69
+ "cli": [],
70
+ "modules": []
71
+ },
72
+ "risk_assessment": {
73
+ "import_feasibility": 0.8,
74
+ "intrusiveness_risk": "medium",
75
+ "complexity": "medium"
76
+ },
77
+ "deepwiki_analysis": {
78
+ "repo_url": "https://github.com/phonopy/phonopy",
79
+ "repo_name": "phonopy",
80
+ "content": "phonopy/phonopy\nGetting Started\nInstallation\nQuick Start Tutorial\nCore Concepts\nCrystal Structures and Cells\nSymmetry Operations\nForce Constants\nDynamical Matrices\nAPI Reference\nPhonopy Class\nCommand-Line Interface\nSettings and Configuration\nFile I/O and Data Formats\nPhonon Calculations\nBand Structure\nMesh Sampling and Reciprocal Space\nDensity of States\nThermal Properties\nGroup Velocities and Derivatives\nCalculator Interfaces\nInterface Architecture\nVASP Interface\nQuantum ESPRESSO Interface\nAbinit and Wien2k Interfaces\nOther Calculator Interfaces\nForce Constant Methods\nTraditional Finite Difference\nSymfc Interface\nALM Interface\nMethod Comparison and Selection\nAdvanced Topics\nNon-Analytic Term Correction\nIrreducible Representations\nDerivative Dynamical Matrix\nGrüneisen Parameters\nQuasi-Harmonic Approximation\nRandom Displacements and Modulations\nMachine Learning Potentials\nPyPolymlp Integration\nMLP Training and Evaluation\nC Extensions and Performance\nDevelopment Guide\nBuild System and Compilation\nCode Quality Tools\nTesting Framework\nContributing Guidelines\nCMakeLists.txt\ndoc/changelog.md\ndoc/conf.py\ndoc/install.md\nget_nanoversion.sh\nphonopy/__init__.py\nphonopy/api_phonopy.py\nphonopy/cui/load.py\nphonopy/cui/load_helper.py\nphonopy/cui/phonopy_argparse.py\nphonopy/cui/phonopy_script.py\nphonopy/cui/settings.py\nphonopy/file_IO.py\nphonopy/interface/phonopy_yaml.py\nphonopy/version.py\npyproject.toml\nrequirements.txt\nPhonopy is a Python package for phonon calculations in the harmonic approximation. The software computes phonon frequencies, band structures, density of states, and thermodynamic properties by solving the lattice dynamics eigenvalue problem from interatomic force constants. Current version is 2.46.1.\nPurpose and Scope\nPhonopy processes crystal structures and atomic forces to calculate phonon properties through a four-stage workflow:\nDisplacement Generation: Create supercells with atomic displacements (systematic or random)\nForce Calculation: Compute forces using external DFT/force calculators (user performs this step)\nForce Constant Calculation: Derive force constants from displacement-force datasets using finite difference, symfc (default since v2.30.0), or ALM methods\nPhonon Property Calculation: Solve dynamical matrix eigenvalue problem to obtain frequencies and thermodynamic properties\nThe package provides two user interfaces:\nCommand-line:phonopyandphonopy-loadcommands\nphonopy-load\nPython API:Phonopyclass andload()function\nPhonopy supports 18+ calculator interfaces (VASP, Quantum ESPRESSO, ABINIT, Wien2k, CRYSTAL, etc.) and multiple file formats (traditional text files, YAML, HDF5).\nSources:phonopy/version.py37phonopy/api_phonopy.py109phonopy/cui/load.py55doc/changelog.md1-200\nHigh-Level Architecture\nPhonopy follows a layered architecture with thePhonopyclass (phonopy/api_phonopy.py109) as the central orchestrator. The system is organized into six major subsystems:\nPhonopy System Architecture\nFile_IOCalculator_InterfacesPhonon_AnalysisDynamical_Matrix_SystemForce_Constant_CalculationCrystal_Structure_SystemCore_OrchestrationUser_Interfacesphonopy commandphonopy_script.pyphonopy-load commandscripts/phonopy_load.pyPhonopy classapi_phonopy.py:109load functioncui/load.py:55Phonopy Coreapi_phonopy.py:109State ManagementMethod OrchestrationPhonopyAtomsstructure/atoms.py:50Supercellstructure/cells.py:94Primitivestructure/cells.py:450Symmetrystructure/symmetry.pyget_fc2fc_calculator.py:71FDFCSolverTraditional FDSymfcFCSolverSymfc defaultALMFCSolverALM higher-orderDynamicalMatrixdynamical_matrix.py:48DynamicalMatrixNACdynamical_matrix.py:248Polar materialsBandStructureband_structure.py:49Mesh/IterMeshmesh.py:49ThermalPropertiesthermal_properties.py:39TotalDos/ProjectedDosdos.py:40GroupVelocitygroup_velocity.py:40Calculator Dispatchercalculator.pyVASPvasp.pyQuantum ESPRESSOqe.py15+ Other Calculatorsabinit, wien2k, etc.phonopy.yamlphonopy_yaml.py:374FORCE_SETS, BORNfile_IO.pyHDF5 Formatforce_constants.hdf5\nCalculator_Interfaces\nPhonon_Analysis\nDynamical_Matrix_System\nForce_Constant_Calculation\nCrystal_Structure_System\nCore_Orchestration\nUser_Interfaces\nphonopy commandphonopy_script.py\nphonopy-load commandscripts/phonopy_load.py\nPhonopy classapi_phonopy.py:109\nload functioncui/load.py:55\nPhonopy Coreapi_phonopy.py:109State ManagementMethod Orchestration\nPhonopyAtomsstructure/atoms.py:50\nSupercellstructure/cells.py:94\nPrimitivestructure/cells.py:450\nSymmetrystructure/symmetry.py\nget_fc2fc_calculator.py:71\nFDFCSolverTraditional FD\nSymfcFCSolverSymfc default\nALMFCSolverALM higher-order\nDynamicalMatrixdynamical_matrix.py:48\nDynamicalMatrixNACdynamical_matrix.py:248Polar materials\nBandStructureband_structure.py:49\nMesh/IterMeshmesh.py:49\nThermalPropertiesthermal_properties.py:39\nTotalDos/ProjectedDosdos.py:40\nGroupVelocitygroup_velocity.py:40\nCalculator Dispatchercalculator.py\nVASPvasp.py\nQuantum ESPRESSOqe.py\n15+ Other Calculatorsabinit, wien2k, etc.\nphonopy.yamlphonopy_yaml.py:374\nFORCE_SETS, BORNfile_IO.py\nHDF5 Formatforce_constants.hdf5\nSubsystem Descriptions\nPhonopyAtoms\nSymfcFCSolver\nALMFCSolver\nDynamicalMatrix\nDynamicalMatrixNAC\nBandStructure\nThermalProperties\nGroupVelocity\nPhonopyYaml\nSources:phonopy/api_phonopy.py109phonopy/structure/cells.py94phonopy/structure/cells.py450phonopy/interface/fc_calculator.py71phonopy/harmonic/dynamical_matrix.py48phonopy/phonon/band_structure.py49phonopy/interface/calculator.py\nComputational Pipeline\nThe typical phonon calculation workflow proceeds through five phases:\nPhonopy Computational Pipeline\nPhase5_Phonon_CalculationsPhase4_Force_ProcessingPhase3_External_CalculationPhase2_Displacement_GenerationPhase1_Structure_ProcessingInput StructurePOSCAR/phonopy.yamlParse Structureread_crystal_structurePhonopyAtomsunitcellBuild Supercell_build_supercellBuild Primitive_build_primitive_cellAnalyze SymmetrySymmetry classSupercell InstancePrimitive Instancegenerate_displacementsapi_phonopy.py:883Systematic FDget_least_displacementsRandom Displacementsget_random_displacementsWrite Displaced SupercellsPOSCAR-001, etc.User Runs DFT/Force CalculatorVASP, QE, etc.Parse ForcesCalculator InterfaceCreate Datasetdisplacements + forcesCalculate FCproduce_force_constantsFCSolversymfc defaultSymmetrize FCsymmetrize_force_constantsSetup Dynamical Matrix_set_dynamical_matrixApply NAC if neededDynamicalMatrixNACBand Structurerun_band_structureMesh Samplingrun_meshThermal Propertiesrun_thermal_propertiesDOS Calculationrun_total_dos\nPhase5_Phonon_Calculations\nPhase4_Force_Processing\nPhase3_External_Calculation\nPhase2_Displacement_Generation\nPhase1_Structure_Processing\nInput StructurePOSCAR/phonopy.yaml\nParse Structureread_crystal_structure\nPhonopyAtomsunitcell\nBuild Supercell_build_supercell\nBuild Primitive_build_primitive_cell\nAnalyze SymmetrySymmetry class\nSupercell Instance\nPrimitive Instance\ngenerate_displacementsapi_phonopy.py:883\nSystematic FDget_least_displacements\nRandom Displacementsget_random_displacements\nWrite Displaced SupercellsPOSCAR-001, etc.\nUser Runs DFT/Force CalculatorVASP, QE, etc.\nParse ForcesCalculator Interface\nCreate Datasetdisplacements + forces\nCalculate FCproduce_force_constants\nFCSolversymfc default\nSymmetrize FCsymmetrize_force_constants\nSetup Dynamical Matrix_set_dynamical_matrix\nApply NAC if neededDynamicalMatrixNAC\nBand Structurerun_band_structure\nMesh Samplingrun_mesh\nThermal Propertiesrun_thermal_properties\nDOS Calculationrun_total_dos\nKey Pipeline Stages:\nStructure Processing(Page 3.1): Parse input structure → build supercell/primitive → analyze symmetry\nDisplacement Generation(Page 4.1): Create systematic (FD) or random displacements usinggenerate_displacements()\ngenerate_displacements()\nExternal Calculation: User performs force calculations (external to Phonopy)\nForce Processing(Page 7): Parse forces → create dataset → calculate force constants using symfc/traditional/ALM\nPhonon Calculations(Page 5): Setup dynamical matrix → apply NAC → compute band structure, DOS, thermal properties\nSources:phonopy/api_phonopy.py883phonopy/api_phonopy.py1120phonopy/api_phonopy.py1355phonopy/api_phonopy.py1452phonopy/api_phonopy.py1721phonopy/api_phonopy.py2346phonopy/api_phonopy.py2374phonopy/interface/calculator.py104phonopy/interface/fc_calculator.py71\nCore Components\nPhonopy Class\nThePhonopyclass (phonopy/api_phonopy.py109) serves as the main API and central orchestrator. Detailed documentation is in Page 4.1.\nKey State Attributes:\nPhonopyAtoms\nforce_constants\ndynamical_matrix\nDynamicalMatrix\nKey Workflow Methods:\ngenerate_displacements()\nproduce_force_constants()\nrun_band_structure()\nrun_thermal_properties()\nSources:phonopy/api_phonopy.py109phonopy/api_phonopy.py883phonopy/api_phonopy.py1120phonopy/api_phonopy.py1355phonopy/api_phonopy.py1452phonopy/api_phonopy.py1721\nConfiguration and Settings\nConfiguration is managed through theSettingsclass (phonopy/cui/settings.py57) andConfParserclass (phonopy/cui/settings.py129). Settings control:\nCalculation mode (band structure, mesh, DOS, thermal properties)\nForce constants calculator selection (traditional, symfc, ALM)\nDisplacement generation parameters\nFile I/O options\nSymmetry handling\nSee Page 4.3 for detailed configuration documentation.\nSources:phonopy/cui/settings.py57phonopy/cui/settings.py129\nFile I/O System\nPhonopy supports three file format categories:\nTraditional text files:FORCE_SETS,FORCE_CONSTANTS,BORN(parsers inphonopy/file_IO.py)\nFORCE_CONSTANTS\nYAML format:phonopy.yaml,phonopy_disp.yaml(handled byPhonopyYamlclass atphonopy/interface/phonopy_yaml.py374)\nphonopy.yaml\nphonopy_disp.yaml\nPhonopyYaml\nHDF5 format:force_constants.hdf5,mesh.hdf5,band.hdf5(binary with compression support since v2.46.0)\nforce_constants.hdf5",
81
+ "model": "gpt-4o-2024-08-06",
82
+ "source": "selenium",
83
+ "success": true
84
+ },
85
+ "code_complexity": {
86
+ "cyclomatic_complexity": "medium",
87
+ "cognitive_complexity": "medium",
88
+ "maintainability_index": 75
89
+ },
90
+ "security_analysis": {
91
+ "vulnerabilities_found": 0,
92
+ "security_score": 85,
93
+ "recommendations": []
94
+ }
95
+ },
96
+ "plugin_generation": {
97
+ "files_created": [
98
+ "mcp_output/start_mcp.py",
99
+ "mcp_output/mcp_plugin/__init__.py",
100
+ "mcp_output/mcp_plugin/mcp_service.py",
101
+ "mcp_output/mcp_plugin/adapter.py",
102
+ "mcp_output/mcp_plugin/main.py",
103
+ "mcp_output/requirements.txt",
104
+ "mcp_output/README_MCP.md"
105
+ ],
106
+ "main_entry": "start_mcp.py",
107
+ "requirements": [
108
+ "fastmcp>=0.1.0",
109
+ "pydantic>=2.0.0"
110
+ ],
111
+ "readme_path": "/export/zxcpu1/shiweijie/code/ghh/Code2MCP/workspace/phonopy/mcp_output/README_MCP.md",
112
+ "adapter_mode": "import",
113
+ "total_lines_of_code": 0,
114
+ "generated_files_size": 0,
115
+ "tool_endpoints": 0,
116
+ "supported_features": [
117
+ "Basic functionality"
118
+ ],
119
+ "generated_tools": [
120
+ "Basic tools",
121
+ "Health check tools",
122
+ "Version info tools"
123
+ ]
124
+ },
125
+ "code_review": {},
126
+ "errors": [],
127
+ "warnings": [],
128
+ "recommendations": [
129
+ "Improve test coverage by adding more unit tests for critical modules",
130
+ "optimize large file handling to improve performance",
131
+ "enhance documentation for complex modules to aid understanding",
132
+ "implement continuous integration to automate testing and deployment",
133
+ "refactor code to reduce complexity and improve maintainability",
134
+ "ensure all dependencies are up-to-date to avoid security vulnerabilities",
135
+ "improve error handling to provide more informative messages",
136
+ "consider adding more examples and tutorials to help new users",
137
+ "streamline the build process to reduce setup time",
138
+ "conduct regular code reviews to maintain code quality."
139
+ ],
140
+ "performance_metrics": {
141
+ "memory_usage_mb": 0,
142
+ "cpu_usage_percent": 0,
143
+ "response_time_ms": 0,
144
+ "throughput_requests_per_second": 0
145
+ },
146
+ "deployment_info": {
147
+ "supported_platforms": [
148
+ "Linux",
149
+ "Windows",
150
+ "macOS"
151
+ ],
152
+ "python_versions": [
153
+ "3.8",
154
+ "3.9",
155
+ "3.10",
156
+ "3.11",
157
+ "3.12"
158
+ ],
159
+ "deployment_methods": [
160
+ "Docker",
161
+ "pip",
162
+ "conda"
163
+ ],
164
+ "monitoring_support": true,
165
+ "logging_configuration": "structured"
166
+ },
167
+ "execution_analysis": {
168
+ "success_factors": [
169
+ "Comprehensive workflow execution with all nodes completed successfully",
170
+ "Efficient processing of the repository with medium complexity"
171
+ ],
172
+ "failure_reasons": [],
173
+ "overall_assessment": "excellent",
174
+ "node_performance": {
175
+ "download_time": "Efficient download and setup of the repository",
176
+ "analysis_time": "Thorough analysis completed within expected duration",
177
+ "generation_time": "Code generation executed smoothly without delays",
178
+ "test_time": "Testing phase completed successfully with healthy service status"
179
+ },
180
+ "resource_usage": {
181
+ "memory_efficiency": "Memory usage was not explicitly measured, but no issues reported",
182
+ "cpu_efficiency": "CPU usage was not explicitly measured, but no issues reported",
183
+ "disk_usage": "Disk usage was efficient with minimal generated file size"
184
+ }
185
+ },
186
+ "technical_quality": {
187
+ "code_quality_score": 80,
188
+ "architecture_score": 85,
189
+ "performance_score": 75,
190
+ "maintainability_score": 75,
191
+ "security_score": 85,
192
+ "scalability_score": 80
193
+ }
194
+ }
phonopy/source/.pre-commit-config.yaml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # See https://pre-commit.com for more informatio
2
+ # See https://pre-commit.com/hooks.html for more hooks
3
+ repos:
4
+ - repo: https://github.com/pre-commit/pre-commit-hooks
5
+ rev: v6.0.0
6
+ hooks:
7
+ - id: trailing-whitespace
8
+ - id: end-of-file-fixer
9
+ - id: check-yaml
10
+ exclude: ^conda/
11
+ - id: check-added-large-files
12
+ - id: mixed-line-ending
13
+ args: ['--fix=lf']
14
+
15
+ - repo: https://github.com/astral-sh/ruff-pre-commit
16
+ rev: v0.14.14
17
+ hooks:
18
+ - id: ruff
19
+ args: [ "--fix", "--show-fixes" ]
20
+ - id: ruff-format
21
+
22
+ - repo: https://github.com/cheshirekow/cmake-format-precommit
23
+ rev: v0.6.13
24
+ hooks:
25
+ - id: cmake-format
26
+ - id: cmake-lint
phonopy/source/CMakeLists.txt ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cmake_minimum_required(VERSION 3.20)
2
+
3
+ if(NOT SKBUILD_PROJECT_NAME)
4
+ set(SKBUILD_PROJECT_NAME phonopy)
5
+ endif()
6
+
7
+ if(PHONOPY_LIBS)
8
+ project(phonopy LANGUAGES C)
9
+ set(CMAKE_MACOSX_RPATH 1)
10
+ set(CMAKE_C_FLAGS_RELEASE "-Wall -O2")
11
+ set(CMAKE_C_FLAGS_DEBUG "-g -DTHMWARNING")
12
+ include(GNUInstallDirs)
13
+
14
+ # Version numbers
15
+ file(READ ${PROJECT_SOURCE_DIR}/phonopy/version.py VERSION_FILE)
16
+ string(REGEX MATCH "__version__.*([0-9]+)[.]([0-9]+)[.]([0-9]+)" phonopy_version
17
+ ${VERSION_FILE})
18
+ set(PHONOPY_MAJOR_VERSION ${CMAKE_MATCH_1})
19
+ set(PHONOPY_MINOR_VERSION ${CMAKE_MATCH_2})
20
+ set(PHONOPY_MICRO_VERSION ${CMAKE_MATCH_3})
21
+ set(SERIAL
22
+ "${PHONOPY_MAJOR_VERSION}.${PHONOPY_MINOR_VERSION}.${PHONOPY_MICRO_VERSION}")
23
+ set(SOSERIAL "1")
24
+ else()
25
+ project(${SKBUILD_PROJECT_NAME})
26
+ set(DEV_MODULE Development.Module)
27
+ find_package(
28
+ Python 3.9 REQUIRED
29
+ COMPONENTS Interpreter ${DEV_MODULE}
30
+ OPTIONAL_COMPONENTS Development.SABIModule)
31
+ endif()
32
+
33
+ cmake_policy(SET CMP0007 NEW)
34
+
35
+ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
36
+ set(CMAKE_BUILD_TYPE
37
+ Release
38
+ CACHE STRING "Choose the type of build." FORCE)
39
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
40
+ "MinSizeRel" "RelWithDebInfo")
41
+ endif()
42
+
43
+ option(PHONOPY_USE_OMP "Build with OpenMP support" ON)
44
+
45
+ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
46
+ message(STATUS "CMAKE_SYSTEM_PREFIX_PATH: ${CMAKE_SYSTEM_PREFIX_PATH}")
47
+
48
+ if(PHONOPY_USE_OMP)
49
+ find_package(OpenMP)
50
+
51
+ if(OpenMP_FOUND)
52
+ message(STATUS "OpenMP libs: ${OpenMP_C_LIBRARIES}")
53
+ message(STATUS "OpenMP flags: ${OpenMP_C_FLAGS}")
54
+ endif()
55
+ else()
56
+ message(STATUS "OpenMP is not used.")
57
+ set(OpenMP_FOUND OFF) # cmake-lint: disable=C0103
58
+ endif()
59
+
60
+ set(SOURCES_PHONOPY
61
+ ${PROJECT_SOURCE_DIR}/c/phonopy.c ${PROJECT_SOURCE_DIR}/c/dynmat.c
62
+ ${PROJECT_SOURCE_DIR}/c/derivative_dynmat.c ${PROJECT_SOURCE_DIR}/c/rgrid.c
63
+ ${PROJECT_SOURCE_DIR}/c/tetrahedron_method.c)
64
+
65
+ if(BUILD_SHARED_LIBS)
66
+ # Shared library
67
+ add_library(phonopy_libs SHARED ${SOURCES_PHONOPY})
68
+
69
+ if(OpenMP_FOUND)
70
+ target_link_libraries(phonopy_libs PRIVATE OpenMP::OpenMP_C)
71
+ endif()
72
+
73
+ target_compile_definitions(phonopy_libs PRIVATE THM_EPSILON=1e-10)
74
+ else()
75
+ # Static link library
76
+ add_library(phonopy_libs STATIC ${SOURCES_PHONOPY})
77
+
78
+ if(OpenMP_FOUND)
79
+ target_link_libraries(phonopy_libs PRIVATE OpenMP::OpenMP_C)
80
+ endif()
81
+
82
+ target_compile_definitions(phonopy_libs PRIVATE THM_EPSILON=1e-10)
83
+ endif()
84
+
85
+ if(PHONOPY_LIBS)
86
+ install(FILES ${PROJECT_SOURCE_DIR}/c/phonopy.h
87
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
88
+
89
+ if(BUILD_SHARED_LIBS)
90
+ install(TARGETS phonopy_libs LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
91
+ set_property(TARGET phonopy_libs PROPERTY VERSION ${SERIAL})
92
+ set_property(TARGET phonopy_libs PROPERTY SOVERSION ${SOSERIAL})
93
+ else()
94
+ install(TARGETS phonopy_libs ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
95
+ set_property(TARGET phonopy_libs PROPERTY VERSION ${SERIAL})
96
+ set_property(TARGET phonopy_libs PROPERTY SOVERSION ${SOSERIAL})
97
+ set_property(TARGET phonopy_libs PROPERTY OUTPUT_NAME phonopy_libs)
98
+ endif()
99
+ else()
100
+ set_target_properties(phonopy_libs PROPERTIES POSITION_INDEPENDENT_CODE ON)
101
+
102
+ execute_process(
103
+ COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir
104
+ OUTPUT_STRIP_TRAILING_WHITESPACE
105
+ OUTPUT_VARIABLE NB_DIR)
106
+ list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}")
107
+ find_package(nanobind CONFIG REQUIRED)
108
+ nanobind_add_module(_phonopy STABLE_ABI ${PROJECT_SOURCE_DIR}/c/phonopy.h
109
+ ${PROJECT_SOURCE_DIR}/c/_phonopy.cpp)
110
+
111
+ if(OpenMP_FOUND)
112
+ target_link_libraries(_phonopy PRIVATE phonopy_libs OpenMP::OpenMP_C)
113
+ else()
114
+ target_link_libraries(_phonopy PRIVATE phonopy_libs)
115
+ endif()
116
+
117
+ target_compile_definitions(_phonopy PRIVATE THM_EPSILON=1e-10)
118
+ install(TARGETS _phonopy LIBRARY DESTINATION ${SKBUILD_PROJECT_NAME})
119
+ endif()
phonopy/source/LICENSE ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2014-2024, Phonopy. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without
4
+ modification, are permitted provided that the following conditions
5
+ are met:
6
+
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ * Neither the name of the phonopy project nor the
13
+ names of its contributors may be used to endorse or promote products
14
+ derived from this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT
20
+ HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
phonopy/source/MANIFEST.in ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ graft c
2
+ graft example
3
+ include __nanoversion__.txt
4
+ include LICENSE
5
+ recursive-include test *
6
+ recursive-exclude test *.pyc
phonopy/source/README.md ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [![Version Badge](https://anaconda.org/conda-forge/phonopy/badges/version.svg)](https://anaconda.org/conda-forge/phonopy)
2
+ [![Downloads Badge](https://anaconda.org/conda-forge/phonopy/badges/downloads.svg)](https://anaconda.org/conda-forge/phonopy)
3
+ [![PyPI](https://img.shields.io/pypi/dm/phonopy.svg?maxAge=2592000)](https://pypi.python.org/pypi/phonopy)
4
+ [![codecov](https://codecov.io/gh/phonopy/phonopy/branch/develop/graph/badge.svg)](https://codecov.io/gh/phonopy/phonopy)
5
+
6
+ # Phonopy
7
+
8
+ Phonon code mainly written in python. Phonopy user documentation is found at
9
+ http://phonopy.github.io/phonopy/
10
+
11
+ ## Installation
12
+
13
+ See https://phonopy.github.io/phonopy/install.html.
14
+
15
+ ## Mailing list for questions
16
+
17
+ Usual phonopy questions should be sent to phonopy mailing list
18
+ (https://sourceforge.net/p/phonopy/mailman/).
19
+
20
+ ## Development
21
+
22
+ The development of phonopy is managed on the `develop` branch of github phonopy
23
+ repository.
24
+
25
+ - Github issues is the place to discuss about phonopy issues.
26
+ - Github pull request is the place to request merging source code.
27
+
28
+ ### Formatting
29
+
30
+ Formatting rules are found in `pyproject.toml`.
31
+
32
+ ### pre-commit
33
+
34
+ Pre-commit (https://pre-commit.com/) is mainly used for applying the formatting
35
+ rules automatically. Therefore, it is strongly encouraged to use it at or before
36
+ git-commit. Pre-commit is set-up and used in the following way:
37
+
38
+ - Installed by `pip install pre-commit`, `conda install pre_commit` or see
39
+ https://pre-commit.com/#install.
40
+ - pre-commit hook is installed by `pre-commit install`.
41
+ - pre-commit hook is run by `pre-commit run --all-files`.
42
+
43
+ Unless running pre-commit, pre-commit.ci may push the fix at PR by github
44
+ action. In this case, the fix should be merged by the contributor's repository.
45
+
46
+ ### VSCode setting
47
+ - Not strictly, but VSCode's `settings.json` may be written like below
48
+
49
+ ```json
50
+ "ruff.lint.args": [
51
+ "--config=${workspaceFolder}/pyproject.toml",
52
+ ],
53
+ "[python]": {
54
+ "editor.defaultFormatter": "charliermarsh.ruff",
55
+ "editor.codeActionsOnSave": {
56
+ "source.organizeImports": "explicit"
57
+ }
58
+ },
59
+ ```
60
+
61
+ ## Documentation
62
+
63
+ Phonopy user documentation is written using python sphinx. The source files are
64
+ stored in `doc` directory. Please see how to write the documentation at
65
+ `doc/README.md`.
66
+
67
+ ## How to run tests
68
+
69
+ Tests are written using pytest. To run tests, pytest has to be installed. The
70
+ tests can be run by
71
+
72
+ ```bash
73
+ % pytest
74
+ ```
phonopy/source/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ phonopy Project Package Initialization File
4
+ """
phonopy/source/build-wheels.sh ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ set -e -u -x
3
+
4
+ function repair_wheel {
5
+ wheel="$1"
6
+ if ! auditwheel show "$wheel"; then
7
+ echo "Skipping non-platform wheel $wheel"
8
+ else
9
+ auditwheel repair "$wheel" --plat "$PLAT" -w /io/wheelhouse/
10
+ fi
11
+ }
12
+
13
+ yum install -y hdf5 freetype freetype-devel pkgconfig libpng-devel
14
+
15
+
16
+ for PYBIN in /opt/python/*/bin; do
17
+ if [[ $PYBIN == *"36"* ]] || [[ $PYBIN == *"37"* ]] || [[ $PYBIN == *"38"* ]] || [[ $PYBIN == *"39"* ]]; then
18
+ "${PYBIN}/pip" install -r /io/dev-requirements.txt
19
+ "${PYBIN}/pip" wheel /io/ -w wheelhouse/
20
+ fi
21
+ done
22
+
23
+ # Bundle external shared libraries into the wheels
24
+ for whl in wheelhouse/phonopy*.whl; do
25
+ repair_wheel "$whl"
26
+ done
27
+
28
+ # Install packages and test
29
+ # for PYBIN in /opt/python/*/bin/; do
30
+ # if [[ $PYBIN == *"36"* ]] || [[ $PYBIN == *"37"* ]] || [[ $PYBIN == *"38"* ]]; then
31
+ # "${PYBIN}/pip" install phonopy --no-index -f /io/wheelhouse
32
+ # fi
33
+ # done
phonopy/source/c/_phonopy.cpp ADDED
@@ -0,0 +1,599 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #include <nanobind/nanobind.h>
2
+ #include <nanobind/ndarray.h>
3
+ #include <stdint.h>
4
+
5
+ #include "phonopy.h"
6
+
7
+ namespace nb = nanobind;
8
+
9
+ void py_transform_dynmat_to_fc(
10
+ nb::ndarray<> py_force_constants, nb::ndarray<> py_dynamical_matrices,
11
+ nb::ndarray<> py_commensurate_points, nb::ndarray<> py_svecs,
12
+ nb::ndarray<> py_multi, nb::ndarray<> py_masses, nb::ndarray<> py_s2pp_map,
13
+ nb::ndarray<> py_fc_index_map, int64_t use_openmp) {
14
+ double *fc;
15
+ double (*dm)[2];
16
+ double (*comm_points)[3];
17
+ double (*svecs)[3];
18
+ double *masses;
19
+ int64_t (*multi)[2];
20
+ int64_t *s2pp_map;
21
+ int64_t *fc_index_map;
22
+ int64_t num_patom;
23
+ int64_t num_satom;
24
+
25
+ fc = (double *)py_force_constants.data();
26
+ dm = (double (*)[2])py_dynamical_matrices.data();
27
+ comm_points = (double (*)[3])py_commensurate_points.data();
28
+ svecs = (double (*)[3])py_svecs.data();
29
+ masses = (double *)py_masses.data();
30
+ multi = (int64_t (*)[2])py_multi.data();
31
+ s2pp_map = (int64_t *)py_s2pp_map.data();
32
+ fc_index_map = (int64_t *)py_fc_index_map.data();
33
+ num_patom = py_multi.shape(1);
34
+ num_satom = py_multi.shape(0);
35
+
36
+ phpy_transform_dynmat_to_fc(fc, dm, comm_points, svecs, multi, masses,
37
+ s2pp_map, fc_index_map, num_patom, num_satom,
38
+ use_openmp);
39
+ };
40
+
41
+ void py_perm_trans_symmetrize_fc(nb::ndarray<> py_force_constants,
42
+ int64_t level) {
43
+ double *fc;
44
+ int n_satom;
45
+
46
+ fc = (double *)py_force_constants.data();
47
+ n_satom = py_force_constants.shape(0);
48
+
49
+ phpy_perm_trans_symmetrize_fc(fc, n_satom, level);
50
+ }
51
+
52
+ void py_perm_trans_symmetrize_compact_fc(nb::ndarray<> py_force_constants,
53
+ nb::ndarray<> py_permutations,
54
+ nb::ndarray<> py_s2pp_map,
55
+ nb::ndarray<> py_p2s_map,
56
+ nb::ndarray<> py_nsym_list,
57
+ int64_t level) {
58
+ double *fc;
59
+ int *perms;
60
+ int *s2pp;
61
+ int *p2s;
62
+ int *nsym_list;
63
+ int n_patom, n_satom;
64
+
65
+ fc = (double *)py_force_constants.data();
66
+ perms = (int *)py_permutations.data();
67
+ s2pp = (int *)py_s2pp_map.data();
68
+ p2s = (int *)py_p2s_map.data();
69
+ nsym_list = (int *)py_nsym_list.data();
70
+ n_patom = py_force_constants.shape(0);
71
+ n_satom = py_force_constants.shape(1);
72
+
73
+ phpy_perm_trans_symmetrize_compact_fc(fc, p2s, s2pp, nsym_list, perms,
74
+ n_satom, n_patom, level);
75
+ }
76
+
77
+ void py_transpose_compact_fc(nb::ndarray<> py_force_constants,
78
+ nb::ndarray<> py_permutations,
79
+ nb::ndarray<> py_s2pp_map,
80
+ nb::ndarray<> py_p2s_map,
81
+ nb::ndarray<> py_nsym_list) {
82
+ double *fc;
83
+ int *s2pp;
84
+ int *p2s;
85
+ int *nsym_list;
86
+ int *perms;
87
+ int n_patom, n_satom;
88
+
89
+ fc = (double *)py_force_constants.data();
90
+ perms = (int *)py_permutations.data();
91
+ s2pp = (int *)py_s2pp_map.data();
92
+ p2s = (int *)py_p2s_map.data();
93
+ nsym_list = (int *)py_nsym_list.data();
94
+ n_patom = py_force_constants.shape(0);
95
+ n_satom = py_force_constants.shape(1);
96
+
97
+ phpy_set_index_permutation_symmetry_compact_fc(fc, p2s, s2pp, nsym_list,
98
+ perms, n_satom, n_patom, 1);
99
+ }
100
+
101
+ void py_get_dynamical_matrices_with_dd_openmp_over_qpoints(
102
+ nb::ndarray<> py_dynamical_matrix, nb::ndarray<> py_qpoints,
103
+ nb::ndarray<> py_force_constants, nb::ndarray<> py_svecs,
104
+ nb::ndarray<> py_multi, nb::ndarray<> py_positions, nb::ndarray<> py_masses,
105
+ nb::ndarray<> py_s2p_map, nb::ndarray<> py_p2s_map,
106
+ nb::ndarray<> py_q_direction, nb::ndarray<> py_born,
107
+ nb::ndarray<> py_dielectric, nb::ndarray<> py_reciprocal_lattice,
108
+ double nac_factor, nb::ndarray<> py_dd_q0, nb::ndarray<> py_G_list,
109
+ double lambda, int64_t is_nac, int64_t is_nac_q_zero, int64_t use_Wang_NAC,
110
+ int64_t hermitianize) {
111
+ double (*dm)[2];
112
+ double *fc;
113
+ double *q_direction;
114
+ double (*qpoints)[3];
115
+ double (*svecs)[3];
116
+ int64_t (*multi)[2];
117
+ double (*positions)[3];
118
+ double *masses;
119
+ double (*born)[3][3];
120
+ double (*dielectric)[3];
121
+ double (*reciprocal_lattice)[3];
122
+ double (*dd_q0)[2];
123
+ double (*G_list)[3];
124
+
125
+ int64_t *s2p_map;
126
+ int64_t *p2s_map;
127
+ int64_t num_patom;
128
+ int64_t num_satom;
129
+ int64_t n_qpoints;
130
+ int64_t n_Gpoints;
131
+
132
+ dm = (double (*)[2])py_dynamical_matrix.data();
133
+ qpoints = (double (*)[3])py_qpoints.data();
134
+ n_qpoints = py_qpoints.shape(0);
135
+ fc = (double *)py_force_constants.data();
136
+ svecs = (double (*)[3])py_svecs.data();
137
+ multi = (int64_t (*)[2])py_multi.data();
138
+ masses = (double *)py_masses.data();
139
+ s2p_map = (int64_t *)py_s2p_map.data();
140
+ p2s_map = (int64_t *)py_p2s_map.data();
141
+ born = (double (*)[3][3])py_born.data();
142
+ dielectric = (double (*)[3])py_dielectric.data();
143
+ reciprocal_lattice = (double (*)[3])py_reciprocal_lattice.data();
144
+
145
+ if (use_Wang_NAC || (!is_nac)) {
146
+ positions = NULL;
147
+ dd_q0 = NULL;
148
+ G_list = NULL;
149
+ n_Gpoints = 0;
150
+ } else {
151
+ positions = (double (*)[3])py_positions.data();
152
+ dd_q0 = (double (*)[2])py_dd_q0.data();
153
+ G_list = (double (*)[3])py_G_list.data();
154
+ n_Gpoints = py_G_list.shape(0);
155
+ }
156
+
157
+ if (is_nac_q_zero || (!is_nac)) {
158
+ q_direction = NULL;
159
+ } else {
160
+ q_direction = (double *)py_q_direction.data();
161
+ }
162
+
163
+ num_patom = py_p2s_map.shape(0);
164
+ num_satom = py_s2p_map.shape(0);
165
+
166
+ phpy_dynamical_matrices_with_dd_openmp_over_qpoints(
167
+ dm, qpoints, n_qpoints, fc, svecs, multi, positions, num_patom,
168
+ num_satom, masses, p2s_map, s2p_map, born, dielectric,
169
+ reciprocal_lattice, q_direction, nac_factor, dd_q0, G_list, n_Gpoints,
170
+ lambda, use_Wang_NAC, hermitianize);
171
+ }
172
+
173
+ void py_get_recip_dipole_dipole(
174
+ nb::ndarray<> py_dd, nb::ndarray<> py_dd_q0, nb::ndarray<> py_G_list,
175
+ nb::ndarray<> py_q_cart, nb::ndarray<> py_q_direction,
176
+ nb::ndarray<> py_born, nb::ndarray<> py_dielectric,
177
+ nb::ndarray<> py_positions, int64_t is_nac_q_zero, double factor,
178
+ double lambda, double tolerance, int64_t use_openmp) {
179
+ double (*dd)[2];
180
+ double (*dd_q0)[2];
181
+ double (*G_list)[3];
182
+ double *q_vector;
183
+ double *q_direction;
184
+ double (*born)[3][3];
185
+ double (*dielectric)[3];
186
+ double (*pos)[3];
187
+
188
+ int64_t num_patom, num_G;
189
+
190
+ dd = (double (*)[2])py_dd.data();
191
+ dd_q0 = (double (*)[2])py_dd_q0.data();
192
+ G_list = (double (*)[3])py_G_list.data();
193
+ if (is_nac_q_zero) {
194
+ q_direction = NULL;
195
+ } else {
196
+ q_direction = (double *)py_q_direction.data();
197
+ }
198
+ q_vector = (double *)py_q_cart.data();
199
+ born = (double (*)[3][3])py_born.data();
200
+ dielectric = (double (*)[3])py_dielectric.data();
201
+ pos = (double (*)[3])py_positions.data();
202
+ num_G = py_G_list.shape(0);
203
+ num_patom = py_positions.shape(0);
204
+
205
+ phpy_get_recip_dipole_dipole(dd, /* [natom, 3, natom, 3, (real, imag)] */
206
+ dd_q0, /* [natom, 3, 3, (real, imag)] */
207
+ G_list, /* [num_kvec, 3] */
208
+ num_G, num_patom, q_vector, q_direction, born,
209
+ dielectric, pos, /* [natom, 3] */
210
+ factor, /* 4pi/V*unit-conv */
211
+ lambda, /* 4 * Lambda^2 */
212
+ tolerance, use_openmp);
213
+ }
214
+
215
+ void py_get_recip_dipole_dipole_q0(nb::ndarray<> py_dd_q0,
216
+ nb::ndarray<> py_G_list,
217
+ nb::ndarray<> py_born,
218
+ nb::ndarray<> py_dielectric,
219
+ nb::ndarray<> py_positions, double lambda,
220
+ double tolerance, int64_t use_openmp) {
221
+ double (*dd_q0)[2];
222
+ double (*G_list)[3];
223
+ double (*born)[3][3];
224
+ double (*dielectric)[3];
225
+ double (*pos)[3];
226
+
227
+ int64_t num_patom, num_G;
228
+
229
+ dd_q0 = (double (*)[2])py_dd_q0.data();
230
+ G_list = (double (*)[3])py_G_list.data();
231
+ born = (double (*)[3][3])py_born.data();
232
+ dielectric = (double (*)[3])py_dielectric.data();
233
+ pos = (double (*)[3])py_positions.data();
234
+ num_G = py_G_list.shape(0);
235
+ num_patom = py_positions.shape(0);
236
+
237
+ phpy_get_recip_dipole_dipole_q0(dd_q0, /* [natom, 3, 3, (real, imag)] */
238
+ G_list, /* [num_kvec, 3] */
239
+ num_G, num_patom, born, dielectric,
240
+ pos, /* [natom, 3] */
241
+ lambda, /* 4 * Lambda^2 */
242
+ tolerance, use_openmp);
243
+ }
244
+
245
+ void py_get_derivative_dynmat(
246
+ nb::ndarray<> py_derivative_dynmat, nb::ndarray<> py_force_constants,
247
+ nb::ndarray<> py_q_vector, nb::ndarray<> py_lattice,
248
+ nb::ndarray<> py_reclat, nb::ndarray<> py_svecs, nb::ndarray<> py_multi,
249
+ nb::ndarray<> py_masses, nb::ndarray<> py_s2p_map, nb::ndarray<> py_p2s_map,
250
+ double nac_factor, nb::ndarray<> py_born, nb::ndarray<> py_dielectric,
251
+ nb::ndarray<> py_q_direction, int64_t is_nac, int64_t is_nac_q_zero,
252
+ int64_t use_openmp) {
253
+ double (*ddm)[2];
254
+ double *fc;
255
+ double *q_vector;
256
+ double *lattice;
257
+ double *reclat;
258
+ double (*svecs)[3];
259
+ double *masses;
260
+ int64_t (*multi)[2];
261
+ int64_t *s2p_map;
262
+ int64_t *p2s_map;
263
+ int64_t num_patom;
264
+ int64_t num_satom;
265
+
266
+ double *born;
267
+ double *epsilon;
268
+ double *q_dir;
269
+
270
+ ddm = (double (*)[2])py_derivative_dynmat.data();
271
+ fc = (double *)py_force_constants.data();
272
+ q_vector = (double *)py_q_vector.data();
273
+ lattice = (double *)py_lattice.data();
274
+ reclat = (double *)py_reclat.data();
275
+ svecs = (double (*)[3])py_svecs.data();
276
+ masses = (double *)py_masses.data();
277
+ multi = (int64_t (*)[2])py_multi.data();
278
+ s2p_map = (int64_t *)py_s2p_map.data();
279
+ p2s_map = (int64_t *)py_p2s_map.data();
280
+ num_patom = py_p2s_map.shape(0);
281
+ num_satom = py_s2p_map.shape(0);
282
+
283
+ epsilon = (double *)py_dielectric.data();
284
+ born = (double *)py_born.data();
285
+ if (is_nac_q_zero) {
286
+ q_dir = NULL;
287
+ } else {
288
+ q_dir = (double *)py_q_direction.data();
289
+ }
290
+
291
+ phpy_get_derivative_dynmat_at_q(ddm, num_patom, num_satom, fc, q_vector,
292
+ lattice, reclat, svecs, multi, masses,
293
+ s2p_map, p2s_map, nac_factor, born, epsilon,
294
+ q_dir, is_nac, use_openmp);
295
+ }
296
+
297
+ void py_get_thermal_properties(nb::ndarray<> py_thermal_props,
298
+ nb::ndarray<> py_temperatures,
299
+ nb::ndarray<> py_frequencies,
300
+ nb::ndarray<> py_weights,
301
+ double cutoff_frequency, double KB,
302
+ int classical) {
303
+ double *temperatures;
304
+ double *freqs;
305
+ double *thermal_props;
306
+ int64_t *weights;
307
+ int64_t num_qpoints;
308
+ int64_t num_bands;
309
+ int64_t num_temp;
310
+
311
+ thermal_props = (double *)py_thermal_props.data();
312
+ temperatures = (double *)py_temperatures.data();
313
+ num_temp = (int64_t)py_temperatures.shape(0);
314
+ freqs = (double *)py_frequencies.data();
315
+ num_qpoints = (int64_t)py_frequencies.shape(0);
316
+ weights = (int64_t *)py_weights.data();
317
+ num_bands = (int64_t)py_frequencies.shape(1);
318
+
319
+ phpy_get_thermal_properties(thermal_props, temperatures, freqs, weights,
320
+ num_temp, num_qpoints, num_bands,
321
+ cutoff_frequency, KB, classical);
322
+ }
323
+
324
+ void py_distribute_fc2(nb::ndarray<> py_force_constants,
325
+ nb::ndarray<> py_atom_list,
326
+ nb::ndarray<> py_fc_indices_of_atom_list,
327
+ nb::ndarray<> py_rotations_cart,
328
+ nb::ndarray<> py_permutations,
329
+ nb::ndarray<> py_map_atoms, nb::ndarray<> py_map_syms) {
330
+ double (*r_carts)[3][3];
331
+ double (*fc2)[3][3];
332
+ int *permutations;
333
+ int *map_atoms;
334
+ int *map_syms;
335
+ int *atom_list;
336
+ int *fc_indices_of_atom_list;
337
+ int64_t num_pos, num_rot, len_atom_list;
338
+
339
+ fc2 = (double (*)[3][3])py_force_constants.data();
340
+ atom_list = (int *)py_atom_list.data();
341
+ len_atom_list = py_atom_list.shape(0);
342
+ fc_indices_of_atom_list = (int *)py_fc_indices_of_atom_list.data();
343
+ permutations = (int *)py_permutations.data();
344
+ map_atoms = (int *)py_map_atoms.data();
345
+ map_syms = (int *)py_map_syms.data();
346
+ r_carts = (double (*)[3][3])py_rotations_cart.data();
347
+ num_rot = py_permutations.shape(0);
348
+ num_pos = py_permutations.shape(1);
349
+
350
+ phpy_distribute_fc2(fc2, atom_list, len_atom_list, fc_indices_of_atom_list,
351
+ r_carts, permutations, map_atoms, map_syms, num_rot,
352
+ num_pos);
353
+ }
354
+
355
+ bool py_compute_permutation(nb::ndarray<> permutation, nb::ndarray<> lattice,
356
+ nb::ndarray<> positions,
357
+ nb::ndarray<> permuted_positions, double symprec) {
358
+ int *rot_atoms;
359
+ double (*lat)[3];
360
+ double (*pos)[3];
361
+ double (*rot_pos)[3];
362
+ int num_pos;
363
+
364
+ int is_found;
365
+
366
+ rot_atoms = (int *)permutation.data();
367
+ lat = (double (*)[3])lattice.data();
368
+ pos = (double (*)[3])positions.data();
369
+ rot_pos = (double (*)[3])permuted_positions.data();
370
+ num_pos = positions.shape(0);
371
+
372
+ is_found = phpy_compute_permutation(rot_atoms, lat, pos, rot_pos, num_pos,
373
+ symprec);
374
+
375
+ if (is_found) {
376
+ return true;
377
+ } else {
378
+ return false;
379
+ }
380
+ }
381
+
382
+ void py_gsv_set_smallest_vectors_sparse(
383
+ nb::ndarray<> py_smallest_vectors, nb::ndarray<> py_multiplicity,
384
+ nb::ndarray<> py_pos_to, nb::ndarray<> py_pos_from,
385
+ nb::ndarray<> py_lattice_points, nb::ndarray<> py_reduced_basis,
386
+ nb::ndarray<> py_trans_mat, double symprec) {
387
+ double (*smallest_vectors)[27][3];
388
+ int *multiplicity;
389
+ double (*pos_to)[3];
390
+ double (*pos_from)[3];
391
+ int (*lattice_points)[3];
392
+ double (*reduced_basis)[3];
393
+ int (*trans_mat)[3];
394
+ int num_pos_to, num_pos_from, num_lattice_points;
395
+
396
+ smallest_vectors = (double (*)[27][3])py_smallest_vectors.data();
397
+ multiplicity = (int *)py_multiplicity.data();
398
+ pos_to = (double (*)[3])py_pos_to.data();
399
+ pos_from = (double (*)[3])py_pos_from.data();
400
+ num_pos_to = py_pos_to.shape(0);
401
+ num_pos_from = py_pos_from.shape(0);
402
+ lattice_points = (int (*)[3])py_lattice_points.data();
403
+ num_lattice_points = py_lattice_points.shape(0);
404
+ reduced_basis = (double (*)[3])py_reduced_basis.data();
405
+ trans_mat = (int (*)[3])py_trans_mat.data();
406
+
407
+ phpy_set_smallest_vectors_sparse(smallest_vectors, multiplicity, pos_to,
408
+ num_pos_to, pos_from, num_pos_from,
409
+ lattice_points, num_lattice_points,
410
+ reduced_basis, trans_mat, symprec);
411
+ }
412
+
413
+ void py_gsv_set_smallest_vectors_dense(
414
+ nb::ndarray<> py_smallest_vectors, nb::ndarray<> py_multiplicity,
415
+ nb::ndarray<> py_pos_to, nb::ndarray<> py_pos_from,
416
+ nb::ndarray<> py_lattice_points, nb::ndarray<> py_reduced_basis,
417
+ nb::ndarray<> py_trans_mat, int64_t initialize, double symprec) {
418
+ double (*smallest_vectors)[3];
419
+ int64_t (*multiplicity)[2];
420
+ double (*pos_to)[3];
421
+ double (*pos_from)[3];
422
+ int64_t (*lattice_points)[3];
423
+ double (*reduced_basis)[3];
424
+ int64_t (*trans_mat)[3];
425
+ int64_t num_pos_to, num_pos_from, num_lattice_points;
426
+
427
+ smallest_vectors = (double (*)[3])py_smallest_vectors.data();
428
+ multiplicity = (int64_t (*)[2])py_multiplicity.data();
429
+ pos_to = (double (*)[3])py_pos_to.data();
430
+ pos_from = (double (*)[3])py_pos_from.data();
431
+ num_pos_to = py_pos_to.shape(0);
432
+ num_pos_from = py_pos_from.shape(0);
433
+ lattice_points = (int64_t (*)[3])py_lattice_points.data();
434
+ num_lattice_points = py_lattice_points.shape(0);
435
+ reduced_basis = (double (*)[3])py_reduced_basis.data();
436
+ trans_mat = (int64_t (*)[3])py_trans_mat.data();
437
+
438
+ phpy_set_smallest_vectors_dense(
439
+ smallest_vectors, multiplicity, pos_to, num_pos_to, pos_from,
440
+ num_pos_from, lattice_points, num_lattice_points, reduced_basis,
441
+ trans_mat, initialize, symprec);
442
+ }
443
+
444
+ void py_thm_relative_grid_address(nb::ndarray<> py_relative_grid_address,
445
+ nb::ndarray<> py_reciprocal_lattice_py) {
446
+ int64_t (*relative_grid_address)[4][3];
447
+ double (*reciprocal_lattice)[3];
448
+
449
+ relative_grid_address = (int64_t (*)[4][3])py_relative_grid_address.data();
450
+ reciprocal_lattice = (double (*)[3])py_reciprocal_lattice_py.data();
451
+
452
+ phpy_get_relative_grid_address(relative_grid_address, reciprocal_lattice);
453
+ }
454
+
455
+ void py_thm_all_relative_grid_address(nb::ndarray<> py_relative_grid_address) {
456
+ int64_t (*relative_grid_address)[24][4][3];
457
+
458
+ relative_grid_address =
459
+ (int64_t (*)[24][4][3])py_relative_grid_address.data();
460
+
461
+ phpy_get_all_relative_grid_address(relative_grid_address);
462
+ }
463
+
464
+ double py_thm_integration_weight(double omega,
465
+ nb::ndarray<> py_tetrahedra_omegas,
466
+ const char *function) {
467
+ double (*tetrahedra_omegas)[4];
468
+ double iw;
469
+
470
+ tetrahedra_omegas = (double (*)[4])py_tetrahedra_omegas.data();
471
+
472
+ iw = phpy_get_integration_weight(omega, tetrahedra_omegas, function[0]);
473
+
474
+ return iw;
475
+ }
476
+
477
+ void py_thm_integration_weight_at_omegas(nb::ndarray<> py_integration_weights,
478
+ nb::ndarray<> py_omegas,
479
+ nb::ndarray<> py_tetrahedra_omegas,
480
+ const char *function) {
481
+ double *omegas;
482
+ double *iw;
483
+ int64_t num_omegas;
484
+ double (*tetrahedra_omegas)[4];
485
+
486
+ int64_t i;
487
+
488
+ omegas = (double *)py_omegas.data();
489
+ iw = (double *)py_integration_weights.data();
490
+ num_omegas = (int64_t)py_omegas.shape(0);
491
+ tetrahedra_omegas = (double (*)[4])py_tetrahedra_omegas.data();
492
+
493
+ #ifdef _OPENMP
494
+ #pragma omp parallel for
495
+ #endif
496
+ for (i = 0; i < num_omegas; i++) {
497
+ iw[i] = phpy_get_integration_weight(omegas[i], tetrahedra_omegas,
498
+ function[0]);
499
+ }
500
+ }
501
+
502
+ void py_get_tetrahedra_frequenies(nb::ndarray<> py_freq_tetras,
503
+ nb::ndarray<> py_grid_points,
504
+ nb::ndarray<> py_mesh,
505
+ nb::ndarray<> py_grid_address,
506
+ nb::ndarray<> py_gp_ir_index,
507
+ nb::ndarray<> py_relative_grid_address,
508
+ nb::ndarray<> py_frequencies) {
509
+ double *freq_tetras;
510
+ int64_t *grid_points;
511
+ int64_t *mesh;
512
+ int64_t (*grid_address)[3];
513
+ int64_t *gp_ir_index;
514
+ int64_t (*relative_grid_address)[3];
515
+ double *frequencies;
516
+
517
+ int64_t num_gp_in, num_band;
518
+
519
+ freq_tetras = (double *)py_freq_tetras.data();
520
+ grid_points = (int64_t *)py_grid_points.data();
521
+ num_gp_in = py_grid_points.shape(0);
522
+ mesh = (int64_t *)py_mesh.data();
523
+ grid_address = (int64_t (*)[3])py_grid_address.data();
524
+ gp_ir_index = (int64_t *)py_gp_ir_index.data();
525
+ relative_grid_address = (int64_t (*)[3])py_relative_grid_address.data();
526
+ frequencies = (double *)py_frequencies.data();
527
+ num_band = py_frequencies.shape(1);
528
+
529
+ phpy_get_tetrahedra_frequenies(freq_tetras, mesh, grid_points, grid_address,
530
+ relative_grid_address, gp_ir_index,
531
+ frequencies, num_band, num_gp_in);
532
+ }
533
+
534
+ void py_tetrahedron_method_dos(nb::ndarray<> py_dos, nb::ndarray<> py_mesh,
535
+ nb::ndarray<> py_freq_points,
536
+ nb::ndarray<> py_frequencies,
537
+ nb::ndarray<> py_coef,
538
+ nb::ndarray<> py_grid_address,
539
+ nb::ndarray<> py_grid_mapping_table,
540
+ nb::ndarray<> py_relative_grid_address) {
541
+ double *dos;
542
+ int64_t *mesh;
543
+ double *freq_points;
544
+ double *frequencies;
545
+ double *coef;
546
+ int64_t (*grid_address)[3];
547
+ int64_t num_gp, num_ir_gp, num_band, num_freq_points, num_coef;
548
+ int64_t *grid_mapping_table;
549
+ int64_t (*relative_grid_address)[4][3];
550
+
551
+ /* dos[num_ir_gp][num_band][num_freq_points][num_coef] */
552
+ dos = (double *)py_dos.data();
553
+ mesh = (int64_t *)py_mesh.data();
554
+ freq_points = (double *)py_freq_points.data();
555
+ num_freq_points = (int64_t)py_freq_points.shape(0);
556
+ frequencies = (double *)py_frequencies.data();
557
+ num_ir_gp = (int64_t)py_frequencies.shape(0);
558
+ num_band = (int64_t)py_frequencies.shape(1);
559
+ coef = (double *)py_coef.data();
560
+ num_coef = (int64_t)py_coef.shape(1);
561
+ grid_address = (int64_t (*)[3])py_grid_address.data();
562
+ num_gp = (int64_t)py_grid_address.shape(0);
563
+ grid_mapping_table = (int64_t *)py_grid_mapping_table.data();
564
+ relative_grid_address = (int64_t (*)[4][3])py_relative_grid_address.data();
565
+
566
+ phpy_tetrahedron_method_dos(dos, mesh, grid_address, relative_grid_address,
567
+ grid_mapping_table, freq_points, frequencies,
568
+ coef, num_freq_points, num_ir_gp, num_band,
569
+ num_coef, num_gp);
570
+ }
571
+
572
+ NB_MODULE(_phonopy, m) {
573
+ m.def("transform_dynmat_to_fc", &py_transform_dynmat_to_fc);
574
+ m.def("perm_trans_symmetrize_fc", &py_perm_trans_symmetrize_fc);
575
+ m.def("perm_trans_symmetrize_compact_fc",
576
+ &py_perm_trans_symmetrize_compact_fc);
577
+ m.def("transpose_compact_fc", &py_transpose_compact_fc);
578
+ m.def("dynamical_matrices_with_dd_openmp_over_qpoints",
579
+ &py_get_dynamical_matrices_with_dd_openmp_over_qpoints);
580
+ m.def("recip_dipole_dipole", &py_get_recip_dipole_dipole);
581
+ m.def("recip_dipole_dipole_q0", &py_get_recip_dipole_dipole_q0);
582
+ m.def("derivative_dynmat", &py_get_derivative_dynmat);
583
+ m.def("thermal_properties", &py_get_thermal_properties);
584
+ m.def("distribute_fc2", &py_distribute_fc2);
585
+ m.def("compute_permutation", &py_compute_permutation);
586
+ m.def("gsv_set_smallest_vectors_sparse",
587
+ &py_gsv_set_smallest_vectors_sparse);
588
+ m.def("gsv_set_smallest_vectors_dense", &py_gsv_set_smallest_vectors_dense);
589
+ m.def("tetrahedra_relative_grid_address", &py_thm_relative_grid_address);
590
+ m.def("all_tetrahedra_relative_grid_address",
591
+ &py_thm_all_relative_grid_address);
592
+ m.def("tetrahedra_integration_weight", &py_thm_integration_weight);
593
+ m.def("tetrahedra_integration_weight_at_omegas",
594
+ &py_thm_integration_weight_at_omegas);
595
+ m.def("tetrahedra_frequencies", &py_get_tetrahedra_frequenies);
596
+ m.def("tetrahedron_method_dos", &py_tetrahedron_method_dos);
597
+ m.def("use_openmp", &phpy_use_openmp);
598
+ m.def("omp_max_threads", &phpy_get_max_threads);
599
+ }
phonopy/source/c/derivative_dynmat.c ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2015 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file is part of phonopy. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the phonopy project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #include "derivative_dynmat.h"
36
+
37
+ #include <math.h>
38
+ #include <stdint.h>
39
+ #include <stdio.h>
40
+ #include <stdlib.h>
41
+
42
+ #define PI 3.14159265358979323846
43
+
44
+ static void get_derivative_dynmat_at_q(
45
+ double (*derivative_dynmat)[2], const int64_t i, const int64_t j,
46
+ const double *ddnac, const double *dnac, const int64_t is_nac,
47
+ const int64_t num_patom, const int64_t num_satom, const double *fc,
48
+ const double *q, const double *lattice, /* column vector */
49
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
50
+ const int64_t *s2p_map, const int64_t *p2s_map);
51
+ static void get_derivative_nac(double *ddnac, double *dnac,
52
+ const int64_t num_patom, const double *lattice,
53
+ const double *mass, const double *q,
54
+ const double *born, const double *dielectric,
55
+ const double *q_direction, const double factor);
56
+ static double get_A(const int64_t atom_i, const int64_t cart_i,
57
+ const double q[3], const double *born);
58
+ static double get_C(const double q[3], const double *dielectric);
59
+ static double get_dA(const int64_t atom_i, const int64_t cart_i,
60
+ const int64_t cart_j, const double *born);
61
+ static double get_dC(const int64_t cart_i, const int64_t cart_j,
62
+ const int64_t cart_k, const double q[3],
63
+ const double *dielectric);
64
+
65
+ void ddm_get_derivative_dynmat_at_q(
66
+ double (*derivative_dynmat)[2], const int64_t num_patom,
67
+ const int64_t num_satom, const double *fc, const double *q,
68
+ const double *lattice, /* column vector */
69
+ const double *reclat, /* column vector */
70
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
71
+ const int64_t *s2p_map, const int64_t *p2s_map, const double nac_factor,
72
+ const double *born, const double *dielectric, const double *q_direction,
73
+ const int64_t is_nac, const int64_t use_openmp) {
74
+ int64_t i, j, k, ij, adrs, adrsT;
75
+ double factor;
76
+ double *ddnac, *dnac;
77
+
78
+ if (is_nac) {
79
+ ddnac = (double *)malloc(sizeof(double) * num_patom * num_patom * 27);
80
+ dnac = (double *)malloc(sizeof(double) * num_patom * num_patom * 9);
81
+ factor = (nac_factor * num_patom) / num_satom;
82
+ get_derivative_nac(ddnac, dnac, num_patom, reclat, mass, q, born,
83
+ dielectric, q_direction, factor);
84
+ }
85
+
86
+ if (use_openmp) {
87
+ #ifdef _OPENMP
88
+ #pragma omp parallel for private(i, j)
89
+ #endif
90
+ for (ij = 0; ij < num_patom * num_patom; ij++) {
91
+ i = ij / num_patom;
92
+ j = ij % num_patom;
93
+ get_derivative_dynmat_at_q(derivative_dynmat, i, j, ddnac, dnac,
94
+ is_nac, num_patom, num_satom, fc, q,
95
+ lattice, svecs, multi, mass, s2p_map,
96
+ p2s_map);
97
+ }
98
+ } else {
99
+ for (i = 0; i < num_patom; i++) {
100
+ for (j = 0; j < num_patom; j++) {
101
+ get_derivative_dynmat_at_q(derivative_dynmat, i, j, ddnac, dnac,
102
+ is_nac, num_patom, num_satom, fc, q,
103
+ lattice, svecs, multi, mass, s2p_map,
104
+ p2s_map);
105
+ }
106
+ }
107
+ }
108
+
109
+ /* Symmetrize to be a Hermitian matrix */
110
+ for (i = 0; i < 3; i++) {
111
+ for (j = i; j < num_patom * 3; j++) {
112
+ for (k = 0; k < num_patom * 3; k++) {
113
+ adrs = i * num_patom * num_patom * 9 + j * num_patom * 3 + k;
114
+ adrsT = i * num_patom * num_patom * 9 + k * num_patom * 3 + j;
115
+ derivative_dynmat[adrs][0] += derivative_dynmat[adrsT][0];
116
+ derivative_dynmat[adrs][0] /= 2;
117
+ derivative_dynmat[adrs][1] -= derivative_dynmat[adrsT][1];
118
+ derivative_dynmat[adrs][1] /= 2;
119
+ derivative_dynmat[adrsT][0] = derivative_dynmat[adrs][0];
120
+ derivative_dynmat[adrsT][1] = -derivative_dynmat[adrs][1];
121
+ }
122
+ }
123
+ }
124
+
125
+ if (is_nac) {
126
+ free(ddnac);
127
+ ddnac = NULL;
128
+ free(dnac);
129
+ dnac = NULL;
130
+ }
131
+ }
132
+
133
+ void get_derivative_dynmat_at_q(
134
+ double (*derivative_dynmat)[2], const int64_t i, const int64_t j,
135
+ const double *ddnac, const double *dnac, const int64_t is_nac,
136
+ const int64_t num_patom, const int64_t num_satom, const double *fc,
137
+ const double *q, const double *lattice, /* column vector */
138
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
139
+ const int64_t *s2p_map, const int64_t *p2s_map) {
140
+ int64_t k, l, m, n, adrs, m_pair, i_pair, svecs_adrs;
141
+ double coef[3], real_coef[3], imag_coef[3];
142
+ double c, s, phase, mass_sqrt, fc_elem, real_phase, imag_phase;
143
+ double ddm_real[3][3][3], ddm_imag[3][3][3];
144
+
145
+ mass_sqrt = sqrt(mass[i] * mass[j]);
146
+
147
+ for (k = 0; k < 3; k++) {
148
+ for (l = 0; l < 3; l++) {
149
+ for (m = 0; m < 3; m++) {
150
+ ddm_real[m][k][l] = 0;
151
+ ddm_imag[m][k][l] = 0;
152
+ }
153
+ }
154
+ }
155
+
156
+ for (k = 0; k < num_satom; k++) { /* Lattice points of right index of fc */
157
+ if (s2p_map[k] != p2s_map[j]) {
158
+ continue;
159
+ }
160
+
161
+ real_phase = 0;
162
+ imag_phase = 0;
163
+ for (l = 0; l < 3; l++) {
164
+ real_coef[l] = 0;
165
+ imag_coef[l] = 0;
166
+ }
167
+ i_pair = k * num_patom + i;
168
+ m_pair = multi[i_pair][0];
169
+ svecs_adrs = multi[i_pair][1];
170
+ for (l = 0; l < m_pair; l++) {
171
+ phase = 0;
172
+ for (m = 0; m < 3; m++) {
173
+ phase += q[m] * svecs[svecs_adrs + l][m];
174
+ }
175
+ s = sin(phase * 2 * PI);
176
+ c = cos(phase * 2 * PI);
177
+
178
+ real_phase += c;
179
+ imag_phase += s;
180
+
181
+ for (m = 0; m < 3; m++) {
182
+ coef[m] = 0;
183
+ for (n = 0; n < 3; n++) {
184
+ coef[m] +=
185
+ 2 * PI * lattice[m * 3 + n] * svecs[svecs_adrs + l][n];
186
+ }
187
+ }
188
+
189
+ for (m = 0; m < 3; m++) {
190
+ real_coef[m] -= coef[m] * s;
191
+ imag_coef[m] += coef[m] * c;
192
+ }
193
+ }
194
+
195
+ real_phase /= m_pair;
196
+ imag_phase /= m_pair;
197
+
198
+ for (l = 0; l < 3; l++) {
199
+ real_coef[l] /= m_pair;
200
+ imag_coef[l] /= m_pair;
201
+ }
202
+
203
+ for (l = 0; l < 3; l++) {
204
+ for (m = 0; m < 3; m++) {
205
+ fc_elem = fc[p2s_map[i] * num_satom * 9 + k * 9 + l * 3 + m] /
206
+ mass_sqrt;
207
+ if (is_nac) {
208
+ fc_elem += dnac[i * 9 * num_patom + j * 9 + l * 3 + m];
209
+ }
210
+ for (n = 0; n < 3; n++) {
211
+ ddm_real[n][l][m] += fc_elem * real_coef[n];
212
+ ddm_imag[n][l][m] += fc_elem * imag_coef[n];
213
+ if (is_nac) {
214
+ ddm_real[n][l][m] +=
215
+ ddnac[n * num_patom * num_patom * 9 +
216
+ i * 9 * num_patom + j * 9 + l * 3 + m] *
217
+ real_phase;
218
+ ddm_imag[n][l][m] +=
219
+ ddnac[n * num_patom * num_patom * 9 +
220
+ i * 9 * num_patom + j * 9 + l * 3 + m] *
221
+ imag_phase;
222
+ }
223
+ }
224
+ }
225
+ }
226
+ }
227
+
228
+ for (k = 0; k < 3; k++) {
229
+ for (l = 0; l < 3; l++) {
230
+ for (m = 0; m < 3; m++) {
231
+ adrs = (k * num_patom * num_patom * 9 +
232
+ (i * 3 + l) * num_patom * 3 + j * 3 + m * 1);
233
+ derivative_dynmat[adrs][0] += ddm_real[k][l][m];
234
+ derivative_dynmat[adrs][1] += ddm_imag[k][l][m];
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ /* D_nac = a * AB/C */
241
+ /* dD_nac = a * D_nac * (A'/A + B'/B - C'/C) */
242
+ static void get_derivative_nac(double *ddnac, double *dnac,
243
+ const int64_t num_patom, const double *reclat,
244
+ const double *mass, const double *q,
245
+ const double *born, const double *dielectric,
246
+ const double *q_direction, const double factor) {
247
+ int64_t i, j, k, l, m;
248
+ double a, b, c, da, db, dc, mass_sqrt;
249
+ double q_cart[3];
250
+
251
+ for (i = 0; i < 3; i++) {
252
+ q_cart[i] = 0;
253
+ for (j = 0; j < 3; j++) {
254
+ if (q_direction) {
255
+ q_cart[i] += reclat[i * 3 + j] * q_direction[j];
256
+ } else {
257
+ q_cart[i] += reclat[i * 3 + j] * q[j];
258
+ }
259
+ }
260
+ }
261
+
262
+ c = get_C(q_cart, dielectric);
263
+
264
+ for (i = 0; i < num_patom; i++) { /* atom_i */
265
+ for (j = 0; j < num_patom; j++) { /* atom_j */
266
+ mass_sqrt = sqrt(mass[i] * mass[j]);
267
+ for (k = 0; k < 3; k++) { /* derivative direction */
268
+ for (l = 0; l < 3; l++) { /* alpha */
269
+ a = get_A(i, l, q_cart, born);
270
+ da = get_dA(i, l, k, born);
271
+ for (m = 0; m < 3; m++) { /* beta */
272
+ b = get_A(j, m, q_cart, born);
273
+ db = get_dA(j, m, k, born);
274
+ dc = get_dC(l, m, k, q_cart, dielectric);
275
+ ddnac[k * num_patom * num_patom * 9 +
276
+ i * 9 * num_patom + j * 9 + l * 3 + m] =
277
+ (da * b + db * a - a * b * dc / c) /
278
+ (c * mass_sqrt) * factor;
279
+ if (k == 0) {
280
+ dnac[i * 9 * num_patom + j * 9 + l * 3 + m] =
281
+ a * b / (c * mass_sqrt) * factor;
282
+ }
283
+ }
284
+ }
285
+ }
286
+ }
287
+ }
288
+ }
289
+
290
+ static double get_A(const int64_t atom_i, const int64_t cart_i,
291
+ const double q[3], const double *born) {
292
+ int64_t i;
293
+ double sum;
294
+
295
+ sum = 0;
296
+ for (i = 0; i < 3; i++) {
297
+ sum += q[i] * born[atom_i * 9 + i * 3 + cart_i];
298
+ }
299
+
300
+ return sum;
301
+ }
302
+
303
+ static double get_C(const double q[3], const double *dielectric) {
304
+ int64_t i, j;
305
+ double sum;
306
+
307
+ sum = 0;
308
+ for (i = 0; i < 3; i++) {
309
+ for (j = 0; j < 3; j++) {
310
+ sum += q[i] * dielectric[i * 3 + j] * q[j];
311
+ }
312
+ }
313
+
314
+ return sum;
315
+ }
316
+
317
+ static double get_dA(const int64_t atom_i, const int64_t cart_i,
318
+ const int64_t cart_j, const double *born) {
319
+ return born[atom_i * 9 + cart_j * 3 + cart_i];
320
+ }
321
+
322
+ static double get_dC(const int64_t cart_i, const int64_t cart_j,
323
+ const int64_t cart_k, const double q[3],
324
+ const double *dielectric) {
325
+ if (cart_k == 0) {
326
+ return (2 * q[0] * dielectric[0] +
327
+ q[1] * (dielectric[1] + dielectric[3]) +
328
+ q[2] * (dielectric[2] + dielectric[6]));
329
+ }
330
+ if (cart_k == 1) {
331
+ return (2 * q[1] * dielectric[4] +
332
+ q[2] * (dielectric[5] + dielectric[7]) +
333
+ q[0] * (dielectric[1] + dielectric[3]));
334
+ }
335
+ if (cart_k == 2) {
336
+ return (2 * q[2] * dielectric[8] +
337
+ q[0] * (dielectric[2] + dielectric[6]) +
338
+ q[1] * (dielectric[5] + dielectric[7]));
339
+ }
340
+ return 0;
341
+ }
phonopy/source/c/derivative_dynmat.h ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2015 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file is part of phonopy. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the phonopy project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #ifndef __derivative_dynmat_H__
36
+ #define __derivative_dynmat_H__
37
+
38
+ #include <stdint.h>
39
+
40
+ void ddm_get_derivative_dynmat_at_q(
41
+ double (*derivative_dynmat)[2], const int64_t num_patom,
42
+ const int64_t num_satom, const double *fc, const double *q,
43
+ const double *lattice, /* column vector */
44
+ const double *reclat, /* column vector */
45
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
46
+ const int64_t *s2p_map, const int64_t *p2s_map, const double nac_factor,
47
+ const double *born, const double *dielectric, const double *q_direction,
48
+ const int64_t is_nac, const int64_t use_openmp);
49
+
50
+ #endif
phonopy/source/c/dynmat.c ADDED
@@ -0,0 +1,822 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2015 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file is part of phonopy. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the phonopy project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #include "dynmat.h"
36
+
37
+ #include <math.h>
38
+ #include <stdint.h>
39
+ #include <stdlib.h>
40
+
41
+ #define PI 3.14159265358979323846
42
+
43
+ static int64_t get_dynamical_matrix_at_q(
44
+ double (*dynamical_matrix)[2], const int64_t num_patom,
45
+ const int64_t num_satom, const double *fc, const double q[3],
46
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
47
+ const int64_t *s2p_map, const int64_t *p2s_map,
48
+ const double (*charge_sum)[3][3], const int64_t hermitianize,
49
+ const int64_t use_openmp);
50
+ static void add_dynmat_dd_at_q(
51
+ double (*dynamical_matrices)[2], const double q[3], const double *fc,
52
+ const double (*positions)[3], const int64_t num_patom, const double *masses,
53
+ const double (*born)[3][3], const double dielectric[3][3],
54
+ const double reciprocal_lattice[3][3], const double *q_dir_cart,
55
+ const double nac_factor, const double (*dd_q0)[2],
56
+ const double (*G_list)[3], const int64_t num_G_points, const double lambda,
57
+ const double tolerance);
58
+ static void get_dynmat_ij(double (*dynamical_matrix)[2],
59
+ const int64_t num_patom, const int64_t num_satom,
60
+ const double *fc, const double q[3],
61
+ const double (*svecs)[3], const int64_t (*multi)[2],
62
+ const double *mass, const int64_t *s2p_map,
63
+ const int64_t *p2s_map,
64
+ const double (*charge_sum)[3][3], const int64_t i,
65
+ const int64_t j);
66
+ static void get_dm(double dm[3][3][2], const int64_t num_patom,
67
+ const int64_t num_satom, const double *fc, const double q[3],
68
+ const double (*svecs)[3], const int64_t (*multi)[2],
69
+ const int64_t *p2s_map, const double (*charge_sum)[3][3],
70
+ const int64_t i, const int64_t j, const int64_t k);
71
+ static double get_dielectric_part(const double q_cart[3],
72
+ const double dielectric[3][3]);
73
+ static void get_dd(double (*dd_part)[2], /* [natom, 3, natom, 3, (real,imag)] */
74
+ const double (*G_list)[3], /* [num_G, 3] */
75
+ const int64_t num_G, const int64_t num_patom,
76
+ const double q_cart[3], const double *q_direction_cart,
77
+ const double dielectric[3][3],
78
+ const double (*pos)[3], /* [num_patom, 3] */
79
+ const double lambda, const double tolerance,
80
+ const int64_t use_openmp);
81
+ static void get_dd_at_g(
82
+ double (*dd_part)[2], /* [natom, 3, natom, 3, (real,imag)] */
83
+ const int64_t i, const int64_t j, const double G[3],
84
+ const int64_t num_patom, const double (*pos)[3], /* [num_patom, 3] */
85
+ const double KK[3][3]);
86
+ static void make_Hermitian(double (*mat)[2], const int64_t num_band);
87
+ static void multiply_borns(double (*dd)[2], const double (*dd_in)[2],
88
+ const int64_t num_patom, const double (*born)[3][3],
89
+ const int64_t use_openmp);
90
+ static void multiply_borns_at_ij(double (*dd)[2], const int64_t i,
91
+ const int64_t j, const double (*dd_in)[2],
92
+ const int64_t num_patom,
93
+ const double (*born)[3][3]);
94
+ static void transform_dynmat_to_fc_ij(
95
+ double *fc, const double (*dm)[2], const int64_t i, const int64_t j,
96
+ const double (*comm_points)[3], const double (*svecs)[3],
97
+ const int64_t (*multi)[2], const double *masses, const int64_t *s2pp_map,
98
+ const int64_t *fc_index_map, const int64_t num_patom,
99
+ const int64_t num_satom);
100
+ static void get_q_cart(double q_cart[3], const double q[3],
101
+ const double reciprocal_lattice[3][3]);
102
+ static void get_dynmat_wang(
103
+ double (*dynamical_matrices)[2], const double qpoint[3], const double *fc,
104
+ const double (*svecs)[3], const int64_t (*multi)[2],
105
+ const int64_t num_patom, const int64_t num_satom, const double *masses,
106
+ const int64_t *p2s_map, const int64_t *s2p_map, const double (*born)[3][3],
107
+ const double dielectric[3][3], const double (*reciprocal_lattice)[3],
108
+ const double *q_direction, const double *q_dir_cart,
109
+ const double nac_factor, const double q_zero_tolerance,
110
+ const int64_t hermitianize);
111
+
112
+ /// @brief Calculate dynamical matrices with openmp over q-points
113
+ /// use_Wang_NAC: Wang et al.
114
+ /// !use_Wang_NAC and dd_0 is NULL: no-NAC
115
+ /// !use_Wang_NAC and dd_0 is not NULL: NAC by Gonze and Lee.
116
+ /// @param reciprocal_lattice in column vectors
117
+ /// @param q_direction in Crystallographic coordinates.
118
+ int64_t dym_dynamical_matrices_with_dd_openmp_over_qpoints(
119
+ double (*dynamical_matrices)[2], const double (*qpoints)[3],
120
+ const int64_t n_qpoints, const double *fc, const double (*svecs)[3],
121
+ const int64_t (*multi)[2], const double (*positions)[3],
122
+ const int64_t num_patom, const int64_t num_satom, const double *masses,
123
+ const int64_t *p2s_map, const int64_t *s2p_map, const double (*born)[3][3],
124
+ const double dielectric[3][3], const double (*reciprocal_lattice)[3],
125
+ const double *q_direction, const double nac_factor,
126
+ const double (*dd_q0)[2], const double (*G_list)[3],
127
+ const int64_t num_G_points, const double lambda, const int64_t use_Wang_NAC,
128
+ const int64_t hermitianize) {
129
+ int64_t i, n, adrs_shift;
130
+ double *q_dir_cart;
131
+ double q_zero_tolerance;
132
+
133
+ q_zero_tolerance = 1e-5;
134
+ q_dir_cart = NULL;
135
+ adrs_shift = num_patom * num_patom * 9;
136
+
137
+ if (q_direction) {
138
+ q_dir_cart = (double *)malloc(sizeof(double) * 3);
139
+ get_q_cart(q_dir_cart, q_direction, reciprocal_lattice);
140
+ }
141
+
142
+ if (use_Wang_NAC) {
143
+ #ifdef _OPENMP
144
+ #pragma omp parallel for
145
+ #endif
146
+ for (i = 0; i < n_qpoints; i++) {
147
+ get_dynmat_wang(dynamical_matrices + adrs_shift * i, qpoints[i], fc,
148
+ svecs, multi, num_patom, num_satom, masses, p2s_map,
149
+ s2p_map, born, dielectric, reciprocal_lattice,
150
+ q_direction, q_dir_cart, nac_factor,
151
+ q_zero_tolerance, hermitianize);
152
+ }
153
+ } else {
154
+ #ifdef _OPENMP
155
+ #pragma omp parallel for
156
+ #endif
157
+ for (i = 0; i < n_qpoints; i++) {
158
+ get_dynamical_matrix_at_q(dynamical_matrices + adrs_shift * i,
159
+ num_patom, num_satom, fc, qpoints[i],
160
+ svecs, multi, masses, s2p_map, p2s_map,
161
+ NULL, hermitianize, 0);
162
+ if (dd_q0) { // NAC by Gonze and Lee if dd_in is not NULL
163
+ add_dynmat_dd_at_q(dynamical_matrices + adrs_shift * i,
164
+ qpoints[i], fc, positions, num_patom, masses,
165
+ born, dielectric, reciprocal_lattice,
166
+ q_dir_cart, nac_factor, dd_q0, G_list,
167
+ num_G_points, lambda, q_zero_tolerance);
168
+ }
169
+ }
170
+ }
171
+
172
+ if (q_direction) {
173
+ free(q_dir_cart);
174
+ q_dir_cart = NULL;
175
+ }
176
+ return 0;
177
+ }
178
+
179
+ static void get_dynmat_wang(
180
+ double (*dynamical_matrices)[2], const double qpoint[3], const double *fc,
181
+ const double (*svecs)[3], const int64_t (*multi)[2],
182
+ const int64_t num_patom, const int64_t num_satom, const double *masses,
183
+ const int64_t *p2s_map, const int64_t *s2p_map, const double (*born)[3][3],
184
+ const double dielectric[3][3], const double (*reciprocal_lattice)[3],
185
+ const double *q_direction, const double *q_dir_cart,
186
+ const double nac_factor, const double q_zero_tolerance,
187
+ const int64_t hermitianize) {
188
+ double (*charge_sum)[3][3];
189
+ double q_cart[3];
190
+ double q_norm;
191
+ int64_t n;
192
+
193
+ charge_sum = NULL;
194
+ n = num_satom / num_patom;
195
+
196
+ get_q_cart(q_cart, qpoint, reciprocal_lattice);
197
+ q_norm = sqrt(q_cart[0] * q_cart[0] + q_cart[1] * q_cart[1] +
198
+ q_cart[2] * q_cart[2]);
199
+ charge_sum =
200
+ (double (*)[3][3])malloc(sizeof(double[3][3]) * num_patom * num_patom);
201
+
202
+ if (q_norm < q_zero_tolerance) {
203
+ if (q_direction) {
204
+ dym_get_charge_sum(
205
+ charge_sum, num_patom,
206
+ nac_factor / n / get_dielectric_part(q_dir_cart, dielectric),
207
+ q_dir_cart, born);
208
+ get_dynamical_matrix_at_q(dynamical_matrices, num_patom, num_satom,
209
+ fc, qpoint, svecs, multi, masses, s2p_map,
210
+ p2s_map, charge_sum, hermitianize, 0);
211
+
212
+ } else {
213
+ get_dynamical_matrix_at_q(dynamical_matrices, num_patom, num_satom,
214
+ fc, qpoint, svecs, multi, masses, s2p_map,
215
+ p2s_map, NULL, hermitianize, 0);
216
+ }
217
+ } else {
218
+ dym_get_charge_sum(
219
+ charge_sum, num_patom,
220
+ nac_factor / n / get_dielectric_part(q_cart, dielectric), q_cart,
221
+ born);
222
+ get_dynamical_matrix_at_q(dynamical_matrices, num_patom, num_satom, fc,
223
+ qpoint, svecs, multi, masses, s2p_map,
224
+ p2s_map, charge_sum, hermitianize, 0);
225
+ }
226
+
227
+ free(charge_sum);
228
+ charge_sum = NULL;
229
+ }
230
+
231
+ static void add_dynmat_dd_at_q(
232
+ double (*dynamical_matrices)[2], const double q[3], const double *fc,
233
+ const double (*positions)[3], const int64_t num_patom, const double *masses,
234
+ const double (*born)[3][3], const double dielectric[3][3],
235
+ const double reciprocal_lattice[3][3], const double *q_dir_cart,
236
+ const double nac_factor, const double (*dd_q0)[2],
237
+ const double (*G_list)[3], const int64_t num_G_points, const double lambda,
238
+ const double tolerance) {
239
+ int64_t i, j, k, l, adrs;
240
+ double (*dd)[2];
241
+ double q_cart[3];
242
+ double mm;
243
+
244
+ dd = (double (*)[2])malloc(sizeof(double[2]) * num_patom * num_patom * 9);
245
+ get_q_cart(q_cart, q, reciprocal_lattice);
246
+ dym_get_recip_dipole_dipole(dd, dd_q0, G_list, num_G_points, num_patom,
247
+ q_cart, q_dir_cart, born, dielectric, positions,
248
+ nac_factor, lambda, tolerance, 0);
249
+
250
+ for (i = 0; i < num_patom; i++) {
251
+ for (j = 0; j < num_patom; j++) {
252
+ mm = sqrt(masses[i] * masses[j]);
253
+ for (k = 0; k < 3; k++) {
254
+ for (l = 0; l < 3; l++) {
255
+ adrs = i * num_patom * 9 + k * num_patom * 3 + j * 3 + l;
256
+ dynamical_matrices[adrs][0] += dd[adrs][0] / mm;
257
+ dynamical_matrices[adrs][1] += dd[adrs][1] / mm;
258
+ }
259
+ }
260
+ }
261
+ }
262
+
263
+ free(dd);
264
+ dd = NULL;
265
+ }
266
+
267
+ void dym_get_recip_dipole_dipole(
268
+ double (*dd)[2], /* [natom, 3, natom, 3, (real,imag)] */
269
+ const double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
270
+ const double (*G_list)[3], /* [num_G, 3] */
271
+ const int64_t num_G, const int64_t num_patom, const double q_cart[3],
272
+ const double *q_direction_cart, /* must be pointer */
273
+ const double (*born)[3][3], const double dielectric[3][3],
274
+ const double (*pos)[3], /* [num_patom, 3] */
275
+ const double factor, /* 4pi/V*unit-conv */
276
+ const double lambda, const double tolerance, const int64_t use_openmp) {
277
+ int64_t i, k, l, adrs, adrs_sum;
278
+ double (*dd_tmp)[2];
279
+
280
+ dd_tmp =
281
+ (double (*)[2])malloc(sizeof(double[2]) * num_patom * num_patom * 9);
282
+
283
+ for (i = 0; i < num_patom * num_patom * 9; i++) {
284
+ dd[i][0] = 0;
285
+ dd[i][1] = 0;
286
+ dd_tmp[i][0] = 0;
287
+ dd_tmp[i][1] = 0;
288
+ }
289
+
290
+ get_dd(dd_tmp, G_list, num_G, num_patom, q_cart, q_direction_cart,
291
+ dielectric, pos, lambda, tolerance, use_openmp);
292
+
293
+ multiply_borns(dd, dd_tmp, num_patom, born, use_openmp);
294
+
295
+ for (i = 0; i < num_patom; i++) {
296
+ for (k = 0; k < 3; k++) { /* alpha */
297
+ for (l = 0; l < 3; l++) { /* beta */
298
+ adrs = i * num_patom * 9 + k * num_patom * 3 + i * 3 + l;
299
+ adrs_sum = i * 9 + k * 3 + l;
300
+ dd[adrs][0] -= dd_q0[adrs_sum][0];
301
+ dd[adrs][1] -= dd_q0[adrs_sum][1];
302
+ }
303
+ }
304
+ }
305
+
306
+ for (i = 0; i < num_patom * num_patom * 9; i++) {
307
+ dd[i][0] *= factor;
308
+ dd[i][1] *= factor;
309
+ }
310
+
311
+ /* This may not be necessary. */
312
+ /* make_Hermitian(dd, num_patom * 3); */
313
+
314
+ free(dd_tmp);
315
+ dd_tmp = NULL;
316
+ }
317
+
318
+ void dym_get_recip_dipole_dipole_q0(
319
+ double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
320
+ const double (*G_list)[3], /* [num_G, 3] */
321
+ const int64_t num_G, const int64_t num_patom, const double (*born)[3][3],
322
+ const double dielectric[3][3], const double (*pos)[3], /* [num_patom, 3] */
323
+ const double lambda, const double tolerance, const int64_t use_openmp) {
324
+ int64_t i, j, k, l, adrs_tmp, adrs, adrsT;
325
+ double zero_vec[3];
326
+ double (*dd_tmp1)[2], (*dd_tmp2)[2];
327
+
328
+ dd_tmp1 =
329
+ (double (*)[2])malloc(sizeof(double[2]) * num_patom * num_patom * 9);
330
+ dd_tmp2 =
331
+ (double (*)[2])malloc(sizeof(double[2]) * num_patom * num_patom * 9);
332
+
333
+ for (i = 0; i < num_patom * num_patom * 9; i++) {
334
+ dd_tmp1[i][0] = 0;
335
+ dd_tmp1[i][1] = 0;
336
+ dd_tmp2[i][0] = 0;
337
+ dd_tmp2[i][1] = 0;
338
+ }
339
+
340
+ zero_vec[0] = 0;
341
+ zero_vec[1] = 0;
342
+ zero_vec[2] = 0;
343
+
344
+ get_dd(dd_tmp1, G_list, num_G, num_patom, zero_vec, NULL, dielectric, pos,
345
+ lambda, tolerance, use_openmp);
346
+
347
+ multiply_borns(dd_tmp2, dd_tmp1, num_patom, born, use_openmp);
348
+
349
+ for (i = 0; i < num_patom * 9; i++) {
350
+ dd_q0[i][0] = 0;
351
+ dd_q0[i][1] = 0;
352
+ }
353
+
354
+ for (i = 0; i < num_patom; i++) {
355
+ for (k = 0; k < 3; k++) { /* alpha */
356
+ for (l = 0; l < 3; l++) { /* beta */
357
+ adrs = i * 9 + k * 3 + l;
358
+ for (j = 0; j < num_patom; j++) {
359
+ adrs_tmp =
360
+ i * num_patom * 9 + k * num_patom * 3 + j * 3 + l;
361
+ dd_q0[adrs][0] += dd_tmp2[adrs_tmp][0];
362
+ dd_q0[adrs][1] += dd_tmp2[adrs_tmp][1];
363
+ }
364
+ }
365
+ }
366
+ }
367
+
368
+ /* Summation over another atomic index */
369
+ /* for (j = 0; j < num_patom; j++) { */
370
+ /* for (k = 0; k < 3; k++) { /\* alpha *\/ */
371
+ /* for (l = 0; l < 3; l++) { /\* beta *\/ */
372
+ /* adrs = j * 9 + k * 3 + l; */
373
+ /* for (i = 0; i < num_patom; i++) { */
374
+ /* adrs_tmp = i * num_patom * 9 + k * num_patom * 3 + j * 3 + l
375
+ * ; */
376
+ /* dd_q0[adrs][0] += dd_tmp2[adrs_tmp][0]; */
377
+ /* dd_q0[adrs][1] += dd_tmp2[adrs_tmp][1]; */
378
+ /* } */
379
+ /* } */
380
+ /* } */
381
+ /* } */
382
+
383
+ for (i = 0; i < num_patom; i++) {
384
+ for (k = 0; k < 3; k++) { /* alpha */
385
+ for (l = 0; l < 3; l++) { /* beta */
386
+ adrs = i * 9 + k * 3 + l;
387
+ adrsT = i * 9 + l * 3 + k;
388
+ dd_q0[adrs][0] += dd_q0[adrsT][0];
389
+ dd_q0[adrs][0] /= 2;
390
+ dd_q0[adrsT][0] = dd_q0[adrs][0];
391
+ dd_q0[adrs][1] -= dd_q0[adrsT][1];
392
+ dd_q0[adrs][1] /= 2;
393
+ dd_q0[adrsT][1] = -dd_q0[adrs][1];
394
+ }
395
+ }
396
+ }
397
+
398
+ free(dd_tmp1);
399
+ dd_tmp1 = NULL;
400
+ free(dd_tmp2);
401
+ dd_tmp2 = NULL;
402
+ }
403
+
404
+ void dym_get_charge_sum(
405
+ double (*charge_sum)[3][3], const int64_t num_patom,
406
+ const double factor, /* 4pi/V*unit-conv and denominator */
407
+ const double q_cart[3], const double (*born)[3][3]) {
408
+ int64_t i, j, k, a, b;
409
+ double (*q_born)[3];
410
+
411
+ q_born = (double (*)[3])malloc(sizeof(double[3]) * num_patom);
412
+ for (i = 0; i < num_patom; i++) {
413
+ for (j = 0; j < 3; j++) {
414
+ q_born[i][j] = 0;
415
+ }
416
+ }
417
+
418
+ for (i = 0; i < num_patom; i++) {
419
+ for (j = 0; j < 3; j++) {
420
+ for (k = 0; k < 3; k++) {
421
+ q_born[i][j] += q_cart[k] * born[i][k][j];
422
+ }
423
+ }
424
+ }
425
+
426
+ for (i = 0; i < num_patom; i++) {
427
+ for (j = 0; j < num_patom; j++) {
428
+ for (a = 0; a < 3; a++) {
429
+ for (b = 0; b < 3; b++) {
430
+ charge_sum[i * num_patom + j][a][b] =
431
+ q_born[i][a] * q_born[j][b] * factor;
432
+ }
433
+ }
434
+ }
435
+ }
436
+
437
+ free(q_born);
438
+ q_born = NULL;
439
+ }
440
+
441
+ /* fc[num_patom, num_satom, 3, 3] */
442
+ /* dm[num_comm_points, num_patom * 3, num_patom *3] */
443
+ /* comm_points[num_satom / num_patom, 3] */
444
+ /* shortest_vectors[:, 3] */
445
+ /* multiplicities[num_satom, num_patom, 2] */
446
+ void dym_transform_dynmat_to_fc(
447
+ double *fc, const double (*dm)[2], const double (*comm_points)[3],
448
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *masses,
449
+ const int64_t *s2pp_map, const int64_t *fc_index_map,
450
+ const int64_t num_patom, const int64_t num_satom,
451
+ const int64_t use_openmp) {
452
+ int64_t i, j, ij;
453
+
454
+ for (i = 0; i < num_patom * num_satom * 9; i++) {
455
+ fc[i] = 0;
456
+ }
457
+
458
+ if (use_openmp) {
459
+ #ifdef _OPENMP
460
+ #pragma omp parallel for
461
+ #endif
462
+ for (ij = 0; ij < num_patom * num_satom; ij++) {
463
+ transform_dynmat_to_fc_ij(
464
+ fc, dm, ij / num_satom, ij % num_satom, comm_points, svecs,
465
+ multi, masses, s2pp_map, fc_index_map, num_patom, num_satom);
466
+ }
467
+ } else {
468
+ for (i = 0; i < num_patom; i++) {
469
+ for (j = 0; j < num_satom; j++) {
470
+ transform_dynmat_to_fc_ij(fc, dm, i, j, comm_points, svecs,
471
+ multi, masses, s2pp_map, fc_index_map,
472
+ num_patom, num_satom);
473
+ }
474
+ }
475
+ }
476
+ }
477
+
478
+ /// @brief charge_sum is NULL if G-L NAC or no-NAC.
479
+ static int64_t get_dynamical_matrix_at_q(
480
+ double (*dynamical_matrix)[2], const int64_t num_patom,
481
+ const int64_t num_satom, const double *fc, const double q[3],
482
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
483
+ const int64_t *s2p_map, const int64_t *p2s_map,
484
+ const double (*charge_sum)[3][3], const int64_t hermitianize,
485
+ const int64_t use_openmp) {
486
+ int64_t i, j, ij;
487
+
488
+ if (use_openmp) {
489
+ #ifdef _OPENMP
490
+ #pragma omp parallel for
491
+ #endif
492
+ for (ij = 0; ij < num_patom * num_patom; ij++) {
493
+ get_dynmat_ij(dynamical_matrix, num_patom, num_satom, fc, q, svecs,
494
+ multi, mass, s2p_map, p2s_map, charge_sum,
495
+ ij / num_patom, /* i */
496
+ ij % num_patom); /* j */
497
+ }
498
+ } else {
499
+ for (i = 0; i < num_patom; i++) {
500
+ for (j = 0; j < num_patom; j++) {
501
+ get_dynmat_ij(dynamical_matrix, num_patom, num_satom, fc, q,
502
+ svecs, multi, mass, s2p_map, p2s_map, charge_sum,
503
+ i, j);
504
+ }
505
+ }
506
+ }
507
+
508
+ if (hermitianize) {
509
+ make_Hermitian(dynamical_matrix, num_patom * 3);
510
+ }
511
+
512
+ return 0;
513
+ }
514
+
515
+ /// @brief charge_sum is NULL if G-L NAC or no-NAC.
516
+ static void get_dynmat_ij(double (*dynamical_matrix)[2],
517
+ const int64_t num_patom, const int64_t num_satom,
518
+ const double *fc, const double q[3],
519
+ const double (*svecs)[3], const int64_t (*multi)[2],
520
+ const double *mass, const int64_t *s2p_map,
521
+ const int64_t *p2s_map,
522
+ const double (*charge_sum)[3][3], const int64_t i,
523
+ const int64_t j) {
524
+ int64_t k, l, adrs;
525
+ double mass_sqrt;
526
+ double dm[3][3][2]; // [3][3][(real, imag)]
527
+
528
+ mass_sqrt = sqrt(mass[i] * mass[j]);
529
+
530
+ for (k = 0; k < 3; k++) {
531
+ for (l = 0; l < 3; l++) {
532
+ dm[k][l][0] = 0;
533
+ dm[k][l][1] = 0;
534
+ }
535
+ }
536
+
537
+ for (k = 0; k < num_satom; k++) { /* Lattice points of right index of fc */
538
+ if (s2p_map[k] != p2s_map[j]) {
539
+ continue;
540
+ }
541
+ get_dm(dm, num_patom, num_satom, fc, q, svecs, multi, p2s_map,
542
+ charge_sum, i, j, k);
543
+ }
544
+
545
+ for (k = 0; k < 3; k++) {
546
+ for (l = 0; l < 3; l++) {
547
+ adrs = (i * 3 + k) * num_patom * 3 + j * 3 + l;
548
+ dynamical_matrix[adrs][0] = dm[k][l][0] / mass_sqrt;
549
+ dynamical_matrix[adrs][1] = dm[k][l][1] / mass_sqrt;
550
+ }
551
+ }
552
+ }
553
+
554
+ static void get_dm(double dm[3][3][2], const int64_t num_patom,
555
+ const int64_t num_satom, const double *fc, const double q[3],
556
+ const double (*svecs)[3], const int64_t (*multi)[2],
557
+ const int64_t *p2s_map, const double (*charge_sum)[3][3],
558
+ const int64_t i, const int64_t j, const int64_t k) {
559
+ int64_t l, m, i_pair, m_pair, adrs;
560
+ double phase, cos_phase, sin_phase, fc_elem;
561
+
562
+ cos_phase = 0;
563
+ sin_phase = 0;
564
+
565
+ i_pair = k * num_patom + i;
566
+ m_pair = multi[i_pair][0];
567
+ adrs = multi[i_pair][1];
568
+
569
+ for (l = 0; l < m_pair; l++) {
570
+ phase = 0;
571
+ for (m = 0; m < 3; m++) {
572
+ phase += q[m] * svecs[adrs + l][m];
573
+ }
574
+ cos_phase += cos(phase * 2 * PI) / m_pair;
575
+ sin_phase += sin(phase * 2 * PI) / m_pair;
576
+ }
577
+
578
+ for (l = 0; l < 3; l++) {
579
+ for (m = 0; m < 3; m++) {
580
+ if (charge_sum) {
581
+ fc_elem = (fc[p2s_map[i] * num_satom * 9 + k * 9 + l * 3 + m] +
582
+ charge_sum[i * num_patom + j][l][m]);
583
+ } else {
584
+ fc_elem = fc[p2s_map[i] * num_satom * 9 + k * 9 + l * 3 + m];
585
+ }
586
+ dm[l][m][0] += fc_elem * cos_phase;
587
+ dm[l][m][1] += fc_elem * sin_phase;
588
+ }
589
+ }
590
+ }
591
+
592
+ static double get_dielectric_part(const double q_cart[3],
593
+ const double dielectric[3][3]) {
594
+ int64_t i, j;
595
+ double sum;
596
+
597
+ sum = 0;
598
+ for (i = 0; i < 3; i++) {
599
+ for (j = 0; j < 3; j++) {
600
+ sum += q_cart[i] * dielectric[i][j] * q_cart[j];
601
+ }
602
+ }
603
+ return sum;
604
+ }
605
+
606
+ static void get_dd(double (*dd_part)[2], /* [natom, 3, natom, 3, (real,imag)] */
607
+ const double (*G_list)[3], /* [num_G, 3] */
608
+ const int64_t num_G, const int64_t num_patom,
609
+ const double q_cart[3], const double *q_direction_cart,
610
+ const double dielectric[3][3],
611
+ const double (*pos)[3], /* [num_patom, 3] */
612
+ const double lambda, const double tolerance,
613
+ const int64_t use_openmp) {
614
+ int64_t i, j, g;
615
+ double q_K[3];
616
+ double norm, dielectric_part, L2;
617
+ double (*KK)[3][3];
618
+
619
+ KK = (double (*)[3][3])malloc(sizeof(double[3][3]) * num_G);
620
+ L2 = 4 * lambda * lambda;
621
+
622
+ /* sum over K = G + q and over G (i.e. q=0) */
623
+ /* q_direction has values for summation over K at Gamma point. */
624
+ /* q_direction is NULL for summation over G */
625
+ #ifdef _OPENMP
626
+ #pragma omp parallel for private(i, j, q_K, norm, \
627
+ dielectric_part) if (use_openmp)
628
+ #endif
629
+ for (g = 0; g < num_G; g++) {
630
+ norm = 0;
631
+ for (i = 0; i < 3; i++) {
632
+ q_K[i] = G_list[g][i] + q_cart[i];
633
+ norm += q_K[i] * q_K[i];
634
+ }
635
+
636
+ if (sqrt(norm) < tolerance) {
637
+ if (!q_direction_cart) {
638
+ for (i = 0; i < 3; i++) {
639
+ for (j = 0; j < 3; j++) {
640
+ KK[g][i][j] = 0;
641
+ }
642
+ }
643
+ continue;
644
+ } else {
645
+ dielectric_part =
646
+ get_dielectric_part(q_direction_cart, dielectric);
647
+ for (i = 0; i < 3; i++) {
648
+ for (j = 0; j < 3; j++) {
649
+ KK[g][i][j] = q_direction_cart[i] *
650
+ q_direction_cart[j] / dielectric_part;
651
+ }
652
+ }
653
+ }
654
+ } else {
655
+ dielectric_part = get_dielectric_part(q_K, dielectric);
656
+ for (i = 0; i < 3; i++) {
657
+ for (j = 0; j < 3; j++) {
658
+ KK[g][i][j] = q_K[i] * q_K[j] / dielectric_part *
659
+ exp(-dielectric_part / L2);
660
+ }
661
+ }
662
+ }
663
+ }
664
+
665
+ // OpenMP should not be used here.
666
+ // Due to race condition in dd_part and bad performance.
667
+ for (g = 0; g < num_G; g++) {
668
+ for (i = 0; i < num_patom; i++) {
669
+ for (j = 0; j < num_patom; j++) {
670
+ get_dd_at_g(dd_part, i, j, G_list[g], num_patom, pos, KK[g]);
671
+ }
672
+ }
673
+ }
674
+
675
+ free(KK);
676
+ KK = NULL;
677
+ }
678
+
679
+ static void get_dd_at_g(
680
+ double (*dd_part)[2], /* [natom, 3, natom, 3, (real,imag)] */
681
+ const int64_t i, const int64_t j, const double G[3],
682
+ const int64_t num_patom, const double (*pos)[3], /* [num_patom, 3] */
683
+ const double KK[3][3]) {
684
+ int64_t k, l, adrs;
685
+ double cos_phase, sin_phase, phase;
686
+
687
+ phase = 0;
688
+ for (k = 0; k < 3; k++) {
689
+ /* For D-type dynamical matrix */
690
+ /* phase += (pos[i][k] - pos[j][k]) * q_K[k]; */
691
+ /* For C-type dynamical matrix */
692
+ phase += (pos[i][k] - pos[j][k]) * G[k];
693
+ }
694
+ phase *= 2 * PI;
695
+ cos_phase = cos(phase);
696
+ sin_phase = sin(phase);
697
+ for (k = 0; k < 3; k++) {
698
+ for (l = 0; l < 3; l++) {
699
+ adrs = i * num_patom * 9 + k * num_patom * 3 + j * 3 + l;
700
+ dd_part[adrs][0] += KK[k][l] * cos_phase;
701
+ dd_part[adrs][1] += KK[k][l] * sin_phase;
702
+ }
703
+ }
704
+ }
705
+
706
+ static void make_Hermitian(double (*mat)[2], const int64_t num_band) {
707
+ int64_t i, j, adrs, adrsT;
708
+
709
+ for (i = 0; i < num_band; i++) {
710
+ for (j = i; j < num_band; j++) {
711
+ adrs = i * num_band + j;
712
+ adrsT = j * num_band + i;
713
+ /* real part */
714
+ mat[adrs][0] += mat[adrsT][0];
715
+ mat[adrs][0] /= 2;
716
+ /* imaginary part */
717
+ mat[adrs][1] -= mat[adrsT][1];
718
+ mat[adrs][1] /= 2;
719
+ /* store */
720
+ mat[adrsT][0] = mat[adrs][0];
721
+ mat[adrsT][1] = -mat[adrs][1];
722
+ }
723
+ }
724
+ }
725
+
726
+ static void multiply_borns(double (*dd)[2], const double (*dd_in)[2],
727
+ const int64_t num_patom, const double (*born)[3][3],
728
+ const int64_t use_openmp) {
729
+ int64_t i, j, ij;
730
+
731
+ if (use_openmp) {
732
+ #ifdef _OPENMP
733
+ #pragma omp parallel for
734
+ #endif
735
+ for (ij = 0; ij < num_patom * num_patom; ij++) {
736
+ multiply_borns_at_ij(dd, ij / num_patom, ij % num_patom, dd_in,
737
+ num_patom, born);
738
+ }
739
+ } else {
740
+ for (i = 0; i < num_patom; i++) {
741
+ for (j = 0; j < num_patom; j++) {
742
+ multiply_borns_at_ij(dd, i, j, dd_in, num_patom, born);
743
+ }
744
+ }
745
+ }
746
+ }
747
+
748
+ static void multiply_borns_at_ij(double (*dd)[2], const int64_t i,
749
+ const int64_t j, const double (*dd_in)[2],
750
+ const int64_t num_patom,
751
+ const double (*born)[3][3]) {
752
+ int64_t k, l, m, n, adrs, adrs_in;
753
+ double zz;
754
+
755
+ for (k = 0; k < 3; k++) { /* alpha */
756
+ for (l = 0; l < 3; l++) { /* beta */
757
+ adrs = i * num_patom * 9 + k * num_patom * 3 + j * 3 + l;
758
+ for (m = 0; m < 3; m++) { /* alpha' */
759
+ for (n = 0; n < 3; n++) { /* beta' */
760
+ adrs_in = i * num_patom * 9 + m * num_patom * 3 + j * 3 + n;
761
+ zz = born[i][m][k] * born[j][n][l];
762
+ dd[adrs][0] += dd_in[adrs_in][0] * zz;
763
+ dd[adrs][1] += dd_in[adrs_in][1] * zz;
764
+ }
765
+ }
766
+ }
767
+ }
768
+ }
769
+
770
+ static void transform_dynmat_to_fc_ij(
771
+ double *fc, const double (*dm)[2], const int64_t i, const int64_t j,
772
+ const double (*comm_points)[3], const double (*svecs)[3],
773
+ const int64_t (*multi)[2], const double *masses, const int64_t *s2pp_map,
774
+ const int64_t *fc_index_map, const int64_t num_patom,
775
+ const int64_t num_satom) {
776
+ int64_t k, l, m, N, adrs, m_pair, i_pair, svecs_adrs;
777
+ double coef, phase, cos_phase, sin_phase;
778
+
779
+ N = num_satom / num_patom;
780
+ i_pair = j * num_patom + i;
781
+ m_pair = multi[i_pair][0];
782
+ svecs_adrs = multi[i_pair][1];
783
+ coef = sqrt(masses[i] * masses[s2pp_map[j]]) / N;
784
+ for (k = 0; k < N; k++) {
785
+ cos_phase = 0;
786
+ sin_phase = 0;
787
+ for (l = 0; l < m_pair; l++) {
788
+ phase = 0;
789
+ for (m = 0; m < 3; m++) {
790
+ phase -= comm_points[k][m] * svecs[svecs_adrs + l][m];
791
+ }
792
+ cos_phase += cos(phase * 2 * PI);
793
+ sin_phase += sin(phase * 2 * PI);
794
+ }
795
+ cos_phase /= m_pair;
796
+ sin_phase /= m_pair;
797
+ for (l = 0; l < 3; l++) {
798
+ for (m = 0; m < 3; m++) {
799
+ adrs = k * num_patom * num_patom * 9 + i * num_patom * 9 +
800
+ l * num_patom * 3 + s2pp_map[j] * 3 + m;
801
+ fc[fc_index_map[i] * num_satom * 9 + j * 9 + l * 3 + m] +=
802
+ (dm[adrs][0] * cos_phase - dm[adrs][1] * sin_phase) * coef;
803
+ }
804
+ }
805
+ }
806
+ }
807
+
808
+ /// @brief
809
+ /// @param q_cart q-point in Cartesian coordinates
810
+ /// @param q q-point in crystallographic coordinates
811
+ /// @param reciprocal_lattice in column vectors
812
+ static void get_q_cart(double q_cart[3], const double q[3],
813
+ const double reciprocal_lattice[3][3]) {
814
+ int64_t i, j;
815
+
816
+ for (i = 0; i < 3; i++) {
817
+ q_cart[i] = 0;
818
+ for (j = 0; j < 3; j++) {
819
+ q_cart[i] += reciprocal_lattice[i][j] * q[j];
820
+ }
821
+ }
822
+ }
phonopy/source/c/dynmat.h ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2015 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file is part of phonopy. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the phonopy project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #ifndef __dynmat_H__
36
+ #define __dynmat_H__
37
+
38
+ #include <stdint.h>
39
+
40
+ int64_t dym_dynamical_matrices_with_dd_openmp_over_qpoints(
41
+ double (*dynamical_matrices)[2], const double (*qpoints)[3],
42
+ const int64_t n_qpoints, const double *fc, const double (*svecs)[3],
43
+ const int64_t (*multi)[2], const double (*positions)[3],
44
+ const int64_t num_patom, const int64_t num_satom, const double *masses,
45
+ const int64_t *p2s_map, const int64_t *s2p_map, const double (*born)[3][3],
46
+ const double dielectric[3][3], const double (*reciprocal_lattice)[3],
47
+ const double *q_direction, const double nac_factor,
48
+ const double (*dd_q0)[2], const double (*G_list)[3],
49
+ const int64_t num_G_points, const double lambda, const int64_t use_Wang_NAC,
50
+ const int64_t hermitianize);
51
+ void dym_get_recip_dipole_dipole(
52
+ double (*dd)[2], /* [natom, 3, natom, 3, (real,imag)] */
53
+ const double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
54
+ const double (*G_list)[3], /* [num_G, 3] */
55
+ const int64_t num_G, const int64_t num_patom, const double q_cart[3],
56
+ const double *q_direction_cart, /* must be pointer */
57
+ const double (*born)[3][3], const double dielectric[3][3],
58
+ const double (*pos)[3], /* [num_patom, 3] */
59
+ const double factor, /* 4pi/V*unit-conv */
60
+ const double lambda, const double tolerance, const int64_t use_openmp);
61
+ void dym_get_recip_dipole_dipole_q0(
62
+ double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
63
+ const double (*G_list)[3], /* [num_G, 3] */
64
+ const int64_t num_G, const int64_t num_patom, const double (*born)[3][3],
65
+ const double dielectric[3][3], const double (*pos)[3], /* [natom, 3] */
66
+ const double lambda, const double tolerance, const int64_t use_openmp);
67
+ void dym_get_charge_sum(double (*charge_sum)[3][3], const int64_t num_patom,
68
+ const double factor, const double q_cart[3],
69
+ const double (*born)[3][3]);
70
+ /* fc[num_patom, num_satom, 3, 3] */
71
+ /* dm[num_comm_points, num_patom * 3, num_patom *3] */
72
+ /* comm_points[num_satom / num_patom, 3] */
73
+ /* shortest_vectors[:, 3] */
74
+ /* multiplicities[num_satom, num_patom, 2] */
75
+ void dym_transform_dynmat_to_fc(
76
+ double *fc, const double (*dm)[2], const double (*comm_points)[3],
77
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *masses,
78
+ const int64_t *s2pp_map, const int64_t *fc_index_map,
79
+ const int64_t num_patom, const int64_t num_satom, const int64_t use_openmp);
80
+
81
+ #endif
phonopy/source/c/phonopy.c ADDED
@@ -0,0 +1,899 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2021 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file is part of phonopy. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the phonopy project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #include "phonopy.h"
36
+
37
+ #include <float.h>
38
+ #include <math.h>
39
+ #include <stdint.h>
40
+ #include <stdio.h>
41
+ #include <stdlib.h>
42
+
43
+ #include "derivative_dynmat.h"
44
+ #include "dynmat.h"
45
+ #include "rgrid.h"
46
+ #include "tetrahedron_method.h"
47
+
48
+ #ifdef _OPENMP
49
+ #include <omp.h>
50
+ #endif
51
+
52
+ static void set_index_permutation_symmetry_fc(double *fc, const int natom);
53
+ static void set_translational_symmetry_fc(double *fc, const int natom);
54
+ static void set_translational_symmetry_compact_fc(double *fc, const int p2s[],
55
+ const int n_satom,
56
+ const int n_patom);
57
+ static double get_free_energy(const double temperature, const double f,
58
+ const double KB, const int classical);
59
+ static double get_entropy(const double temperature, const double f,
60
+ const double KB, const int classical);
61
+ static double get_heat_capacity(const double temperature, const double f,
62
+ const double KB, const int classical);
63
+ /* static double get_energy(double temperature, double f); */
64
+ static void distribute_fc2(double (*fc2)[3][3], const int *atom_list,
65
+ const int len_atom_list,
66
+ const int *fc_indices_of_atom_list,
67
+ const double (*r_carts)[3][3],
68
+ const int *permutations, const int *map_atoms,
69
+ const int *map_syms, const int num_rot,
70
+ const int num_pos);
71
+ static int nint(const double a);
72
+
73
+ void phpy_transform_dynmat_to_fc(
74
+ double *fc, const double (*dm)[2], const double (*comm_points)[3],
75
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *masses,
76
+ const int64_t *s2pp_map, const int64_t *fc_index_map,
77
+ const int64_t num_patom, const int64_t num_satom,
78
+ const int64_t use_openmp) {
79
+ dym_transform_dynmat_to_fc(fc, dm, comm_points, svecs, multi, masses,
80
+ s2pp_map, fc_index_map, num_patom, num_satom,
81
+ use_openmp);
82
+ }
83
+
84
+ int64_t phpy_dynamical_matrices_with_dd_openmp_over_qpoints(
85
+ double (*dynamical_matrices)[2], const double (*qpoints)[3],
86
+ const int64_t n_qpoints, const double *fc, const double (*svecs)[3],
87
+ const int64_t (*multi)[2], const double (*positions)[3],
88
+ const int64_t num_patom, const int64_t num_satom, const double *masses,
89
+ const int64_t *p2s_map, const int64_t *s2p_map, const double (*born)[3][3],
90
+ const double dielectric[3][3], const double (*reciprocal_lattice)[3],
91
+ const double *q_direction, const double nac_factor,
92
+ const double (*dd_q0)[2], const double (*G_list)[3],
93
+ const int64_t num_G_points, const double lambda, const int64_t use_Wang_NAC,
94
+ const int64_t hermitianize) {
95
+ return dym_dynamical_matrices_with_dd_openmp_over_qpoints(
96
+ dynamical_matrices, qpoints, n_qpoints, fc, svecs, multi, positions,
97
+ num_patom, num_satom, masses, p2s_map, s2p_map, born, dielectric,
98
+ reciprocal_lattice, q_direction, nac_factor, dd_q0, G_list,
99
+ num_G_points, lambda, use_Wang_NAC, hermitianize);
100
+ }
101
+
102
+ void phpy_get_charge_sum(
103
+ double (*charge_sum)[3][3], const int64_t num_patom,
104
+ const double factor, /* 4pi/V*unit-conv and denominator */
105
+ const double q_cart[3], const double (*born)[3][3]) {
106
+ dym_get_charge_sum(charge_sum, num_patom, factor, q_cart, born);
107
+ }
108
+
109
+ void phpy_get_recip_dipole_dipole(
110
+ double (*dd)[2], /* [natom, 3, natom, 3, (real,imag)] */
111
+ const double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
112
+ const double (*G_list)[3], /* [num_G, 3] */
113
+ const int64_t num_G, const int64_t num_patom, const double q_cart[3],
114
+ const double *q_direction_cart, /* must be pointer */
115
+ const double (*born)[3][3], const double dielectric[3][3],
116
+ const double (*pos)[3], /* [num_patom, 3] */
117
+ const double factor, /* 4pi/V*unit-conv */
118
+ const double lambda, const double tolerance, const int64_t use_openmp) {
119
+ dym_get_recip_dipole_dipole(dd, dd_q0, G_list, num_G, num_patom, q_cart,
120
+ q_direction_cart, born, dielectric, pos, factor,
121
+ lambda, tolerance, use_openmp);
122
+ }
123
+
124
+ void phpy_get_recip_dipole_dipole_q0(
125
+ double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
126
+ const double (*G_list)[3], /* [num_G, 3] */
127
+ const int64_t num_G, const int64_t num_patom, const double (*born)[3][3],
128
+ const double dielectric[3][3], const double (*pos)[3], /* [num_patom, 3] */
129
+ const double lambda, const double tolerance, const int64_t use_openmp) {
130
+ dym_get_recip_dipole_dipole_q0(dd_q0, G_list, num_G, num_patom, born,
131
+ dielectric, pos, lambda, tolerance,
132
+ use_openmp);
133
+ }
134
+
135
+ void phpy_get_derivative_dynmat_at_q(
136
+ double (*derivative_dynmat)[2], const int64_t num_patom,
137
+ const int64_t num_satom, const double *fc, const double *q,
138
+ const double *lattice, /* column vector */
139
+ const double *reclat, /* column vector */
140
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
141
+ const int64_t *s2p_map, const int64_t *p2s_map, const double nac_factor,
142
+ const double *born, const double *dielectric, const double *q_direction,
143
+ const int64_t is_nac, const int64_t use_openmp) {
144
+ ddm_get_derivative_dynmat_at_q(derivative_dynmat, num_patom, num_satom, fc,
145
+ q, lattice, reclat, svecs, multi, mass,
146
+ s2p_map, p2s_map, nac_factor, born,
147
+ dielectric, q_direction, is_nac, use_openmp);
148
+ }
149
+
150
+ void phpy_get_relative_grid_address(int64_t relative_grid_address[24][4][3],
151
+ const double reciprocal_lattice[3][3]) {
152
+ thm_get_relative_grid_address(relative_grid_address, reciprocal_lattice);
153
+ }
154
+
155
+ void phpy_get_all_relative_grid_address(
156
+ int64_t relative_grid_address[4][24][4][3]) {
157
+ thm_get_all_relative_grid_address(relative_grid_address);
158
+ }
159
+
160
+ double phpy_get_integration_weight(const double omega,
161
+ const double tetrahedra_omegas[24][4],
162
+ const char function) {
163
+ return thm_get_integration_weight(omega, tetrahedra_omegas, function);
164
+ }
165
+
166
+ void phpy_get_tetrahedra_frequenies(
167
+ double *freq_tetras, const int64_t mesh[3], const int64_t *grid_points,
168
+ const int64_t (*grid_address)[3], const int64_t (*relative_grid_address)[3],
169
+ const int64_t *gp_ir_index, const double *frequencies,
170
+ const int64_t num_band, const int64_t num_gp) {
171
+ int64_t is_shift[3] = {0, 0, 0};
172
+ int64_t i, j, k, gp;
173
+ int64_t g_addr[3];
174
+ int64_t address_double[3];
175
+
176
+ /* relative_grid_address[4, 24, 3] is viewed as [96, 3]. */
177
+ for (i = 0; i < num_gp; i++) {
178
+ #ifdef _OPENMP
179
+ #pragma omp parallel for private(k, g_addr, gp, address_double)
180
+ #endif
181
+ for (j = 0; j < num_band * 96; j++) {
182
+ for (k = 0; k < 3; k++) {
183
+ g_addr[k] = grid_address[grid_points[i]][k] +
184
+ relative_grid_address[j % 96][k];
185
+ }
186
+ rgd_get_double_grid_address(address_double, g_addr, mesh, is_shift);
187
+ gp = rgd_get_double_grid_index(address_double, mesh);
188
+ freq_tetras[i * num_band * 96 + j] =
189
+ frequencies[gp_ir_index[gp] * num_band + j / 96];
190
+ }
191
+ }
192
+ }
193
+
194
+ void phpy_tetrahedron_method_dos(
195
+ double *dos, const int64_t mesh[3], const int64_t (*grid_address)[3],
196
+ const int64_t (*relative_grid_address)[4][3],
197
+ const int64_t *grid_mapping_table, const double *freq_points,
198
+ const double *frequencies, const double *coef,
199
+ const int64_t num_freq_points, const int64_t num_ir_gp,
200
+ const int64_t num_band, const int64_t num_coef, const int64_t num_gp) {
201
+ int64_t is_shift[3] = {0, 0, 0};
202
+ int64_t i, j, k, l, m, q, r, count;
203
+ int64_t ir_gps[24][4];
204
+ int64_t g_addr[3];
205
+ double tetrahedra[24][4];
206
+ int64_t address_double[3];
207
+ int64_t *gp2ir, *ir_grid_points;
208
+ int64_t *weights;
209
+ double iw;
210
+
211
+ gp2ir = NULL;
212
+ ir_grid_points = NULL;
213
+ weights = NULL;
214
+
215
+ gp2ir = (int64_t *)malloc(sizeof(int64_t) * num_gp);
216
+ ir_grid_points = (int64_t *)malloc(sizeof(int64_t) * num_ir_gp);
217
+ weights = (int64_t *)malloc(sizeof(int64_t) * num_ir_gp);
218
+
219
+ count = 0;
220
+ for (i = 0; i < num_gp; i++) {
221
+ if (grid_mapping_table[i] == i) {
222
+ gp2ir[i] = count;
223
+ ir_grid_points[count] = i;
224
+ weights[count] = 1;
225
+ count++;
226
+ } else {
227
+ gp2ir[i] = gp2ir[grid_mapping_table[i]];
228
+ weights[gp2ir[i]]++;
229
+ }
230
+ }
231
+
232
+ if (num_ir_gp != count) {
233
+ printf("Something is wrong!\n");
234
+ }
235
+
236
+ #ifdef _OPENMP
237
+ #pragma omp parallel for private(j, k, l, m, q, r, iw, ir_gps, g_addr, \
238
+ tetrahedra, address_double)
239
+ #endif
240
+ for (i = 0; i < num_ir_gp; i++) {
241
+ /* set 24 tetrahedra */
242
+ for (l = 0; l < 24; l++) {
243
+ for (q = 0; q < 4; q++) {
244
+ for (r = 0; r < 3; r++) {
245
+ g_addr[r] = grid_address[ir_grid_points[i]][r] +
246
+ relative_grid_address[l][q][r];
247
+ }
248
+ rgd_get_double_grid_address(address_double, g_addr, mesh,
249
+ is_shift);
250
+ ir_gps[l][q] =
251
+ gp2ir[rgd_get_double_grid_index(address_double, mesh)];
252
+ }
253
+ }
254
+
255
+ for (k = 0; k < num_band; k++) {
256
+ for (l = 0; l < 24; l++) {
257
+ for (q = 0; q < 4; q++) {
258
+ tetrahedra[l][q] = frequencies[ir_gps[l][q] * num_band + k];
259
+ }
260
+ }
261
+ for (j = 0; j < num_freq_points; j++) {
262
+ iw = thm_get_integration_weight(freq_points[j], tetrahedra,
263
+ 'I') *
264
+ weights[i];
265
+ for (m = 0; m < num_coef; m++) {
266
+ dos[i * num_band * num_freq_points * num_coef +
267
+ k * num_coef * num_freq_points + j * num_coef + m] +=
268
+ iw * coef[i * num_coef * num_band + m * num_band + k];
269
+ }
270
+ }
271
+ }
272
+ }
273
+
274
+ free(gp2ir);
275
+ gp2ir = NULL;
276
+ free(ir_grid_points);
277
+ ir_grid_points = NULL;
278
+ free(weights);
279
+ weights = NULL;
280
+ }
281
+
282
+ void phpy_get_thermal_properties(
283
+ double *thermal_props, const double *temperatures, const double *freqs,
284
+ const int64_t *weights, const int64_t num_temp, const int64_t num_qpoints,
285
+ const int64_t num_bands, const double cutoff_frequency, const double KB,
286
+ const int classical) {
287
+ int64_t i, j, k;
288
+ double f;
289
+ double *tp;
290
+
291
+ tp = (double *)malloc(sizeof(double) * num_qpoints * num_temp * 3);
292
+ for (i = 0; i < num_qpoints * num_temp * 3; i++) {
293
+ tp[i] = 0;
294
+ }
295
+
296
+ #ifdef _OPENMP
297
+ #pragma omp parallel for private(j, k, f)
298
+ #endif
299
+ for (i = 0; i < num_qpoints; i++) {
300
+ for (j = 0; j < num_temp; j++) {
301
+ for (k = 0; k < num_bands; k++) {
302
+ f = freqs[i * num_bands + k];
303
+ if (temperatures[j] > 0 && f > cutoff_frequency) {
304
+ tp[i * num_temp * 3 + j * 3] +=
305
+ get_free_energy(temperatures[j], f, KB, classical) *
306
+ weights[i];
307
+ tp[i * num_temp * 3 + j * 3 + 1] +=
308
+ get_entropy(temperatures[j], f, KB, classical) *
309
+ weights[i];
310
+ tp[i * num_temp * 3 + j * 3 + 2] +=
311
+ get_heat_capacity(temperatures[j], f, KB, classical) *
312
+ weights[i];
313
+ }
314
+ }
315
+ }
316
+ }
317
+
318
+ for (i = 0; i < num_qpoints; i++) {
319
+ for (j = 0; j < num_temp * 3; j++) {
320
+ thermal_props[j] += tp[i * num_temp * 3 + j];
321
+ }
322
+ }
323
+
324
+ free(tp);
325
+ tp = NULL;
326
+ }
327
+
328
+ void phpy_distribute_fc2(double (*fc2)[3][3], const int *atom_list,
329
+ const int len_atom_list,
330
+ const int *fc_indices_of_atom_list,
331
+ const double (*r_carts)[3][3], const int *permutations,
332
+ const int *map_atoms, const int *map_syms,
333
+ const int num_rot, const int num_pos) {
334
+ distribute_fc2(fc2, atom_list, len_atom_list, fc_indices_of_atom_list,
335
+ r_carts, permutations, map_atoms, map_syms, num_rot,
336
+ num_pos);
337
+ }
338
+
339
+ int phpy_compute_permutation(int *rot_atom, const double lat[3][3],
340
+ const double (*pos)[3], const double (*rot_pos)[3],
341
+ const int num_pos, const double symprec) {
342
+ int i, j, k, l;
343
+ int search_start;
344
+ double distance2, diff_cart;
345
+ double diff[3];
346
+
347
+ for (i = 0; i < num_pos; i++) {
348
+ rot_atom[i] = -1;
349
+ }
350
+
351
+ /* optimization: Iterate primarily by pos instead of rot_pos. */
352
+ /* (find where 0 beint64_ts in rot_atom, then where 1 beint64_ts, etc.) */
353
+ /* Then track the first unassigned index. */
354
+ /* */
355
+ /* This works best if the permutation is close to the identity. */
356
+ /* (more specifically, if the max value of 'rot_atom[i] - i' is small)
357
+ */
358
+ search_start = 0;
359
+ for (i = 0; i < num_pos; i++) {
360
+ while (rot_atom[search_start] >= 0) {
361
+ search_start++;
362
+ }
363
+ for (j = search_start; j < num_pos; j++) {
364
+ if (rot_atom[j] >= 0) {
365
+ continue;
366
+ }
367
+
368
+ for (k = 0; k < 3; k++) {
369
+ diff[k] = pos[i][k] - rot_pos[j][k];
370
+ diff[k] -= nint(diff[k]);
371
+ }
372
+ distance2 = 0;
373
+ for (k = 0; k < 3; k++) {
374
+ diff_cart = 0;
375
+ for (l = 0; l < 3; l++) {
376
+ diff_cart += lat[k][l] * diff[l];
377
+ }
378
+ distance2 += diff_cart * diff_cart;
379
+ }
380
+
381
+ if (sqrt(distance2) < symprec) {
382
+ rot_atom[j] = i;
383
+ break;
384
+ }
385
+ }
386
+ }
387
+
388
+ for (i = 0; i < num_pos; i++) {
389
+ if (rot_atom[i] < 0) {
390
+ return 0;
391
+ }
392
+ }
393
+ return 1;
394
+ }
395
+
396
+ void phpy_set_smallest_vectors_sparse(
397
+ double (*smallest_vectors)[27][3], int *multiplicity,
398
+ const double (*pos_to)[3], const int num_pos_to,
399
+ const double (*pos_from)[3], const int num_pos_from,
400
+ const int (*lattice_points)[3], const int num_lattice_points,
401
+ const double reduced_basis[3][3], const int trans_mat[3][3],
402
+ const double symprec) {
403
+ int i, j, k, l, count;
404
+ double length_tmp, minimum, vec_xyz;
405
+ double *length;
406
+ double (*vec)[3];
407
+
408
+ length = (double *)malloc(sizeof(double) * num_lattice_points);
409
+ vec = (double (*)[3])malloc(sizeof(double[3]) * num_lattice_points);
410
+
411
+ for (i = 0; i < num_pos_to; i++) {
412
+ for (j = 0; j < num_pos_from; j++) {
413
+ for (k = 0; k < num_lattice_points; k++) {
414
+ length[k] = 0;
415
+ for (l = 0; l < 3; l++) {
416
+ vec[k][l] =
417
+ pos_to[i][l] - pos_from[j][l] + lattice_points[k][l];
418
+ }
419
+ for (l = 0; l < 3; l++) {
420
+ length_tmp = (reduced_basis[l][0] * vec[k][0] +
421
+ reduced_basis[l][1] * vec[k][1] +
422
+ reduced_basis[l][2] * vec[k][2]);
423
+ length[k] += length_tmp * length_tmp;
424
+ }
425
+ length[k] = sqrt(length[k]);
426
+ }
427
+
428
+ minimum = DBL_MAX;
429
+ for (k = 0; k < num_lattice_points; k++) {
430
+ if (length[k] < minimum) {
431
+ minimum = length[k];
432
+ }
433
+ }
434
+
435
+ count = 0;
436
+ for (k = 0; k < num_lattice_points; k++) {
437
+ if (length[k] - minimum < symprec) {
438
+ for (l = 0; l < 3; l++) {
439
+ /* Transform back to supercell coordinates */
440
+ vec_xyz = (trans_mat[l][0] * vec[k][0] +
441
+ trans_mat[l][1] * vec[k][1] +
442
+ trans_mat[l][2] * vec[k][2]);
443
+ smallest_vectors[i * num_pos_from + j][count][l] =
444
+ vec_xyz;
445
+ }
446
+ count++;
447
+ }
448
+ }
449
+ if (count > 27) { /* should not be greater than 27 */
450
+ printf("Warning (gsv_set_smallest_vectors_sparse): ");
451
+ printf("number of shortest vectors is out of range,\n");
452
+ break;
453
+ } else {
454
+ multiplicity[i * num_pos_from + j] = count;
455
+ }
456
+ }
457
+ }
458
+
459
+ free(length);
460
+ length = NULL;
461
+ free(vec);
462
+ vec = NULL;
463
+ }
464
+
465
+ void phpy_set_smallest_vectors_dense(
466
+ double (*smallest_vectors)[3], int64_t (*multiplicity)[2],
467
+ const double (*pos_to)[3], const int64_t num_pos_to,
468
+ const double (*pos_from)[3], const int64_t num_pos_from,
469
+ const int64_t (*lattice_points)[3], const int64_t num_lattice_points,
470
+ const double reduced_basis[3][3], const int64_t trans_mat[3][3],
471
+ const int64_t initialize, const double symprec) {
472
+ int64_t i, j, k, l, count, adrs;
473
+ double length_tmp, minimum, vec_xyz;
474
+ double *length;
475
+ double (*vec)[3];
476
+
477
+ length = (double *)malloc(sizeof(double) * num_lattice_points);
478
+ vec = (double (*)[3])malloc(sizeof(double[3]) * num_lattice_points);
479
+
480
+ adrs = 0;
481
+
482
+ for (i = 0; i < num_pos_to; i++) {
483
+ for (j = 0; j < num_pos_from; j++) {
484
+ for (k = 0; k < num_lattice_points; k++) {
485
+ length[k] = 0;
486
+ for (l = 0; l < 3; l++) {
487
+ vec[k][l] =
488
+ pos_to[i][l] - pos_from[j][l] + lattice_points[k][l];
489
+ }
490
+ for (l = 0; l < 3; l++) {
491
+ length_tmp = (reduced_basis[l][0] * vec[k][0] +
492
+ reduced_basis[l][1] * vec[k][1] +
493
+ reduced_basis[l][2] * vec[k][2]);
494
+ length[k] += length_tmp * length_tmp;
495
+ }
496
+ length[k] = sqrt(length[k]);
497
+ }
498
+
499
+ minimum = DBL_MAX;
500
+ for (k = 0; k < num_lattice_points; k++) {
501
+ if (length[k] < minimum) {
502
+ minimum = length[k];
503
+ }
504
+ }
505
+
506
+ count = 0;
507
+ for (k = 0; k < num_lattice_points; k++) {
508
+ if (length[k] - minimum < symprec) {
509
+ if (!initialize) {
510
+ for (l = 0; l < 3; l++) {
511
+ /* Transform back to supercell coordinates */
512
+ vec_xyz = (trans_mat[l][0] * vec[k][0] +
513
+ trans_mat[l][1] * vec[k][1] +
514
+ trans_mat[l][2] * vec[k][2]);
515
+ smallest_vectors[adrs + count][l] = vec_xyz;
516
+ }
517
+ }
518
+ count++;
519
+ }
520
+ }
521
+ if (initialize) {
522
+ multiplicity[i * num_pos_from + j][0] = count;
523
+ multiplicity[i * num_pos_from + j][1] = adrs;
524
+ }
525
+ adrs += count;
526
+ }
527
+ }
528
+
529
+ free(length);
530
+ length = NULL;
531
+ free(vec);
532
+ vec = NULL;
533
+ }
534
+
535
+ void phpy_perm_trans_symmetrize_fc(double *fc, const int n_satom,
536
+ const int level) {
537
+ int i, j, k, l, iter;
538
+ double sum;
539
+
540
+ for (iter = 0; iter < level; iter++) {
541
+ /* Subtract drift aint64_t column */
542
+ for (j = 0; j < n_satom; j++) {
543
+ for (k = 0; k < 3; k++) {
544
+ for (l = 0; l < 3; l++) {
545
+ sum = 0;
546
+ for (i = 0; i < n_satom; i++) {
547
+ sum += fc[i * n_satom * 9 + j * 9 + k * 3 + l];
548
+ }
549
+ sum /= n_satom;
550
+ for (i = 0; i < n_satom; i++) {
551
+ fc[i * n_satom * 9 + j * 9 + k * 3 + l] -= sum;
552
+ }
553
+ }
554
+ }
555
+ }
556
+ /* Subtract drift aint64_t row */
557
+ for (i = 0; i < n_satom; i++) {
558
+ for (k = 0; k < 3; k++) {
559
+ for (l = 0; l < 3; l++) {
560
+ sum = 0;
561
+ for (j = 0; j < n_satom; j++) {
562
+ sum += fc[i * n_satom * 9 + j * 9 + k * 3 + l];
563
+ }
564
+ sum /= n_satom;
565
+ for (j = 0; j < n_satom; j++) {
566
+ fc[i * n_satom * 9 + j * 9 + k * 3 + l] -= sum;
567
+ }
568
+ }
569
+ }
570
+ }
571
+ set_index_permutation_symmetry_fc(fc, n_satom);
572
+ }
573
+ set_translational_symmetry_fc(fc, n_satom);
574
+ }
575
+
576
+ void phpy_perm_trans_symmetrize_compact_fc(double *fc, const int p2s[],
577
+ const int s2pp[],
578
+ const int nsym_list[],
579
+ const int perms[], const int n_satom,
580
+ const int n_patom, const int level) {
581
+ int i, j, k, l, n, iter;
582
+ double sum;
583
+
584
+ for (iter = 0; iter < level; iter++) {
585
+ for (n = 0; n < 2; n++) {
586
+ /* transpose only */
587
+ phpy_set_index_permutation_symmetry_compact_fc(
588
+ fc, p2s, s2pp, nsym_list, perms, n_satom, n_patom, 1);
589
+ for (i = 0; i < n_patom; i++) {
590
+ for (k = 0; k < 3; k++) {
591
+ for (l = 0; l < 3; l++) {
592
+ sum = 0;
593
+ for (j = 0; j < n_satom; j++) {
594
+ sum += fc[i * n_satom * 9 + j * 9 + k * 3 + l];
595
+ }
596
+ sum /= n_satom;
597
+ for (j = 0; j < n_satom; j++) {
598
+ fc[i * n_satom * 9 + j * 9 + k * 3 + l] -= sum;
599
+ }
600
+ }
601
+ }
602
+ }
603
+ }
604
+
605
+ phpy_set_index_permutation_symmetry_compact_fc(
606
+ fc, p2s, s2pp, nsym_list, perms, n_satom, n_patom, 0);
607
+ }
608
+
609
+ set_translational_symmetry_compact_fc(fc, p2s, n_satom, n_patom);
610
+ }
611
+
612
+ void phpy_set_index_permutation_symmetry_compact_fc(
613
+ double *fc, const int p2s[], const int s2pp[], const int nsym_list[],
614
+ const int perms[], const int n_satom, const int n_patom,
615
+ const int is_transpose) {
616
+ int i, j, k, l, m, n, i_p, j_p, i_trans;
617
+ double fc_elem;
618
+ char *done;
619
+
620
+ done = NULL;
621
+ done = (char *)malloc(sizeof(char) * n_satom * n_patom);
622
+ for (i = 0; i < n_satom * n_patom; i++) {
623
+ done[i] = 0;
624
+ }
625
+
626
+ for (j = 0; j < n_satom; j++) {
627
+ j_p = s2pp[j];
628
+ for (i_p = 0; i_p < n_patom; i_p++) {
629
+ i = p2s[i_p];
630
+ if (i == j) { /* diagnoal part */
631
+ for (k = 0; k < 3; k++) {
632
+ for (l = 0; l < 3; l++) {
633
+ if (l > k) {
634
+ m = i_p * n_satom * 9 + i * 9 + k * 3 + l;
635
+ n = i_p * n_satom * 9 + i * 9 + l * 3 + k;
636
+ if (is_transpose) {
637
+ fc_elem = fc[m];
638
+ fc[m] = fc[n];
639
+ fc[n] = fc_elem;
640
+ } else {
641
+ fc[m] = (fc[m] + fc[n]) / 2;
642
+ fc[n] = fc[m];
643
+ }
644
+ }
645
+ }
646
+ }
647
+ }
648
+ if (!done[i_p * n_satom + j]) {
649
+ /* (j, i) -- nsym_list[j] --> (j', i') */
650
+ /* nsym_list[j] translates j to j' where j' is in */
651
+ /* primitive cell. The same translation sends i to i' */
652
+ /* where i' is not necessarily to be in primitive cell. */
653
+ /* Thus, i' = perms[nsym_list[j] * n_satom + i] */
654
+ i_trans = perms[nsym_list[j] * n_satom + i];
655
+ done[i_p * n_satom + j] = 1;
656
+ done[j_p * n_satom + i_trans] = 1;
657
+ for (k = 0; k < 3; k++) {
658
+ for (l = 0; l < 3; l++) {
659
+ m = i_p * n_satom * 9 + j * 9 + k * 3 + l;
660
+ n = j_p * n_satom * 9 + i_trans * 9 + l * 3 + k;
661
+ if (is_transpose) {
662
+ fc_elem = fc[m];
663
+ fc[m] = fc[n];
664
+ fc[n] = fc_elem;
665
+ } else {
666
+ fc[m] = (fc[n] + fc[m]) / 2;
667
+ fc[n] = fc[m];
668
+ }
669
+ }
670
+ }
671
+ }
672
+ }
673
+ }
674
+
675
+ free(done);
676
+ done = NULL;
677
+ }
678
+
679
+ int64_t phpy_use_openmp(void) {
680
+ #ifdef _OPENMP
681
+ return 1;
682
+ #else
683
+ return 0;
684
+ #endif
685
+ }
686
+
687
+ int64_t phpy_get_max_threads(void) {
688
+ #ifdef _OPENMP
689
+ return omp_get_max_threads();
690
+ #else
691
+ return 0;
692
+ #endif
693
+ }
694
+
695
+ static void set_index_permutation_symmetry_fc(double *fc, const int natom) {
696
+ int i, j, k, l, m, n;
697
+
698
+ for (i = 0; i < natom; i++) {
699
+ /* non diagonal part */
700
+ for (j = i + 1; j < natom; j++) {
701
+ for (k = 0; k < 3; k++) {
702
+ for (l = 0; l < 3; l++) {
703
+ m = i * natom * 9 + j * 9 + k * 3 + l;
704
+ n = j * natom * 9 + i * 9 + l * 3 + k;
705
+ fc[m] += fc[n];
706
+ fc[m] /= 2;
707
+ fc[n] = fc[m];
708
+ }
709
+ }
710
+ }
711
+
712
+ /* diagnoal part */
713
+ for (k = 0; k < 2; k++) {
714
+ for (l = k + 1; l < 3; l++) {
715
+ m = i * natom * 9 + i * 9 + k * 3 + l;
716
+ n = i * natom * 9 + i * 9 + l * 3 + k;
717
+ fc[m] += fc[n];
718
+ fc[m] /= 2;
719
+ fc[n] = fc[m];
720
+ }
721
+ }
722
+ }
723
+ }
724
+
725
+ static void set_translational_symmetry_fc(double *fc, const int natom) {
726
+ int i, j, k, l, m;
727
+ double sums[3][3];
728
+
729
+ for (i = 0; i < natom; i++) {
730
+ for (k = 0; k < 3; k++) {
731
+ for (l = 0; l < 3; l++) {
732
+ sums[k][l] = 0;
733
+ m = i * natom * 9 + k * 3 + l;
734
+ for (j = 0; j < natom; j++) {
735
+ if (i != j) {
736
+ sums[k][l] += fc[m];
737
+ }
738
+ m += 9;
739
+ }
740
+ }
741
+ }
742
+ for (k = 0; k < 3; k++) {
743
+ for (l = 0; l < 3; l++) {
744
+ fc[i * natom * 9 + i * 9 + k * 3 + l] =
745
+ -(sums[k][l] + sums[l][k]) / 2;
746
+ }
747
+ }
748
+ }
749
+ }
750
+
751
+ static void set_translational_symmetry_compact_fc(double *fc, const int p2s[],
752
+ const int n_satom,
753
+ const int n_patom) {
754
+ int j, k, l, m, i_p;
755
+ double sums[3][3];
756
+
757
+ for (i_p = 0; i_p < n_patom; i_p++) {
758
+ for (k = 0; k < 3; k++) {
759
+ for (l = 0; l < 3; l++) {
760
+ sums[k][l] = 0;
761
+ m = i_p * n_satom * 9 + k * 3 + l;
762
+ for (j = 0; j < n_satom; j++) {
763
+ if (p2s[i_p] != j) {
764
+ sums[k][l] += fc[m];
765
+ }
766
+ m += 9;
767
+ }
768
+ }
769
+ }
770
+ for (k = 0; k < 3; k++) {
771
+ for (l = 0; l < 3; l++) {
772
+ fc[i_p * n_satom * 9 + p2s[i_p] * 9 + k * 3 + l] =
773
+ -(sums[k][l] + sums[l][k]) / 2;
774
+ }
775
+ }
776
+ }
777
+ }
778
+
779
+ static double get_free_energy(const double temperature, const double f,
780
+ const double KB, const int classical) {
781
+ /* temperature is defined by T (K) */
782
+ /* 'f' must be given in eV. */
783
+ if (classical) {
784
+ return KB * temperature * log(f / (KB * temperature));
785
+ } else {
786
+ return KB * temperature * log(1 - exp(-f / (KB * temperature)));
787
+ }
788
+ }
789
+
790
+ static double get_entropy(const double temperature, const double f,
791
+ const double KB, const int classical) {
792
+ /* temperature is defined by T (K) */
793
+ /* 'f' must be given in eV. */
794
+ double val;
795
+ if (classical) {
796
+ return KB - KB * log(f / (KB * temperature));
797
+ } else {
798
+ val = f / (2 * KB * temperature);
799
+ return 1 / (2 * temperature) * f * cosh(val) / sinh(val) -
800
+ KB * log(2 * sinh(val));
801
+ }
802
+ }
803
+
804
+ static double get_heat_capacity(const double temperature, const double f,
805
+ const double KB, const int classical) {
806
+ /* temperature is defined by T (K) */
807
+ /* 'f' must be given in eV. */
808
+ /* If val is close to 1. Then expansion is used. */
809
+ double val, val1, val2;
810
+ if (classical) {
811
+ return KB;
812
+ } else {
813
+ val = f / (KB * temperature);
814
+ val1 = exp(val);
815
+ val2 = (val) / (val1 - 1);
816
+ return KB * val1 * val2 * val2;
817
+ }
818
+ }
819
+
820
+ static void distribute_fc2(double (*fc2)[3][3], /* shape[n_pos][n_pos] */
821
+ const int *atom_list, const int len_atom_list,
822
+ const int *fc_indices_of_atom_list,
823
+ const double (*r_carts)[3][3], /* shape[n_rot] */
824
+ const int *permutations, /* shape[n_rot][n_pos] */
825
+ const int *map_atoms, /* shape [n_pos] */
826
+ const int *map_syms, /* shape [n_pos] */
827
+ const int num_rot, const int num_pos) {
828
+ int i, j, k, l, m;
829
+ int atom_todo, atom_done, atom_other;
830
+ int sym_index;
831
+ int *atom_list_reverse;
832
+ double (*fc2_done)[3];
833
+ double (*fc2_todo)[3];
834
+ const double (*r_cart)[3];
835
+ const int *permutation;
836
+
837
+ atom_list_reverse = NULL;
838
+ atom_list_reverse = (int *)malloc(sizeof(int) * num_pos);
839
+ /* atom_list_reverse[!atom_done] is undefined. */
840
+ for (i = 0; i < len_atom_list; i++) {
841
+ atom_done = map_atoms[atom_list[i]];
842
+ if (atom_done == atom_list[i]) {
843
+ atom_list_reverse[atom_done] = i;
844
+ }
845
+ }
846
+
847
+ for (i = 0; i < len_atom_list; i++) {
848
+ /* look up how this atom maps into the done list. */
849
+ atom_todo = atom_list[i];
850
+ atom_done = map_atoms[atom_todo];
851
+ sym_index = map_syms[atom_todo];
852
+
853
+ /* skip the atoms in the done list, */
854
+ /* which are easily identified because they map to themselves. */
855
+ if (atom_todo == atom_done) {
856
+ continue;
857
+ }
858
+
859
+ /* look up information about the rotation */
860
+ r_cart = r_carts[sym_index];
861
+ permutation = &permutations[sym_index * num_pos]; /* shape[num_pos] */
862
+
863
+ /* distribute terms from atom_done to atom_todo */
864
+ for (atom_other = 0; atom_other < num_pos; atom_other++) {
865
+ fc2_done =
866
+ fc2[fc_indices_of_atom_list[atom_list_reverse[atom_done]] *
867
+ num_pos +
868
+ permutation[atom_other]];
869
+ fc2_todo = fc2[fc_indices_of_atom_list[i] * num_pos + atom_other];
870
+ for (j = 0; j < 3; j++) {
871
+ for (k = 0; k < 3; k++) {
872
+ for (l = 0; l < 3; l++) {
873
+ for (m = 0; m < 3; m++) {
874
+ /* P' = R^-1 P R */
875
+ fc2_todo[j][k] +=
876
+ r_cart[l][j] * r_cart[m][k] * fc2_done[l][m];
877
+ }
878
+ }
879
+ }
880
+ }
881
+ }
882
+ }
883
+
884
+ free(atom_list_reverse);
885
+ atom_list_reverse = NULL;
886
+ }
887
+
888
+ /* static double get_energy(double temperature, double f){ */
889
+ /* /\* temperature is defined by T (K) *\/ */
890
+ /* /\* 'f' must be given in eV. *\/ */
891
+ /* return f / (exp(f / (KB * temperature)) - 1); */
892
+ /* } */
893
+
894
+ static int nint(const double a) {
895
+ if (a < 0.0)
896
+ return (int)(a - 0.5);
897
+ else
898
+ return (int)(a + 0.5);
899
+ }
phonopy/source/c/phonopy.h ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2021 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file is part of phonopy. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the phonopy project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #ifndef __phonopy_H__
36
+ #define __phonopy_H__
37
+
38
+ #ifdef __cplusplus
39
+ extern "C" {
40
+ #endif
41
+
42
+ #include <stddef.h>
43
+ #include <stdint.h>
44
+
45
+ void phpy_transform_dynmat_to_fc(
46
+ double *fc, const double (*dm)[2], const double (*comm_points)[3],
47
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *masses,
48
+ const int64_t *s2pp_map, const int64_t *fc_index_map,
49
+ const int64_t num_patom, const int64_t num_satomconst, int64_t use_openmp);
50
+ int64_t phpy_dynamical_matrices_with_dd_openmp_over_qpoints(
51
+ double (*dynamical_matrices)[2], const double (*qpoints)[3],
52
+ const int64_t n_qpoints, const double *fc, const double (*svecs)[3],
53
+ const int64_t (*multi)[2], const double (*positions)[3],
54
+ const int64_t num_patom, const int64_t num_satom, const double *masses,
55
+ const int64_t *p2s_map, const int64_t *s2p_map, const double (*born)[3][3],
56
+ const double dielectric[3][3], const double (*reciprocal_lattice)[3],
57
+ const double *q_direction, const double nac_factor,
58
+ const double (*dd_q0)[2], const double (*G_list)[3],
59
+ const int64_t num_G_points, const double lambda, const int64_t use_Wang_NAC,
60
+ const int64_t hermitianize);
61
+ void phpy_get_charge_sum(
62
+ double (*charge_sum)[3][3], const int64_t num_patom,
63
+ const double factor, /* 4pi/V*unit-conv and denominator */
64
+ const double q_cart[3], const double (*born)[3][3]);
65
+ void phpy_get_recip_dipole_dipole(
66
+ double (*dd)[2], /* [natom, 3, natom, 3, (real,imag)] */
67
+ const double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
68
+ const double (*G_list)[3], /* [num_G, 3] */
69
+ const int64_t num_G, const int64_t num_patom, const double q_cart[3],
70
+ const double *q_direction_cart, /* must be pointer */
71
+ const double (*born)[3][3], const double dielectric[3][3],
72
+ const double (*pos)[3], /* [num_patom, 3] */
73
+ const double factor, /* 4pi/V*unit-conv */
74
+ const double lambda, const double tolerance, const int64_t use_openmp);
75
+ void phpy_get_recip_dipole_dipole_q0(
76
+ double (*dd_q0)[2], /* [natom, 3, 3, (real,imag)] */
77
+ const double (*G_list)[3], /* [num_G, 3] */
78
+ const int64_t num_G, const int64_t num_patom, const double (*born)[3][3],
79
+ const double dielectric[3][3], const double (*pos)[3], /* [num_patom, 3] */
80
+ const double lambda, const double tolerance, const int64_t use_openmp);
81
+ void phpy_get_derivative_dynmat_at_q(
82
+ double (*derivative_dynmat)[2], const int64_t num_patom,
83
+ const int64_t num_satom, const double *fc, const double *q,
84
+ const double *lattice, /* column vector */
85
+ const double *reclat, /* column vector */
86
+ const double (*svecs)[3], const int64_t (*multi)[2], const double *mass,
87
+ const int64_t *s2p_map, const int64_t *p2s_map, const double nac_factor,
88
+ const double *born, const double *dielectric, const double *q_direction,
89
+ const int64_t is_nac, const int64_t use_openmp);
90
+ void phpy_get_neighboring_grid_points(
91
+ size_t neighboring_grid_points[], const size_t grid_point,
92
+ const int relative_grid_address[][3], const int num_relative_grid_address,
93
+ const int mesh[3], const int bz_grid_address[][3], const size_t bz_map[]);
94
+ void phpy_get_relative_grid_address(int64_t relative_grid_address[24][4][3],
95
+ const double reciprocal_lattice[3][3]);
96
+ void phpy_get_all_relative_grid_address(
97
+ int64_t relative_grid_address[4][24][4][3]);
98
+ double phpy_get_integration_weight(const double omega,
99
+ const double tetrahedra_omegas[24][4],
100
+ const char function);
101
+ void phpy_get_tetrahedra_frequenies(
102
+ double *freq_tetras, const int64_t mesh[3], const int64_t *grid_points,
103
+ const int64_t (*grid_address)[3], const int64_t (*relative_grid_address)[3],
104
+ const int64_t *gp_ir_index, const double *frequencies,
105
+ const int64_t num_band, const int64_t num_gp);
106
+ void phpy_tetrahedron_method_dos(
107
+ double *dos, const int64_t mesh[3], const int64_t (*grid_address)[3],
108
+ const int64_t (*relative_grid_address)[4][3],
109
+ const int64_t *grid_mapping_table, const double *freq_points,
110
+ const double *frequencies, const double *coef,
111
+ const int64_t num_freq_points, const int64_t num_ir_gp,
112
+ const int64_t num_band, const int64_t num_coef, const int64_t num_gp);
113
+ void phpy_get_thermal_properties(
114
+ double *thermal_props, const double *temperatures, const double *freqs,
115
+ const int64_t *weights, const int64_t num_temp, const int64_t num_qpoints,
116
+ const int64_t num_bands, const double cutoff_frequency, const double KB,
117
+ const int classical);
118
+ void phpy_distribute_fc2(double (*fc2)[3][3], const int *atom_list,
119
+ const int len_atom_list,
120
+ const int *fc_indices_of_atom_list,
121
+ const double (*r_carts)[3][3], const int *permutations,
122
+ const int *map_atoms, const int *map_syms,
123
+ const int num_rot, const int num_pos);
124
+ int phpy_compute_permutation(int *rot_atom, const double lat[3][3],
125
+ const double (*pos)[3], const double (*rot_pos)[3],
126
+ const int num_pos, const double symprec);
127
+ void phpy_set_smallest_vectors_sparse(
128
+ double (*smallest_vectors)[27][3], int *multiplicity,
129
+ const double (*pos_to)[3], const int num_pos_to,
130
+ const double (*pos_from)[3], const int num_pos_from,
131
+ const int (*lattice_points)[3], const int num_lattice_points,
132
+ const double reduced_basis[3][3], const int trans_mat[3][3],
133
+ const double symprec);
134
+ void phpy_set_smallest_vectors_dense(
135
+ double (*smallest_vectors)[3], int64_t (*multiplicity)[2],
136
+ const double (*pos_to)[3], const int64_t num_pos_to,
137
+ const double (*pos_from)[3], const int64_t num_pos_from,
138
+ const int64_t (*lattice_points)[3], const int64_t num_lattice_points,
139
+ const double reduced_basis[3][3], const int64_t trans_mat[3][3],
140
+ const int64_t initialize, const double symprec);
141
+
142
+ void phpy_perm_trans_symmetrize_fc(double *fc, const int nsatom,
143
+ const int level);
144
+ void phpy_perm_trans_symmetrize_compact_fc(double *fc, const int p2s[],
145
+ const int s2pp[],
146
+ const int nsym_list[],
147
+ const int perms[], const int n_satom,
148
+ const int n_patom, const int level);
149
+ void phpy_set_index_permutation_symmetry_compact_fc(
150
+ double *fc, const int p2s[], const int s2pp[], const int nsym_list[],
151
+ const int perms[], const int n_satom, const int n_patom,
152
+ const int is_transpose);
153
+ int64_t phpy_use_openmp(void);
154
+ int64_t phpy_get_max_threads(void);
155
+
156
+ #ifdef __cplusplus
157
+ }
158
+ #endif
159
+
160
+ #endif
phonopy/source/c/rgrid.c ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2015 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file was originally part of spglib and is part of kspclib. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the kspclib project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #include "rgrid.h"
36
+
37
+ #include <assert.h>
38
+ #include <stddef.h>
39
+ #include <stdint.h>
40
+ #include <stdio.h>
41
+
42
+ static int64_t get_double_grid_index(const int64_t address_double[3],
43
+ const int64_t mesh[3]);
44
+ static int64_t get_grid_index_single_mesh(const int64_t address[3],
45
+ const int64_t mesh[3]);
46
+ static void reduce_double_grid_address(int64_t address[3],
47
+ const int64_t mesh[3]);
48
+ static int64_t mat_modulo_l(const int64_t a, const int64_t b);
49
+
50
+ int64_t rgd_get_double_grid_index(const int64_t address_double[3],
51
+ const int64_t mesh[3]) {
52
+ return get_double_grid_index(address_double, mesh);
53
+ }
54
+
55
+ void rgd_get_double_grid_address(int64_t address_double[3],
56
+ const int64_t address[3],
57
+ const int64_t mesh[3],
58
+ const int64_t is_shift[3]) {
59
+ int64_t i;
60
+
61
+ for (i = 0; i < 3; i++) {
62
+ address_double[i] = address[i] * 2 + (is_shift[i] != 0);
63
+ }
64
+ reduce_double_grid_address(address_double, mesh);
65
+ }
66
+
67
+ static int64_t get_double_grid_index(const int64_t address_double[3],
68
+ const int64_t mesh[3]) {
69
+ int64_t i;
70
+ int64_t address[3];
71
+
72
+ for (i = 0; i < 3; i++) {
73
+ if (address_double[i] % 2 == 0) {
74
+ address[i] = address_double[i] / 2;
75
+ } else {
76
+ address[i] = (address_double[i] - 1) / 2;
77
+ }
78
+ address[i] = mat_modulo_l(address[i], mesh[i]);
79
+ }
80
+
81
+ return get_grid_index_single_mesh(address, mesh);
82
+ }
83
+
84
+ static int64_t get_grid_index_single_mesh(const int64_t address[3],
85
+ const int64_t mesh[3]) {
86
+ #ifndef GRID_ORDER_XYZ
87
+ return (address[2] * mesh[0] * (int64_t)(mesh[1]) + address[1] * mesh[0] +
88
+ address[0]);
89
+ #else
90
+ return (address[0] * mesh[1] * (int64_t)(mesh[2]) + address[1] * mesh[2] +
91
+ address[2]);
92
+ #endif
93
+ }
94
+
95
+ static void reduce_double_grid_address(int64_t address[3],
96
+ const int64_t mesh[3]) {
97
+ int64_t i;
98
+
99
+ for (i = 0; i < 3; i++) {
100
+ #ifndef GRID_BOUNDARY_AS_NEGATIVE
101
+ address[i] -= 2 * mesh[i] * (address[i] > mesh[i]);
102
+ #else
103
+ address[i] -= 2 * mesh[i] * (address[i] > mesh[i] - 1);
104
+ #endif
105
+ }
106
+ }
107
+
108
+ static int64_t mat_modulo_l(const int64_t a, const int64_t b) {
109
+ int64_t c;
110
+ c = a % b;
111
+ if (c < 0) {
112
+ c += b;
113
+ }
114
+ return c;
115
+ }
phonopy/source/c/rgrid.h ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2015 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file was originally part of spglib and is part of kspclib. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the kspclib project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #ifndef __rgrid_H__
36
+ #define __rgrid_H__
37
+
38
+ #include <stdint.h>
39
+
40
+ /* #define GRID_ORDER_XYZ */
41
+ /* This changes behaviour of index order of address. */
42
+ /* Without GRID_ORDER_XYZ, left most element of address runs first. */
43
+ /* grid_address (e.g. 4x4x4 mesh, unless GRID_ORDER_XYZ is defined) */
44
+ /* [[ 0 0 0] */
45
+ /* [ 1 0 0] */
46
+ /* [ 2 0 0] */
47
+ /* [-1 0 0] */
48
+ /* [ 0 1 0] */
49
+ /* [ 1 1 0] */
50
+ /* [ 2 1 0] */
51
+ /* [-1 1 0] */
52
+ /* .... ] */
53
+ /* */
54
+ /* With GRID_ORDER_XYZ, right most element of address runs first. */
55
+ /* grid_address (e.g. 4x4x4 mesh, if GRID_ORDER_XYZ is defined) */
56
+ /* [[ 0 0 0] */
57
+ /* [ 0 0 1] */
58
+ /* [ 0 0 2] */
59
+ /* [ 0 0 -1] */
60
+ /* [ 0 1 0] */
61
+ /* [ 0 1 1] */
62
+ /* [ 0 1 2] */
63
+ /* [ 0 1 -1] */
64
+ /* .... ] */
65
+
66
+ /* #define GRID_BOUNDARY_AS_NEGATIVE */
67
+ /* This changes the behaviour of address elements on the surface of */
68
+ /* parallelepiped. */
69
+ /* For odd mesh number, this affects nothing, e.g., [-2, -1, 0, 1, 2]. */
70
+ /* regardless of with and without GRID_BOUNDARY_AS_NEGATIVE. */
71
+ /* For even mesh number, this affects as follows: */
72
+ /* without GRID_BOUNDARY_AS_NEGATIVE, e.g., [-2, -1, 0, 1, 2, 3]. */
73
+ /* with GRID_BOUNDARY_AS_NEGATIVE, e.g., [-3, -2, -1, 0, 1, 2]. */
74
+
75
+ int64_t rgd_get_double_grid_index(const int64_t address_double[3],
76
+ const int64_t mesh[3]);
77
+ void rgd_get_double_grid_address(int64_t address_double[3],
78
+ const int64_t address[3],
79
+ const int64_t mesh[3],
80
+ const int64_t is_shift[3]);
81
+
82
+ #endif
phonopy/source/c/tetrahedron_method.c ADDED
@@ -0,0 +1,1455 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2014 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file was originally part of spglib and is part of kspclib. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the kspclib project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+ /* tetrahedron_method.c */
35
+ /* Copyright (C) 2014 Atsushi Togo */
36
+
37
+ #include "tetrahedron_method.h"
38
+
39
+ #include <stddef.h>
40
+ #include <stdint.h>
41
+
42
+ #ifdef THMWARNING
43
+ #include <stdio.h>
44
+ #define warning_print(...) fprintf(stderr, __VA_ARGS__)
45
+ #else
46
+ #define warning_print(...)
47
+ #endif
48
+
49
+ #ifdef THM_EPSILON
50
+ #include <math.h>
51
+ #endif
52
+
53
+ /* 6-------7 */
54
+ /* /| /| */
55
+ /* / | / | */
56
+ /* 4-------5 | */
57
+ /* | 2----|--3 */
58
+ /* | / | / */
59
+ /* |/ |/ */
60
+ /* 0-------1 */
61
+ /* */
62
+ /* i: vec neighbours */
63
+ /* 0: O 1, 2, 4 */
64
+ /* 1: a 0, 3, 5 */
65
+ /* 2: b 0, 3, 6 */
66
+ /* 3: a + b 1, 2, 7 */
67
+ /* 4: c 0, 5, 6 */
68
+ /* 5: c + a 1, 4, 7 */
69
+ /* 6: c + b 2, 4, 7 */
70
+ /* 7: c + a + b 3, 5, 6 */
71
+
72
+ static int64_t main_diagonals[4][3] = {{1, 1, 1}, /* 0-7 */
73
+ {-1, 1, 1}, /* 1-6 */
74
+ {1, -1, 1}, /* 2-5 */
75
+ {1, 1, -1}}; /* 3-4 */
76
+
77
+ static int64_t db_relative_grid_address[4][24][4][3] = {
78
+ {
79
+ {
80
+ {0, 0, 0},
81
+ {1, 0, 0},
82
+ {1, 1, 0},
83
+ {1, 1, 1},
84
+ },
85
+ {
86
+ {0, 0, 0},
87
+ {1, 0, 0},
88
+ {1, 0, 1},
89
+ {1, 1, 1},
90
+ },
91
+ {
92
+ {0, 0, 0},
93
+ {0, 1, 0},
94
+ {1, 1, 0},
95
+ {1, 1, 1},
96
+ },
97
+ {
98
+ {0, 0, 0},
99
+ {0, 1, 0},
100
+ {0, 1, 1},
101
+ {1, 1, 1},
102
+ },
103
+ {
104
+ {0, 0, 0},
105
+ {0, 0, 1},
106
+ {1, 0, 1},
107
+ {1, 1, 1},
108
+ },
109
+ {
110
+ {0, 0, 0},
111
+ {0, 0, 1},
112
+ {0, 1, 1},
113
+ {1, 1, 1},
114
+ },
115
+ {
116
+ {0, 0, 0},
117
+ {0, 1, 0},
118
+ {0, 1, 1},
119
+ {-1, 0, 0},
120
+ },
121
+ {
122
+ {0, 0, 0},
123
+ {0, 0, 1},
124
+ {0, 1, 1},
125
+ {-1, 0, 0},
126
+ },
127
+ {
128
+ {0, 0, 0},
129
+ {1, 0, 0},
130
+ {1, 0, 1},
131
+ {0, -1, 0},
132
+ },
133
+ {
134
+ {0, 0, 0},
135
+ {0, 0, 1},
136
+ {1, 0, 1},
137
+ {0, -1, 0},
138
+ },
139
+ {
140
+ {0, 0, 0},
141
+ {0, 0, 1},
142
+ {-1, -1, 0},
143
+ {0, -1, 0},
144
+ },
145
+ {
146
+ {0, 0, 0},
147
+ {0, 0, 1},
148
+ {-1, -1, 0},
149
+ {-1, 0, 0},
150
+ },
151
+ {
152
+ {0, 0, 0},
153
+ {1, 0, 0},
154
+ {1, 1, 0},
155
+ {0, 0, -1},
156
+ },
157
+ {
158
+ {0, 0, 0},
159
+ {0, 1, 0},
160
+ {1, 1, 0},
161
+ {0, 0, -1},
162
+ },
163
+ {
164
+ {0, 0, 0},
165
+ {0, 1, 0},
166
+ {-1, 0, -1},
167
+ {0, 0, -1},
168
+ },
169
+ {
170
+ {0, 0, 0},
171
+ {0, 1, 0},
172
+ {-1, 0, -1},
173
+ {-1, 0, 0},
174
+ },
175
+ {
176
+ {0, 0, 0},
177
+ {1, 0, 0},
178
+ {0, -1, -1},
179
+ {0, 0, -1},
180
+ },
181
+ {
182
+ {0, 0, 0},
183
+ {1, 0, 0},
184
+ {0, -1, -1},
185
+ {0, -1, 0},
186
+ },
187
+ {
188
+ {0, 0, 0},
189
+ {-1, -1, -1},
190
+ {0, -1, -1},
191
+ {0, 0, -1},
192
+ },
193
+ {
194
+ {0, 0, 0},
195
+ {-1, -1, -1},
196
+ {0, -1, -1},
197
+ {0, -1, 0},
198
+ },
199
+ {
200
+ {0, 0, 0},
201
+ {-1, -1, -1},
202
+ {-1, 0, -1},
203
+ {0, 0, -1},
204
+ },
205
+ {
206
+ {0, 0, 0},
207
+ {-1, -1, -1},
208
+ {-1, 0, -1},
209
+ {-1, 0, 0},
210
+ },
211
+ {
212
+ {0, 0, 0},
213
+ {-1, -1, -1},
214
+ {-1, -1, 0},
215
+ {0, -1, 0},
216
+ },
217
+ {
218
+ {0, 0, 0},
219
+ {-1, -1, -1},
220
+ {-1, -1, 0},
221
+ {-1, 0, 0},
222
+ },
223
+ },
224
+ {
225
+ {
226
+ {0, 0, 0},
227
+ {1, 0, 0},
228
+ {0, 1, 0},
229
+ {0, 1, 1},
230
+ },
231
+ {
232
+ {0, 0, 0},
233
+ {1, 0, 0},
234
+ {0, 0, 1},
235
+ {0, 1, 1},
236
+ },
237
+ {
238
+ {0, 0, 0},
239
+ {-1, 1, 0},
240
+ {-1, 1, 1},
241
+ {-1, 0, 0},
242
+ },
243
+ {
244
+ {0, 0, 0},
245
+ {-1, 0, 1},
246
+ {-1, 1, 1},
247
+ {-1, 0, 0},
248
+ },
249
+ {
250
+ {0, 0, 0},
251
+ {-1, 1, 0},
252
+ {0, 1, 0},
253
+ {-1, 1, 1},
254
+ },
255
+ {
256
+ {0, 0, 0},
257
+ {0, 1, 0},
258
+ {-1, 1, 1},
259
+ {0, 1, 1},
260
+ },
261
+ {
262
+ {0, 0, 0},
263
+ {-1, 0, 1},
264
+ {0, 0, 1},
265
+ {-1, 1, 1},
266
+ },
267
+ {
268
+ {0, 0, 0},
269
+ {0, 0, 1},
270
+ {-1, 1, 1},
271
+ {0, 1, 1},
272
+ },
273
+ {
274
+ {0, 0, 0},
275
+ {0, 0, 1},
276
+ {0, -1, 0},
277
+ {1, -1, 0},
278
+ },
279
+ {
280
+ {0, 0, 0},
281
+ {1, 0, 0},
282
+ {0, 0, 1},
283
+ {1, -1, 0},
284
+ },
285
+ {
286
+ {0, 0, 0},
287
+ {-1, 0, 1},
288
+ {0, -1, 0},
289
+ {-1, 0, 0},
290
+ },
291
+ {
292
+ {0, 0, 0},
293
+ {-1, 0, 1},
294
+ {0, 0, 1},
295
+ {0, -1, 0},
296
+ },
297
+ {
298
+ {0, 0, 0},
299
+ {0, 1, 0},
300
+ {0, 0, -1},
301
+ {1, 0, -1},
302
+ },
303
+ {
304
+ {0, 0, 0},
305
+ {1, 0, 0},
306
+ {0, 1, 0},
307
+ {1, 0, -1},
308
+ },
309
+ {
310
+ {0, 0, 0},
311
+ {-1, 1, 0},
312
+ {0, 0, -1},
313
+ {-1, 0, 0},
314
+ },
315
+ {
316
+ {0, 0, 0},
317
+ {-1, 1, 0},
318
+ {0, 1, 0},
319
+ {0, 0, -1},
320
+ },
321
+ {
322
+ {0, 0, 0},
323
+ {0, -1, -1},
324
+ {1, -1, -1},
325
+ {0, 0, -1},
326
+ },
327
+ {
328
+ {0, 0, 0},
329
+ {0, -1, -1},
330
+ {1, -1, -1},
331
+ {0, -1, 0},
332
+ },
333
+ {
334
+ {0, 0, 0},
335
+ {1, -1, -1},
336
+ {0, 0, -1},
337
+ {1, 0, -1},
338
+ },
339
+ {
340
+ {0, 0, 0},
341
+ {1, 0, 0},
342
+ {1, -1, -1},
343
+ {1, 0, -1},
344
+ },
345
+ {
346
+ {0, 0, 0},
347
+ {1, -1, -1},
348
+ {0, -1, 0},
349
+ {1, -1, 0},
350
+ },
351
+ {
352
+ {0, 0, 0},
353
+ {1, 0, 0},
354
+ {1, -1, -1},
355
+ {1, -1, 0},
356
+ },
357
+ {
358
+ {0, 0, 0},
359
+ {0, -1, -1},
360
+ {0, 0, -1},
361
+ {-1, 0, 0},
362
+ },
363
+ {
364
+ {0, 0, 0},
365
+ {0, -1, -1},
366
+ {0, -1, 0},
367
+ {-1, 0, 0},
368
+ },
369
+ },
370
+ {
371
+ {
372
+ {0, 0, 0},
373
+ {1, 0, 0},
374
+ {0, 1, 0},
375
+ {1, 0, 1},
376
+ },
377
+ {
378
+ {0, 0, 0},
379
+ {0, 1, 0},
380
+ {0, 0, 1},
381
+ {1, 0, 1},
382
+ },
383
+ {
384
+ {0, 0, 0},
385
+ {-1, 1, 0},
386
+ {0, 0, 1},
387
+ {-1, 0, 0},
388
+ },
389
+ {
390
+ {0, 0, 0},
391
+ {-1, 1, 0},
392
+ {0, 1, 0},
393
+ {0, 0, 1},
394
+ },
395
+ {
396
+ {0, 0, 0},
397
+ {1, -1, 1},
398
+ {0, -1, 0},
399
+ {1, -1, 0},
400
+ },
401
+ {
402
+ {0, 0, 0},
403
+ {0, -1, 1},
404
+ {1, -1, 1},
405
+ {0, -1, 0},
406
+ },
407
+ {
408
+ {0, 0, 0},
409
+ {1, 0, 0},
410
+ {1, -1, 1},
411
+ {1, -1, 0},
412
+ },
413
+ {
414
+ {0, 0, 0},
415
+ {1, 0, 0},
416
+ {1, -1, 1},
417
+ {1, 0, 1},
418
+ },
419
+ {
420
+ {0, 0, 0},
421
+ {0, -1, 1},
422
+ {1, -1, 1},
423
+ {0, 0, 1},
424
+ },
425
+ {
426
+ {0, 0, 0},
427
+ {1, -1, 1},
428
+ {0, 0, 1},
429
+ {1, 0, 1},
430
+ },
431
+ {
432
+ {0, 0, 0},
433
+ {0, -1, 1},
434
+ {0, -1, 0},
435
+ {-1, 0, 0},
436
+ },
437
+ {
438
+ {0, 0, 0},
439
+ {0, -1, 1},
440
+ {0, 0, 1},
441
+ {-1, 0, 0},
442
+ },
443
+ {
444
+ {0, 0, 0},
445
+ {1, 0, 0},
446
+ {0, 0, -1},
447
+ {0, 1, -1},
448
+ },
449
+ {
450
+ {0, 0, 0},
451
+ {1, 0, 0},
452
+ {0, 1, 0},
453
+ {0, 1, -1},
454
+ },
455
+ {
456
+ {0, 0, 0},
457
+ {-1, 0, -1},
458
+ {0, 0, -1},
459
+ {-1, 1, -1},
460
+ },
461
+ {
462
+ {0, 0, 0},
463
+ {-1, 0, -1},
464
+ {-1, 1, -1},
465
+ {-1, 0, 0},
466
+ },
467
+ {
468
+ {0, 0, 0},
469
+ {0, 0, -1},
470
+ {-1, 1, -1},
471
+ {0, 1, -1},
472
+ },
473
+ {
474
+ {0, 0, 0},
475
+ {0, 1, 0},
476
+ {-1, 1, -1},
477
+ {0, 1, -1},
478
+ },
479
+ {
480
+ {0, 0, 0},
481
+ {-1, 1, 0},
482
+ {-1, 1, -1},
483
+ {-1, 0, 0},
484
+ },
485
+ {
486
+ {0, 0, 0},
487
+ {-1, 1, 0},
488
+ {0, 1, 0},
489
+ {-1, 1, -1},
490
+ },
491
+ {
492
+ {0, 0, 0},
493
+ {0, 0, -1},
494
+ {0, -1, 0},
495
+ {1, -1, 0},
496
+ },
497
+ {
498
+ {0, 0, 0},
499
+ {1, 0, 0},
500
+ {0, 0, -1},
501
+ {1, -1, 0},
502
+ },
503
+ {
504
+ {0, 0, 0},
505
+ {-1, 0, -1},
506
+ {0, 0, -1},
507
+ {0, -1, 0},
508
+ },
509
+ {
510
+ {0, 0, 0},
511
+ {-1, 0, -1},
512
+ {0, -1, 0},
513
+ {-1, 0, 0},
514
+ },
515
+ },
516
+ {
517
+ {
518
+ {0, 0, 0},
519
+ {1, 0, 0},
520
+ {1, 1, 0},
521
+ {0, 0, 1},
522
+ },
523
+ {
524
+ {0, 0, 0},
525
+ {0, 1, 0},
526
+ {1, 1, 0},
527
+ {0, 0, 1},
528
+ },
529
+ {
530
+ {0, 0, 0},
531
+ {0, 1, 0},
532
+ {-1, 0, 1},
533
+ {-1, 0, 0},
534
+ },
535
+ {
536
+ {0, 0, 0},
537
+ {0, 1, 0},
538
+ {-1, 0, 1},
539
+ {0, 0, 1},
540
+ },
541
+ {
542
+ {0, 0, 0},
543
+ {1, 0, 0},
544
+ {0, -1, 1},
545
+ {0, -1, 0},
546
+ },
547
+ {
548
+ {0, 0, 0},
549
+ {1, 0, 0},
550
+ {0, -1, 1},
551
+ {0, 0, 1},
552
+ },
553
+ {
554
+ {0, 0, 0},
555
+ {-1, -1, 1},
556
+ {-1, -1, 0},
557
+ {0, -1, 0},
558
+ },
559
+ {
560
+ {0, 0, 0},
561
+ {-1, -1, 1},
562
+ {-1, -1, 0},
563
+ {-1, 0, 0},
564
+ },
565
+ {
566
+ {0, 0, 0},
567
+ {-1, -1, 1},
568
+ {0, -1, 1},
569
+ {0, -1, 0},
570
+ },
571
+ {
572
+ {0, 0, 0},
573
+ {-1, -1, 1},
574
+ {-1, 0, 1},
575
+ {-1, 0, 0},
576
+ },
577
+ {
578
+ {0, 0, 0},
579
+ {-1, -1, 1},
580
+ {0, -1, 1},
581
+ {0, 0, 1},
582
+ },
583
+ {
584
+ {0, 0, 0},
585
+ {-1, -1, 1},
586
+ {-1, 0, 1},
587
+ {0, 0, 1},
588
+ },
589
+ {
590
+ {0, 0, 0},
591
+ {0, 0, -1},
592
+ {1, 0, -1},
593
+ {1, 1, -1},
594
+ },
595
+ {
596
+ {0, 0, 0},
597
+ {0, 0, -1},
598
+ {0, 1, -1},
599
+ {1, 1, -1},
600
+ },
601
+ {
602
+ {0, 0, 0},
603
+ {1, 0, 0},
604
+ {1, 0, -1},
605
+ {1, 1, -1},
606
+ },
607
+ {
608
+ {0, 0, 0},
609
+ {0, 1, 0},
610
+ {0, 1, -1},
611
+ {1, 1, -1},
612
+ },
613
+ {
614
+ {0, 0, 0},
615
+ {1, 0, 0},
616
+ {1, 1, 0},
617
+ {1, 1, -1},
618
+ },
619
+ {
620
+ {0, 0, 0},
621
+ {0, 1, 0},
622
+ {1, 1, 0},
623
+ {1, 1, -1},
624
+ },
625
+ {
626
+ {0, 0, 0},
627
+ {0, 0, -1},
628
+ {0, 1, -1},
629
+ {-1, 0, 0},
630
+ },
631
+ {
632
+ {0, 0, 0},
633
+ {0, 1, 0},
634
+ {0, 1, -1},
635
+ {-1, 0, 0},
636
+ },
637
+ {
638
+ {0, 0, 0},
639
+ {0, 0, -1},
640
+ {1, 0, -1},
641
+ {0, -1, 0},
642
+ },
643
+ {
644
+ {0, 0, 0},
645
+ {1, 0, 0},
646
+ {1, 0, -1},
647
+ {0, -1, 0},
648
+ },
649
+ {
650
+ {0, 0, 0},
651
+ {0, 0, -1},
652
+ {-1, -1, 0},
653
+ {0, -1, 0},
654
+ },
655
+ {
656
+ {0, 0, 0},
657
+ {0, 0, -1},
658
+ {-1, -1, 0},
659
+ {-1, 0, 0},
660
+ },
661
+ },
662
+ };
663
+
664
+ static double get_integration_weight(
665
+ const double omega, const double tetrahedra_omegas[24][4],
666
+ double (*gn)(const int64_t, const double, const double[4]),
667
+ double (*IJ)(const int64_t, const int64_t, const double, const double[4]));
668
+ static int64_t get_main_diagonal(const double rec_lattice[3][3]);
669
+ static int64_t sort_omegas(double v[4]);
670
+ static double norm_squared_d3(const double a[3]);
671
+ static void multiply_matrix_vector_dl3(double v[3], const double a[3][3],
672
+ const int64_t b[3]);
673
+ static double _f(const int64_t n, const int64_t m, const double omega,
674
+ const double vertices_omegas[4]);
675
+ static double _J(const int64_t i, const int64_t ci, const double omega,
676
+ const double vertices_omegas[4]);
677
+ static double _I(const int64_t i, const int64_t ci, const double omega,
678
+ const double vertices_omegas[4]);
679
+ static double _n(const int64_t i, const double omega,
680
+ const double vertices_omegas[4]);
681
+ static double _g(const int64_t i, const double omega,
682
+ const double vertices_omegas[4]);
683
+ static double _n_0(void);
684
+ static double _n_1(const double omega, const double vertices_omegas[4]);
685
+ static double _n_2(const double omega, const double vertices_omegas[4]);
686
+ static double _n_3(const double omega, const double vertices_omegas[4]);
687
+ static double _n_4(void);
688
+ static double _g_0(void);
689
+ static double _g_1(const double omega, const double vertices_omegas[4]);
690
+ static double _g_2(const double omega, const double vertices_omegas[4]);
691
+ static double _g_3(const double omega, const double vertices_omegas[4]);
692
+ static double _g_4(void);
693
+ static double _J_0(void);
694
+ static double _J_10(const double omega, const double vertices_omegas[4]);
695
+ static double _J_11(const double omega, const double vertices_omegas[4]);
696
+ static double _J_12(const double omega, const double vertices_omegas[4]);
697
+ static double _J_13(const double omega, const double vertices_omegas[4]);
698
+ static double _J_20(const double omega, const double vertices_omegas[4]);
699
+ static double _J_21(const double omega, const double vertices_omegas[4]);
700
+ static double _J_22(const double omega, const double vertices_omegas[4]);
701
+ static double _J_23(const double omega, const double vertices_omegas[4]);
702
+ static double _J_30(const double omega, const double vertices_omegas[4]);
703
+ static double _J_31(const double omega, const double vertices_omegas[4]);
704
+ static double _J_32(const double omega, const double vertices_omegas[4]);
705
+ static double _J_33(const double omega, const double vertices_omegas[4]);
706
+ static double _J_4(void);
707
+ static double _I_0(void);
708
+ static double _I_10(const double omega, const double vertices_omegas[4]);
709
+ static double _I_11(const double omega, const double vertices_omegas[4]);
710
+ static double _I_12(const double omega, const double vertices_omegas[4]);
711
+ static double _I_13(const double omega, const double vertices_omegas[4]);
712
+ static double _I_20(const double omega, const double vertices_omegas[4]);
713
+ static double _I_21(const double omega, const double vertices_omegas[4]);
714
+ static double _I_22(const double omega, const double vertices_omegas[4]);
715
+ static double _I_23(const double omega, const double vertices_omegas[4]);
716
+ static double _I_30(const double omega, const double vertices_omegas[4]);
717
+ static double _I_31(const double omega, const double vertices_omegas[4]);
718
+ static double _I_32(const double omega, const double vertices_omegas[4]);
719
+ static double _I_33(const double omega, const double vertices_omegas[4]);
720
+ static double _I_4(void);
721
+
722
+ void thm_get_relative_grid_address(int64_t relative_grid_address[24][4][3],
723
+ const double rec_lattice[3][3]) {
724
+ int64_t i, j, k, main_diag_index;
725
+
726
+ main_diag_index = get_main_diagonal(rec_lattice);
727
+
728
+ for (i = 0; i < 24; i++) {
729
+ for (j = 0; j < 4; j++) {
730
+ for (k = 0; k < 3; k++) {
731
+ relative_grid_address[i][j][k] =
732
+ db_relative_grid_address[main_diag_index][i][j][k];
733
+ }
734
+ }
735
+ }
736
+ }
737
+
738
+ void thm_get_all_relative_grid_address(
739
+ int64_t relative_grid_address[4][24][4][3]) {
740
+ int64_t i, j, k, main_diag_index;
741
+
742
+ for (main_diag_index = 0; main_diag_index < 4; main_diag_index++) {
743
+ for (i = 0; i < 24; i++) {
744
+ for (j = 0; j < 4; j++) {
745
+ for (k = 0; k < 3; k++) {
746
+ relative_grid_address[main_diag_index][i][j][k] =
747
+ db_relative_grid_address[main_diag_index][i][j][k];
748
+ }
749
+ }
750
+ }
751
+ }
752
+ }
753
+
754
+ double thm_get_integration_weight(const double omega,
755
+ const double tetrahedra_omegas[24][4],
756
+ const char function) {
757
+ if (function == 'I') {
758
+ return get_integration_weight(omega, tetrahedra_omegas, _g, _I);
759
+ } else {
760
+ return get_integration_weight(omega, tetrahedra_omegas, _n, _J);
761
+ }
762
+ }
763
+
764
+ int64_t thm_in_tetrahedra(const double f0, const double freq_vertices[24][4]) {
765
+ int64_t i, j;
766
+ double fmin, fmax;
767
+
768
+ fmin = freq_vertices[0][0];
769
+ fmax = freq_vertices[0][0];
770
+
771
+ for (i = 0; i < 24; i++) {
772
+ for (j = 0; j < 4; j++) {
773
+ if (fmin > freq_vertices[i][j]) {
774
+ fmin = freq_vertices[i][j];
775
+ }
776
+ if (fmax < freq_vertices[i][j]) {
777
+ fmax = freq_vertices[i][j];
778
+ }
779
+ }
780
+ }
781
+
782
+ if (fmin > f0 || fmax < f0) {
783
+ return 0;
784
+ } else {
785
+ return 1;
786
+ }
787
+ }
788
+
789
+ static double get_integration_weight(
790
+ const double omega, const double tetrahedra_omegas[24][4],
791
+ double (*gn)(const int64_t, const double, const double[4]),
792
+ double (*IJ)(const int64_t, const int64_t, const double, const double[4])) {
793
+ int64_t i, j, ci;
794
+ double sum;
795
+ double v[4];
796
+
797
+ sum = 0;
798
+ for (i = 0; i < 24; i++) {
799
+ for (j = 0; j < 4; j++) {
800
+ v[j] = tetrahedra_omegas[i][j];
801
+ }
802
+ ci = sort_omegas(v);
803
+ if (omega < v[0]) {
804
+ sum += IJ(0, ci, omega, v) * gn(0, omega, v);
805
+ } else {
806
+ if (v[0] < omega && omega < v[1]) {
807
+ sum += IJ(1, ci, omega, v) * gn(1, omega, v);
808
+ } else {
809
+ if (v[1] < omega && omega < v[2]) {
810
+ sum += IJ(2, ci, omega, v) * gn(2, omega, v);
811
+ } else {
812
+ if (v[2] < omega && omega < v[3]) {
813
+ sum += IJ(3, ci, omega, v) * gn(3, omega, v);
814
+ } else {
815
+ if (v[3] < omega) {
816
+ sum += IJ(4, ci, omega, v) * gn(4, omega, v);
817
+ }
818
+ }
819
+ }
820
+ }
821
+ }
822
+ }
823
+ return sum / 6;
824
+ }
825
+
826
+ static int64_t sort_omegas(double v[4]) {
827
+ int64_t i;
828
+ double w[4];
829
+
830
+ i = 0;
831
+
832
+ if (v[0] > v[1]) {
833
+ w[0] = v[1];
834
+ w[1] = v[0];
835
+ i = 1;
836
+ } else {
837
+ w[0] = v[0];
838
+ w[1] = v[1];
839
+ }
840
+
841
+ if (v[2] > v[3]) {
842
+ w[2] = v[3];
843
+ w[3] = v[2];
844
+ } else {
845
+ w[2] = v[2];
846
+ w[3] = v[3];
847
+ }
848
+
849
+ if (w[0] > w[2]) {
850
+ v[0] = w[2];
851
+ v[1] = w[0];
852
+ if (i == 0) {
853
+ i = 4;
854
+ }
855
+ } else {
856
+ v[0] = w[0];
857
+ v[1] = w[2];
858
+ }
859
+
860
+ if (w[1] > w[3]) {
861
+ v[3] = w[1];
862
+ v[2] = w[3];
863
+ if (i == 1) {
864
+ i = 3;
865
+ }
866
+ } else {
867
+ v[3] = w[3];
868
+ v[2] = w[1];
869
+ if (i == 1) {
870
+ i = 5;
871
+ }
872
+ }
873
+
874
+ if (v[1] > v[2]) {
875
+ w[1] = v[1];
876
+ v[1] = v[2];
877
+ v[2] = w[1];
878
+ if (i == 4) {
879
+ i = 2;
880
+ }
881
+ if (i == 5) {
882
+ i = 1;
883
+ }
884
+ } else {
885
+ if (i == 4) {
886
+ i = 1;
887
+ }
888
+ if (i == 5) {
889
+ i = 2;
890
+ }
891
+ }
892
+ return i;
893
+ }
894
+
895
+ static int64_t get_main_diagonal(const double rec_lattice[3][3]) {
896
+ int64_t i, shortest;
897
+ double length, min_length;
898
+ double main_diag[3];
899
+
900
+ shortest = 0;
901
+ multiply_matrix_vector_dl3(main_diag, rec_lattice, main_diagonals[0]);
902
+ min_length = norm_squared_d3(main_diag);
903
+ for (i = 1; i < 4; i++) {
904
+ multiply_matrix_vector_dl3(main_diag, rec_lattice, main_diagonals[i]);
905
+ length = norm_squared_d3(main_diag);
906
+ if (min_length > length) {
907
+ min_length = length;
908
+ shortest = i;
909
+ }
910
+ }
911
+ return shortest;
912
+ }
913
+
914
+ static double norm_squared_d3(const double a[3]) {
915
+ return a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
916
+ }
917
+
918
+ static void multiply_matrix_vector_dl3(double v[3], const double a[3][3],
919
+ const int64_t b[3]) {
920
+ int64_t i;
921
+ double c[3];
922
+
923
+ for (i = 0; i < 3; i++) {
924
+ c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
925
+ }
926
+
927
+ for (i = 0; i < 3; i++) {
928
+ v[i] = c[i];
929
+ }
930
+ }
931
+
932
+ static double _f(const int64_t n, const int64_t m, const double omega,
933
+ const double vertices_omegas[4]) {
934
+ double delta;
935
+ delta = vertices_omegas[n] - vertices_omegas[m];
936
+
937
+ #ifdef THM_EPSILON
938
+ if (fabs(delta) < THM_EPSILON) {
939
+ return 0;
940
+ }
941
+ #endif
942
+
943
+ return ((omega - vertices_omegas[m]) / delta);
944
+ }
945
+
946
+ static double _J(const int64_t i, const int64_t ci, const double omega,
947
+ const double vertices_omegas[4]) {
948
+ switch (i) {
949
+ case 0:
950
+ return _J_0();
951
+ case 1:
952
+ switch (ci) {
953
+ case 0:
954
+ return _J_10(omega, vertices_omegas);
955
+ case 1:
956
+ return _J_11(omega, vertices_omegas);
957
+ case 2:
958
+ return _J_12(omega, vertices_omegas);
959
+ case 3:
960
+ return _J_13(omega, vertices_omegas);
961
+ }
962
+ case 2:
963
+ switch (ci) {
964
+ case 0:
965
+ return _J_20(omega, vertices_omegas);
966
+ case 1:
967
+ return _J_21(omega, vertices_omegas);
968
+ case 2:
969
+ return _J_22(omega, vertices_omegas);
970
+ case 3:
971
+ return _J_23(omega, vertices_omegas);
972
+ }
973
+ case 3:
974
+ switch (ci) {
975
+ case 0:
976
+ return _J_30(omega, vertices_omegas);
977
+ case 1:
978
+ return _J_31(omega, vertices_omegas);
979
+ case 2:
980
+ return _J_32(omega, vertices_omegas);
981
+ case 3:
982
+ return _J_33(omega, vertices_omegas);
983
+ }
984
+ case 4:
985
+ return _J_4();
986
+ }
987
+
988
+ warning_print("******* Warning *******\n");
989
+ warning_print(" J is something wrong. \n");
990
+ warning_print("******* Warning *******\n");
991
+ warning_print("(line %d, %s).\n", __LINE__, __FILE__);
992
+
993
+ return 0;
994
+ }
995
+
996
+ static double _I(const int64_t i, const int64_t ci, const double omega,
997
+ const double vertices_omegas[4]) {
998
+ switch (i) {
999
+ case 0:
1000
+ return _I_0();
1001
+ case 1:
1002
+ switch (ci) {
1003
+ case 0:
1004
+ return _I_10(omega, vertices_omegas);
1005
+ case 1:
1006
+ return _I_11(omega, vertices_omegas);
1007
+ case 2:
1008
+ return _I_12(omega, vertices_omegas);
1009
+ case 3:
1010
+ return _I_13(omega, vertices_omegas);
1011
+ }
1012
+ case 2:
1013
+ switch (ci) {
1014
+ case 0:
1015
+ return _I_20(omega, vertices_omegas);
1016
+ case 1:
1017
+ return _I_21(omega, vertices_omegas);
1018
+ case 2:
1019
+ return _I_22(omega, vertices_omegas);
1020
+ case 3:
1021
+ return _I_23(omega, vertices_omegas);
1022
+ }
1023
+ case 3:
1024
+ switch (ci) {
1025
+ case 0:
1026
+ return _I_30(omega, vertices_omegas);
1027
+ case 1:
1028
+ return _I_31(omega, vertices_omegas);
1029
+ case 2:
1030
+ return _I_32(omega, vertices_omegas);
1031
+ case 3:
1032
+ return _I_33(omega, vertices_omegas);
1033
+ }
1034
+ case 4:
1035
+ return _I_4();
1036
+ }
1037
+
1038
+ warning_print("******* Warning *******\n");
1039
+ warning_print(" I is something wrong. \n");
1040
+ warning_print("******* Warning *******\n");
1041
+ warning_print("(line %d, %s).\n", __LINE__, __FILE__);
1042
+
1043
+ return 0;
1044
+ }
1045
+
1046
+ static double _n(const int64_t i, const double omega,
1047
+ const double vertices_omegas[4]) {
1048
+ switch (i) {
1049
+ case 0:
1050
+ return _n_0();
1051
+ case 1:
1052
+ return _n_1(omega, vertices_omegas);
1053
+ case 2:
1054
+ return _n_2(omega, vertices_omegas);
1055
+ case 3:
1056
+ return _n_3(omega, vertices_omegas);
1057
+ case 4:
1058
+ return _n_4();
1059
+ }
1060
+
1061
+ warning_print("******* Warning *******\n");
1062
+ warning_print(" n is something wrong. \n");
1063
+ warning_print("******* Warning *******\n");
1064
+ warning_print("(line %d, %s).\n", __LINE__, __FILE__);
1065
+
1066
+ return 0;
1067
+ }
1068
+
1069
+ static double _g(const int64_t i, const double omega,
1070
+ const double vertices_omegas[4]) {
1071
+ switch (i) {
1072
+ case 0:
1073
+ return _g_0();
1074
+ case 1:
1075
+ return _g_1(omega, vertices_omegas);
1076
+ case 2:
1077
+ return _g_2(omega, vertices_omegas);
1078
+ case 3:
1079
+ return _g_3(omega, vertices_omegas);
1080
+ case 4:
1081
+ return _g_4();
1082
+ }
1083
+
1084
+ warning_print("******* Warning *******\n");
1085
+ warning_print(" g is something wrong. \n");
1086
+ warning_print("******* Warning *******\n");
1087
+ warning_print("(line %d, %s).\n", __LINE__, __FILE__);
1088
+
1089
+ return 0;
1090
+ }
1091
+
1092
+ /* omega < omega1 */
1093
+ static double _n_0(void) { return 0.0; }
1094
+
1095
+ /* omega1 < omega < omega2 */
1096
+ static double _n_1(const double omega, const double vertices_omegas[4]) {
1097
+ return (_f(1, 0, omega, vertices_omegas) *
1098
+ _f(2, 0, omega, vertices_omegas) *
1099
+ _f(3, 0, omega, vertices_omegas));
1100
+ }
1101
+
1102
+ /* omega2 < omega < omega3 */
1103
+ static double _n_2(const double omega, const double vertices_omegas[4]) {
1104
+ return (
1105
+ _f(3, 1, omega, vertices_omegas) * _f(2, 1, omega, vertices_omegas) +
1106
+ _f(3, 0, omega, vertices_omegas) * _f(1, 3, omega, vertices_omegas) *
1107
+ _f(2, 1, omega, vertices_omegas) +
1108
+ _f(3, 0, omega, vertices_omegas) * _f(2, 0, omega, vertices_omegas) *
1109
+ _f(1, 2, omega, vertices_omegas));
1110
+ }
1111
+
1112
+ /* omega2 < omega < omega3 */
1113
+ static double _n_3(const double omega, const double vertices_omegas[4]) {
1114
+ return (1.0 - _f(0, 3, omega, vertices_omegas) *
1115
+ _f(1, 3, omega, vertices_omegas) *
1116
+ _f(2, 3, omega, vertices_omegas));
1117
+ }
1118
+
1119
+ /* omega4 < omega */
1120
+ static double _n_4(void) { return 1.0; }
1121
+
1122
+ /* omega < omega1 */
1123
+ static double _g_0(void) { return 0.0; }
1124
+
1125
+ /* omega1 < omega < omega2 */
1126
+ static double _g_1(const double omega, const double vertices_omegas[4]) {
1127
+ return (3 * _f(1, 0, omega, vertices_omegas) *
1128
+ _f(2, 0, omega, vertices_omegas) /
1129
+ (vertices_omegas[3] - vertices_omegas[0]));
1130
+ }
1131
+
1132
+ /* omega2 < omega < omega3 */
1133
+ static double _g_2(const double omega, const double vertices_omegas[4]) {
1134
+ return (
1135
+ 3 / (vertices_omegas[3] - vertices_omegas[0]) *
1136
+ (_f(1, 2, omega, vertices_omegas) * _f(2, 0, omega, vertices_omegas) +
1137
+ _f(2, 1, omega, vertices_omegas) * _f(1, 3, omega, vertices_omegas)));
1138
+ }
1139
+
1140
+ /* omega3 < omega < omega4 */
1141
+ static double _g_3(const double omega, const double vertices_omegas[4]) {
1142
+ return (3 * _f(1, 3, omega, vertices_omegas) *
1143
+ _f(2, 3, omega, vertices_omegas) /
1144
+ (vertices_omegas[3] - vertices_omegas[0]));
1145
+ }
1146
+
1147
+ /* omega4 < omega */
1148
+ static double _g_4(void) { return 0.0; }
1149
+
1150
+ static double _J_0(void) { return 0.0; }
1151
+
1152
+ static double _J_10(const double omega, const double vertices_omegas[4]) {
1153
+ return (1.0 + _f(0, 1, omega, vertices_omegas) +
1154
+ _f(0, 2, omega, vertices_omegas) +
1155
+ _f(0, 3, omega, vertices_omegas)) /
1156
+ 4;
1157
+ }
1158
+
1159
+ static double _J_11(const double omega, const double vertices_omegas[4]) {
1160
+ return _f(1, 0, omega, vertices_omegas) / 4;
1161
+ }
1162
+
1163
+ static double _J_12(const double omega, const double vertices_omegas[4]) {
1164
+ return _f(2, 0, omega, vertices_omegas) / 4;
1165
+ }
1166
+
1167
+ static double _J_13(const double omega, const double vertices_omegas[4]) {
1168
+ return _f(3, 0, omega, vertices_omegas) / 4;
1169
+ }
1170
+
1171
+ static double _J_20(const double omega, const double vertices_omegas[4]) {
1172
+ double n;
1173
+ n = _n_2(omega, vertices_omegas);
1174
+
1175
+ #ifdef THM_EPSILON
1176
+ if (n < THM_EPSILON) {
1177
+ return 0;
1178
+ }
1179
+ #endif
1180
+
1181
+ return (_f(3, 1, omega, vertices_omegas) *
1182
+ _f(2, 1, omega, vertices_omegas) +
1183
+ _f(3, 0, omega, vertices_omegas) *
1184
+ _f(1, 3, omega, vertices_omegas) *
1185
+ _f(2, 1, omega, vertices_omegas) *
1186
+ (1.0 + _f(0, 3, omega, vertices_omegas)) +
1187
+ _f(3, 0, omega, vertices_omegas) *
1188
+ _f(2, 0, omega, vertices_omegas) *
1189
+ _f(1, 2, omega, vertices_omegas) *
1190
+ (1.0 + _f(0, 3, omega, vertices_omegas) +
1191
+ _f(0, 2, omega, vertices_omegas))) /
1192
+ 4 / n;
1193
+ }
1194
+
1195
+ static double _J_21(const double omega, const double vertices_omegas[4]) {
1196
+ double n;
1197
+ n = _n_2(omega, vertices_omegas);
1198
+
1199
+ #ifdef THM_EPSILON
1200
+ if (n < THM_EPSILON) {
1201
+ return 0;
1202
+ }
1203
+ #endif
1204
+
1205
+ return (_f(3, 1, omega, vertices_omegas) *
1206
+ _f(2, 1, omega, vertices_omegas) *
1207
+ (1.0 + _f(1, 3, omega, vertices_omegas) +
1208
+ _f(1, 2, omega, vertices_omegas)) +
1209
+ _f(3, 0, omega, vertices_omegas) *
1210
+ _f(1, 3, omega, vertices_omegas) *
1211
+ _f(2, 1, omega, vertices_omegas) *
1212
+ (_f(1, 3, omega, vertices_omegas) +
1213
+ _f(1, 2, omega, vertices_omegas)) +
1214
+ _f(3, 0, omega, vertices_omegas) *
1215
+ _f(2, 0, omega, vertices_omegas) *
1216
+ _f(1, 2, omega, vertices_omegas) *
1217
+ _f(1, 2, omega, vertices_omegas)) /
1218
+ 4 / n;
1219
+ }
1220
+
1221
+ static double _J_22(const double omega, const double vertices_omegas[4]) {
1222
+ double n;
1223
+ n = _n_2(omega, vertices_omegas);
1224
+
1225
+ #ifdef THM_EPSILON
1226
+ if (n < THM_EPSILON) {
1227
+ return 0;
1228
+ }
1229
+ #endif
1230
+
1231
+ return (_f(3, 1, omega, vertices_omegas) *
1232
+ _f(2, 1, omega, vertices_omegas) *
1233
+ _f(2, 1, omega, vertices_omegas) +
1234
+ _f(3, 0, omega, vertices_omegas) *
1235
+ _f(1, 3, omega, vertices_omegas) *
1236
+ _f(2, 1, omega, vertices_omegas) *
1237
+ _f(2, 1, omega, vertices_omegas) +
1238
+ _f(3, 0, omega, vertices_omegas) *
1239
+ _f(2, 0, omega, vertices_omegas) *
1240
+ _f(1, 2, omega, vertices_omegas) *
1241
+ (_f(2, 1, omega, vertices_omegas) +
1242
+ _f(2, 0, omega, vertices_omegas))) /
1243
+ 4 / n;
1244
+ }
1245
+
1246
+ static double _J_23(const double omega, const double vertices_omegas[4]) {
1247
+ double n;
1248
+ n = _n_2(omega, vertices_omegas);
1249
+
1250
+ #ifdef THM_EPSILON
1251
+ if (n < THM_EPSILON) {
1252
+ return 0;
1253
+ }
1254
+ #endif
1255
+
1256
+ return (_f(3, 1, omega, vertices_omegas) *
1257
+ _f(2, 1, omega, vertices_omegas) *
1258
+ _f(3, 1, omega, vertices_omegas) +
1259
+ _f(3, 0, omega, vertices_omegas) *
1260
+ _f(1, 3, omega, vertices_omegas) *
1261
+ _f(2, 1, omega, vertices_omegas) *
1262
+ (_f(3, 1, omega, vertices_omegas) +
1263
+ _f(3, 0, omega, vertices_omegas)) +
1264
+ _f(3, 0, omega, vertices_omegas) *
1265
+ _f(2, 0, omega, vertices_omegas) *
1266
+ _f(1, 2, omega, vertices_omegas) *
1267
+ _f(3, 0, omega, vertices_omegas)) /
1268
+ 4 / n;
1269
+ }
1270
+
1271
+ static double _J_30(const double omega, const double vertices_omegas[4]) {
1272
+ double n;
1273
+ n = _n_3(omega, vertices_omegas);
1274
+
1275
+ #ifdef THM_EPSILON
1276
+ if (n < THM_EPSILON) {
1277
+ return 0;
1278
+ }
1279
+ #endif
1280
+
1281
+ return (1.0 - _f(0, 3, omega, vertices_omegas) *
1282
+ _f(0, 3, omega, vertices_omegas) *
1283
+ _f(1, 3, omega, vertices_omegas) *
1284
+ _f(2, 3, omega, vertices_omegas)) /
1285
+ 4 / n;
1286
+ }
1287
+
1288
+ static double _J_31(const double omega, const double vertices_omegas[4]) {
1289
+ double n;
1290
+ n = _n_3(omega, vertices_omegas);
1291
+
1292
+ #ifdef THM_EPSILON
1293
+ if (n < THM_EPSILON) {
1294
+ return 0;
1295
+ }
1296
+ #endif
1297
+
1298
+ return (1.0 - _f(0, 3, omega, vertices_omegas) *
1299
+ _f(1, 3, omega, vertices_omegas) *
1300
+ _f(1, 3, omega, vertices_omegas) *
1301
+ _f(2, 3, omega, vertices_omegas)) /
1302
+ 4 / n;
1303
+ }
1304
+
1305
+ static double _J_32(const double omega, const double vertices_omegas[4]) {
1306
+ double n;
1307
+ n = _n_3(omega, vertices_omegas);
1308
+
1309
+ #ifdef THM_EPSILON
1310
+ if (n < THM_EPSILON) {
1311
+ return 0;
1312
+ }
1313
+ #endif
1314
+
1315
+ return (1.0 - _f(0, 3, omega, vertices_omegas) *
1316
+ _f(1, 3, omega, vertices_omegas) *
1317
+ _f(2, 3, omega, vertices_omegas) *
1318
+ _f(2, 3, omega, vertices_omegas)) /
1319
+ 4 / n;
1320
+ }
1321
+
1322
+ static double _J_33(const double omega, const double vertices_omegas[4]) {
1323
+ double n;
1324
+ n = _n_3(omega, vertices_omegas);
1325
+
1326
+ #ifdef THM_EPSILON
1327
+ if (n < THM_EPSILON) {
1328
+ return 0;
1329
+ }
1330
+ #endif
1331
+
1332
+ return (1.0 - _f(0, 3, omega, vertices_omegas) *
1333
+ _f(1, 3, omega, vertices_omegas) *
1334
+ _f(2, 3, omega, vertices_omegas) *
1335
+ (1.0 + _f(3, 0, omega, vertices_omegas) +
1336
+ _f(3, 1, omega, vertices_omegas) +
1337
+ _f(3, 2, omega, vertices_omegas))) /
1338
+ 4 / n;
1339
+ }
1340
+
1341
+ static double _J_4(void) { return 0.25; }
1342
+
1343
+ static double _I_0(void) { return 0.0; }
1344
+
1345
+ static double _I_10(const double omega, const double vertices_omegas[4]) {
1346
+ return (_f(0, 1, omega, vertices_omegas) +
1347
+ _f(0, 2, omega, vertices_omegas) +
1348
+ _f(0, 3, omega, vertices_omegas)) /
1349
+ 3;
1350
+ }
1351
+
1352
+ static double _I_11(const double omega, const double vertices_omegas[4]) {
1353
+ return _f(1, 0, omega, vertices_omegas) / 3;
1354
+ }
1355
+
1356
+ static double _I_12(const double omega, const double vertices_omegas[4]) {
1357
+ return _f(2, 0, omega, vertices_omegas) / 3;
1358
+ }
1359
+
1360
+ static double _I_13(const double omega, const double vertices_omegas[4]) {
1361
+ return _f(3, 0, omega, vertices_omegas) / 3;
1362
+ }
1363
+
1364
+ static double _I_20(const double omega, const double vertices_omegas[4]) {
1365
+ double f12_20, g;
1366
+ f12_20 =
1367
+ _f(1, 2, omega, vertices_omegas) * _f(2, 0, omega, vertices_omegas);
1368
+ g = f12_20 +
1369
+ _f(2, 1, omega, vertices_omegas) * _f(1, 3, omega, vertices_omegas);
1370
+
1371
+ #ifdef THM_EPSILON
1372
+ if (g < THM_EPSILON) {
1373
+ return 0;
1374
+ }
1375
+ #endif
1376
+
1377
+ return (_f(0, 3, omega, vertices_omegas) +
1378
+ _f(0, 2, omega, vertices_omegas) * f12_20 / g) /
1379
+ 3;
1380
+ }
1381
+
1382
+ static double _I_21(const double omega, const double vertices_omegas[4]) {
1383
+ double f13_21, g;
1384
+ f13_21 =
1385
+ _f(1, 3, omega, vertices_omegas) * _f(2, 1, omega, vertices_omegas);
1386
+ g = _f(1, 2, omega, vertices_omegas) * _f(2, 0, omega, vertices_omegas) +
1387
+ f13_21;
1388
+
1389
+ #ifdef THM_EPSILON
1390
+ if (g < THM_EPSILON) {
1391
+ return 0;
1392
+ }
1393
+ #endif
1394
+
1395
+ return (_f(1, 2, omega, vertices_omegas) +
1396
+ _f(1, 3, omega, vertices_omegas) * f13_21 / g) /
1397
+ 3;
1398
+ }
1399
+
1400
+ static double _I_22(const double omega, const double vertices_omegas[4]) {
1401
+ double f12_20, g;
1402
+ f12_20 =
1403
+ _f(1, 2, omega, vertices_omegas) * _f(2, 0, omega, vertices_omegas);
1404
+ g = f12_20 +
1405
+ _f(2, 1, omega, vertices_omegas) * _f(1, 3, omega, vertices_omegas);
1406
+
1407
+ #ifdef THM_EPSILON
1408
+ if (g < THM_EPSILON) {
1409
+ return 0;
1410
+ }
1411
+ #endif
1412
+
1413
+ return (_f(2, 1, omega, vertices_omegas) +
1414
+ _f(2, 0, omega, vertices_omegas) * f12_20 / g) /
1415
+ 3;
1416
+ }
1417
+
1418
+ static double _I_23(const double omega, const double vertices_omegas[4]) {
1419
+ double f13_21, g;
1420
+ f13_21 =
1421
+ _f(1, 3, omega, vertices_omegas) * _f(2, 1, omega, vertices_omegas);
1422
+ g = _f(1, 2, omega, vertices_omegas) * _f(2, 0, omega, vertices_omegas) +
1423
+ f13_21;
1424
+
1425
+ #ifdef THM_EPSILON
1426
+ if (g < THM_EPSILON) {
1427
+ return 0;
1428
+ }
1429
+ #endif
1430
+
1431
+ return (_f(3, 0, omega, vertices_omegas) +
1432
+ _f(3, 1, omega, vertices_omegas) * f13_21 / g) /
1433
+ 3;
1434
+ }
1435
+
1436
+ static double _I_30(const double omega, const double vertices_omegas[4]) {
1437
+ return _f(0, 3, omega, vertices_omegas) / 3;
1438
+ }
1439
+
1440
+ static double _I_31(const double omega, const double vertices_omegas[4]) {
1441
+ return _f(1, 3, omega, vertices_omegas) / 3;
1442
+ }
1443
+
1444
+ static double _I_32(const double omega, const double vertices_omegas[4]) {
1445
+ return _f(2, 3, omega, vertices_omegas) / 3;
1446
+ }
1447
+
1448
+ static double _I_33(const double omega, const double vertices_omegas[4]) {
1449
+ return (_f(3, 0, omega, vertices_omegas) +
1450
+ _f(3, 1, omega, vertices_omegas) +
1451
+ _f(3, 2, omega, vertices_omegas)) /
1452
+ 3;
1453
+ }
1454
+
1455
+ static double _I_4(void) { return 0.0; }
phonopy/source/c/tetrahedron_method.h ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright (C) 2014 Atsushi Togo */
2
+ /* All rights reserved. */
3
+
4
+ /* This file was originally part of spglib and is part of kspclib. */
5
+
6
+ /* Redistribution and use in source and binary forms, with or without */
7
+ /* modification, are permitted provided that the following conditions */
8
+ /* are met: */
9
+
10
+ /* * Redistributions of source code must retain the above copyright */
11
+ /* notice, this list of conditions and the following disclaimer. */
12
+
13
+ /* * Redistributions in binary form must reproduce the above copyright */
14
+ /* notice, this list of conditions and the following disclaimer in */
15
+ /* the documentation and/or other materials provided with the */
16
+ /* distribution. */
17
+
18
+ /* * Neither the name of the kspclib project nor the names of its */
19
+ /* contributors may be used to endorse or promote products derived */
20
+ /* from this software without specific prior written permission. */
21
+
22
+ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
23
+ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
24
+ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
25
+ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE */
26
+ /* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
27
+ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */
28
+ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
29
+ /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER */
30
+ /* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT */
31
+ /* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN */
32
+ /* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
33
+ /* POSSIBILITY OF SUCH DAMAGE. */
34
+
35
+ #ifndef __tetrahedron_method_H__
36
+ #define __tetrahedron_method_H__
37
+
38
+ #include <stddef.h>
39
+ #include <stdint.h>
40
+
41
+ void thm_get_relative_grid_address(int64_t relative_grid_address[24][4][3],
42
+ const double rec_lattice[3][3]);
43
+ void thm_get_all_relative_grid_address(
44
+ int64_t relative_grid_address[4][24][4][3]);
45
+ double thm_get_integration_weight(const double omega,
46
+ const double tetrahedra_omegas[24][4],
47
+ const char function);
48
+ int64_t thm_in_tetrahedra(const double f0, const double freq_vertices[24][4]);
49
+
50
+ #endif
phonopy/source/cmake-format.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ with section("format"):
2
+ disable = False
3
+ line_width = 85
4
+ tab_size = 4
phonopy/source/dev-requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ numpy
phonopy/source/doc/Al-QHA.png ADDED

Git LFS Details

  • SHA256: f92950be4962f58f1eb65ba8fc8f80c9fb125734667d9172cfb0cbe8a5585d9d
  • Pointer size: 131 Bytes
  • Size of remote file: 111 kB
phonopy/source/doc/Cu-QHA.png ADDED
phonopy/source/doc/Fleur.rst ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. _Fleur_interface:
2
+
3
+ Fleur & phonopy calculation
4
+ =========================================
5
+
6
+ Setting up the inpgen file:
7
+
8
+ The preparation of a Fleur calculation takes two steps. First a basic input file
9
+ is written, that is converted to an inp.xml via the Fleur input generator inpgen.
10
+
11
+ The input file starts with a comment line describing the calculation. From there,
12
+ a multitude of options can be specified by namelists starting with '&' and ending
13
+ with '/'. Normally, the lattice information would be set preferably by tags like
14
+ 'fcc' etc. and the corresponding necessary lattice constants. For further
15
+ information, consult the inpgen documentation under 'User Guide --> Reference -->
16
+ The input generator' on flapw.de.
17
+
18
+ An important thing to note is:
19
+ The bravais matrix needs to be set directly via the second method proposed in
20
+ the reference. The complete overhead to constuct the bravais matrix from only
21
+ the lattice tag and constants in not (yet) programmed into the phonopy interface.
22
+ The supercell will be written in the same fashion, while the rest of the inpgen
23
+ file is merely copied over.
24
+
25
+ Also:
26
+ For phonopy to be able to correctly extract the necessary quantities from the
27
+ input file, a mandatory comment '! a1' needs to be put at the end of the first
28
+ line of the Bravais matrix and '! num atoms' after the atom count.
29
+
30
+ How to run
31
+ ----------
32
+
33
+ A procedure of a Fleur-phonopy calculation may look as follows:
34
+
35
+ 1) Read a Fleur input file and create supercells with the
36
+ :ref:`Fleur_mode` option::
37
+
38
+ % phonopy --fleur -d --dim="a b c" -c fleur_inpgen
39
+
40
+ In this example several axbxc supercells are created. ``supercell.in``
41
+ and ``supercell-XXX.in`` (``XXX`` enumerating the necessary displacements) give
42
+ the perfect and displaced supercells respectively. ``phonopy_disp.yaml``
43
+ is also generated. This file contains information on displacements.
44
+ The supercell files ``supercell-XXX.in`` should be stored in
45
+ subfolders e.g. ``disp-XXX``, then Fleur calculations are executed
46
+ in these directories.
47
+
48
+ 2) Calculate forces on atoms in the supercells with displacements.
49
+ First run the fleur inpgen with the '-f supercell-XXX.in' option
50
+ The resulting inp.xml is then run by the fleur command itself.
51
+ After successfull convergence, set the tag 'l_f' in the inp.xml to "T"
52
+ and add 'f_level="n"' behind it with n from {0,1,2,3}. This optional
53
+ tag ensures the write-out of the 'FORCES' file and setting it to
54
+ {1,2,3} calculates additional refined force contibutions.
55
+
56
+ 3) Create ``FORCE_SETS`` by::
57
+
58
+ % phonopy --fleur -f disp-001/FORCES disp-002/FORCES ...
59
+
60
+ To run this command, ``phonopy_disp.yaml`` has to be located in same
61
+ directory because the atomic displacements need to be written into the
62
+ FORCE_SETS file. See some more detail at
63
+ :ref:`Fleur_force_sets_option`. An example for fcc Al with a 2x2x2
64
+ supercell and only one necessary displacement is found in
65
+ ``example/Al-Fleur``.
66
+
67
+ 4) Run the post-process of phonopy with the Fleur input file for the
68
+ unit cell used in step 1::
69
+
70
+ % phonopy --fleur -c fleur_inpgen -p band.conf
71
+
72
+ if you prepared a band.conf file or::
73
+
74
+ % phonopy --fleur -c fleur_inpgen --dim="2 2 2" [other-OPTIONS] [setting-file]
75
+
76
+ if you want to set the path directly or specify a different file.
phonopy/source/doc/Makefile ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= sphinx-build
8
+ SOURCEDIR = .
9
+ BUILDDIR = _build
10
+
11
+ # Put it first so that "make" without argument is like "make help".
12
+ help:
13
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14
+
15
+ .PHONY: help Makefile
16
+
17
+ # Catch-all target: route all unknown targets to Sphinx using the new
18
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19
+ %: Makefile
20
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
phonopy/source/doc/NaCl-PDOS-nac.png ADDED
phonopy/source/doc/NaCl-PDOS.png ADDED
phonopy/source/doc/NaCl-VASPdfpt.png ADDED
phonopy/source/doc/NaCl-band-NAC.png ADDED
phonopy/source/doc/NaCl-band-PDOS-NAC.png ADDED
phonopy/source/doc/NaCl-band.png ADDED
phonopy/source/doc/NaCl-crystal-band-NAC.png ADDED
phonopy/source/doc/NaCl-disp-dist.png ADDED
phonopy/source/doc/NaCl-pwscf-band-NAC.png ADDED
phonopy/source/doc/NaCl-pwscf-band.png ADDED
phonopy/source/doc/NaCl-q2r-band-NAC.png ADDED
phonopy/source/doc/QHA.png ADDED

Git LFS Details

  • SHA256: a1cd0e265325fac646708fe5ca01523cb8bf89b1ceff497758226ce28383759a
  • Pointer size: 131 Bytes
  • Size of remote file: 334 kB