├── .coveralls.yml ├── .github └── workflows │ └── python-publish.yml ├── .travis.yml ├── LICENSE ├── README.md ├── c ├── correlation.c ├── displacements.c └── mem.c ├── doc └── QuickGuide.pdf ├── dynaphopy ├── __init__.py ├── analysis │ ├── __init__.py │ ├── coordinates.py │ ├── energy.py │ ├── fitting │ │ ├── __init__.py │ │ └── fitting_functions.py │ ├── modes.py │ ├── peaksearch.py │ └── thermal_properties.py ├── atoms.py ├── dynamics.py ├── generate_cell.py ├── interface │ ├── __init__.py │ ├── interactive_ui.py │ ├── iofile │ │ ├── __init__.py │ │ └── trajectory_parsers.py │ ├── lammps_link.py │ └── phonopy_link.py ├── parameters.py ├── power_spectrum │ └── __init__.py └── projection.py ├── examples ├── GaN_lammps │ ├── FORCE_CONSTANTS_3x3x3 │ ├── GaN.tersoff │ ├── POSCAR_unitcell │ ├── README │ ├── data.gan │ ├── dos.png │ ├── in.md_pos │ ├── in.md_vel │ ├── input_gan │ ├── log.lammps │ ├── output_dynaphopy │ ├── phonon_dispersion.png │ ├── phonon_dispersion_and_linewidths.png │ ├── quasiparticles_data.yaml │ └── renormalized_fc ├── Si_VASP │ ├── FORCE_SETS_2x2x2 │ ├── INCAR │ ├── KPOINTS │ ├── POSCAR │ ├── POSCAR_unitcell │ ├── README │ ├── dos.png │ ├── input_si │ ├── output_dynaphopy │ ├── phonon_dispersion.png │ ├── quasiparticles_data.yaml │ └── renormalized_fc ├── api_scripts │ ├── script_silicon.py │ └── silicon_pure.py ├── inputs │ ├── input_AlN │ ├── input_GaN │ ├── input_Ge │ ├── input_MgO │ ├── input_diamond │ └── input_silicon └── lammps_interface │ ├── GaN │ ├── GaN.tersoff │ ├── POSCAR_unitcell │ ├── README.txt │ ├── in.lammps │ └── input_dynaphopy │ └── Si │ ├── POSCAR_unitcell │ ├── README.txt │ ├── SiCGe.tersoff │ ├── data_unitcell.si │ ├── in.lammps │ └── input_si ├── requirements.txt ├── scripts ├── concath5 ├── dynaphopy ├── fitdata ├── qha_extract ├── qha_quasiparticle.py └── rfc_calc ├── setup.py └── unittest ├── Ag2Cu2O4_data ├── FORCE_SETS └── POSCAR ├── Ag2Cu2O4_test.py ├── GaN_data ├── FORCE_CONSTANTS ├── FORCE_CONSTANTS_old ├── POSCAR ├── atomic_displacements.dat ├── bands_data.yaml └── quasiparticles_data.yaml ├── GaN_test.py ├── MgO_data ├── FORCE_CONSTANTS └── POSCAR ├── MgO_test.py ├── Si_data ├── FORCE_CONSTANTS ├── OUTCAR ├── POSCAR ├── XDATCAR ├── atomic_displacements.dat ├── atomic_displacements_mem.dat ├── bands_data.yaml ├── bands_data_mem.yaml ├── quasiparticles_data.yaml ├── quasiparticles_data_mem.yaml └── si.lammpstrj ├── Si_mem_test.py ├── Si_test.py └── reading_test.py /.coveralls.yml: -------------------------------------------------------------------------------- 1 | repo_token: vD2RMjy4usdmuPVFGbLZ37IIopFpeZHmu -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | name: Test Build wheels and Deploy 2 | 3 | # Build on every branch push, tag push, and pull request change: 4 | on: [push, pull_request] 5 | # Alternatively, to publish when a (published) GitHub Release is created, use the following: 6 | # on: 7 | # push: 8 | # pull_request: 9 | # release: 10 | # types: 11 | # - published 12 | 13 | jobs: 14 | 15 | test_code: 16 | runs-on: ubuntu-latest 17 | strategy: 18 | matrix: 19 | python-version: [ '3.8', '3.11', '3.12' ] 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v2 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | - name: Install dependencies 28 | run: | 29 | python -m pip install --upgrade pip 30 | python -m pip install flake8 pytest setuptools 31 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 32 | - name: Lint with flake8 33 | run: | 34 | # stop the build if there are Python syntax errors or undefined names 35 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 36 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 37 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 38 | - name: Build c extensions 39 | run: | 40 | #python setup.py build_ext --inplace 41 | python setup.py install 42 | - name: Test with pytest 43 | run: | 44 | # pytest test 45 | cd unittest 46 | pytest 47 | 48 | build_wheels: 49 | name: Build wheels on ${{ matrix.os }} 50 | runs-on: ${{ matrix.os }} 51 | needs: [ test_code ] 52 | if: github.ref == 'refs/heads/master' 53 | strategy: 54 | matrix: 55 | os: [ubuntu-latest, windows-2019, macos-13] 56 | #os: [macos-10.15, windows-2019] 57 | 58 | steps: 59 | - uses: actions/checkout@v4 60 | - uses: actions/setup-python@v3 61 | 62 | - name: Install cibuildwheel 63 | run: python -m pip install cibuildwheel==2.17.0 64 | 65 | - name: Build wheels 66 | run: python -m cibuildwheel --output-dir wheelhouse 67 | env: 68 | CIBW_BEFORE_BUILD: pip install numpy==1.19.5 setuptools 69 | CIBW_BUILD: cp38-* 70 | 71 | - name: Build wheels 72 | run: python -m cibuildwheel --output-dir wheelhouse 73 | env: 74 | CIBW_BEFORE_BUILD: pip install numpy==1.21.6 setuptools 75 | CIBW_BUILD: cp39-* cp310-* 76 | CIBW_ARCHS_MACOS: x86_64 universal2 77 | 78 | - name: Build wheels 79 | run: python -m cibuildwheel --output-dir wheelhouse 80 | env: 81 | CIBW_BEFORE_BUILD: pip install numpy setuptools 82 | CIBW_BUILD: cp311-* 83 | CIBW_ARCHS_MACOS: x86_64 universal2 84 | 85 | - uses: actions/upload-artifact@v4 86 | with: 87 | name: cibw-wheels-${{ matrix.os }}-${{ strategy.job-index }} 88 | path: ./wheelhouse/*.whl 89 | 90 | build_sdist: 91 | name: Build source distribution 92 | needs: [ test_code ] 93 | runs-on: ubuntu-latest 94 | if: github.ref == 'refs/heads/master' 95 | steps: 96 | - uses: actions/checkout@v2 97 | - name: Set up Python 98 | uses: actions/setup-python@v2 99 | with: 100 | python-version: '3.x' 101 | - name: Install dependencies 102 | run: | 103 | python -m pip install numpy setuptools 104 | - name: Build sdist 105 | run: | 106 | python setup.py sdist 107 | - uses: actions/upload-artifact@v4 108 | with: 109 | name: cibw-sdist 110 | path: dist/*.tar.gz 111 | 112 | upload_pypi: 113 | needs: [build_wheels, build_sdist, test_code] 114 | runs-on: ubuntu-latest 115 | if: github.ref == 'refs/heads/master' 116 | # upload to PyPI on every tag starting with 'v' 117 | # if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') 118 | # alternatively, to publish when a GitHub Release is created, use the following rule: 119 | # if: github.event_name == 'release' && github.event.action == 'published' 120 | steps: 121 | - uses: actions/download-artifact@v4 122 | with: 123 | # unpacks all CIBW artifacts into dist/ 124 | pattern: cibw-* 125 | path: dist 126 | merge-multiple: true 127 | 128 | - uses: pypa/gh-action-pypi-publish@v1.4.2 129 | with: 130 | user: __token__ 131 | password: ${{ secrets.PYPI_API_TOKEN }} 132 | # repository_url: https://test.pypi.org/legacy/ 133 | skip_existing: true -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | os: 4 | - linux 5 | 6 | python: 7 | - "3.6" 8 | - "3.8" 9 | 10 | branches: 11 | only: 12 | - master 13 | - development 14 | - improve_API 15 | - python_3_development 16 | 17 | install: 18 | - sudo apt-get install libhdf5-serial-dev 19 | - pip install coverage 20 | - pip install coveralls 21 | - pip install -r requirements.txt 22 | - pip install -e . 23 | 24 | script: 25 | - cd unittest 26 | - coverage run --source=../dynaphopy -m unittest discover . "*_test.py" 27 | 28 | after_success: 29 | - coveralls 30 | - cd .. 31 | 32 | #deploy: 33 | # # pypi 34 | # - provider: pypi 35 | # distributions: sdist 36 | # user: abelcarreras83 37 | # password: 38 | # secure: "Q5AioRbIJz4DAnoYyxdIred0tQ4G5xOLdM6RAv1UnCdknzxPh1ukJVnFDU+AypFt5cB3lrYoPTDp4VOOuh12lbS4kXEsWwTB/7oOmUG0QwuWyWoNI4/lD1gXxdptxC7ND/P9pUzBQ1FT41/GXWYzSGhg8PGT22Uz2xrNFymIpu3/qj8H4cymTb1jJxBrVsft0OXuRWRERRB69ZPUjXM/a8HGr/mvhfayiEXZ8c1TVcUtYgVPKLqIUeMfAnQLZxblwp1xqepRihJMLAlkiM58Olj/Yt0KIJOIY0IkaBHES8SBQoRIuBfCuJrCE9JeG23yKwzvxowtnXjeQUDUnitqqWI2wiJ88CIZFbBayHN9SNqeM8lOjEUN9TeUmXODf6Txj6wW1JhfDLYSri0pvnGQ3AROq9khUPUOv/aY9e64mfxvHPgR3Hx80OYLZgIstbwRSWYgEp9E15F5YkB72qD8Iz+eEBquBvYaGLfVpiwXtlxVxo9AzUBFlBxuj+DLI4dQRepXabuu21iSlL0rowlOUUM2EG5eby3aSxpKXHRu76n/sTFr5TsYgswMmPq0TfYAW/LgkyZGYia2hy+PufmjFENlCF1YyDe2yGPqwlhnDE/0gLziHfiq6IvcsAdGMX0jNjSGANR1fDV+syB2aDDNTUhSJJoCxLBdQBoi2M75W/g=" 39 | # skip_existing: true 40 | # on: 41 | # branch: master 42 | # branch: development 43 | # tags: False -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Abel Carreras Conill 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![PyPI version](https://badge.fury.io/py/dynaphopy.svg)](https://pypi.python.org/pypi/dynaphopy) 2 | [![Build Status](https://app.travis-ci.com/abelcarreras/DynaPhoPy.svg)](https://app.travis-ci.com/github/abelcarreras/DynaPhoPy) 3 | [![Coverage Status](https://coveralls.io/repos/github/abelcarreras/DynaPhoPy/badge.svg)](https://coveralls.io/github/abelcarreras/DynaPhoPy) 4 | [![DOI](https://img.shields.io/badge/DOI-10.1016%2Fj.cpc.2017.08.017-blue)](https://doi.org/10.1016/j.cpc.2017.08.017) 5 | 6 | DynaPhoPy 7 | ========= 8 | Software to calculate crystal microscopic anharmonic properties 9 | from molecular dynamics (MD) using the normal-mode-decomposition technique. 10 | These properties include the phonon frequency shifts and linewidths, 11 | as well as the renormalized force constanst and thermal properties 12 | by using quasiparticle theory. This code includes interfaces for MD 13 | outputs from VASP and LAMMPS. PHONOPY code is used to obtain harmonic 14 | phonon modes. 15 | 16 | Online manual: http://abelcarreras.github.io/DynaPhoPy/ 17 | 18 | 19 | Installation instructions 20 | --------------------------------------------------------- 21 | 22 | 1. Requirements 23 | - Python 2.7.x/3.5 or higher 24 | - Phonopy 2.0 or higher (https://phonopy.github.io/phonopy) 25 | - Matplotlib 26 | - Scipy 27 | - h5py 28 | - pyYAML 29 | - (optional) pyFFTW (http://www.fftw.org/) 30 | - (optional) cuda_functions (https://github.com/abelcarreras/cuda_functions) 31 | 32 | 2a. Install from pypi repository 33 | ``` 34 | pip install dynaphopy --user 35 | ``` 36 | 37 | 2b. Install from source (requires c compiler) 38 | - Install requirements from requirements.txt: 39 | ``` 40 | pip install -r requirements.txt --user 41 | ``` 42 | - Run setup.py to install dynaphopy 43 | ``` 44 | python setup.py install --user 45 | ``` 46 | 47 | Executing this software 48 | --------------------------------------------------------- 49 | 50 | 1. Command line method 51 | - execute ***dynaphopy -h*** for detailed description of available options 52 | ``` 53 | dynaphopy input_file MD_file [Options] 54 | ``` 55 | 56 | 2. Interactive mode 57 | - Use -i option from command line method and follow the instructions 58 | ``` 59 | dynaphopy input_file MD_file -i 60 | ``` 61 | 3. Scripting method (as a module) 62 | - Dynaphopy can be imported as a python module 63 | - In examples/api_scripts directory an example script is available (script_silicon.py) 64 | - The comments in the script makes it (hopefully) self explained. 65 | 66 | Input files for several materials can be found in the same example/inputs directory. 67 | More information in the online manual at: http://abelcarreras.github.io/DynaPhoPy 68 | 69 | 70 | Contact info 71 | --------------------------------------------------------- 72 | Abel Carreras 73 | abelcarreras83@gmail.com 74 | 75 | Donostia International Physics Center (DIPC) 76 | Donostia-San Sebastian (Spain) -------------------------------------------------------------------------------- /c/correlation.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #if defined(ENABLE_OPENMP) 9 | #include 10 | #endif 11 | 12 | 13 | #undef I 14 | 15 | // Cross compatibility mingw - gcc 16 | 17 | #if !defined(_WIN32) 18 | 19 | #define _Dcomplex double _Complex 20 | 21 | _Dcomplex _Cbuild(double real, double imag){ 22 | return real + imag* 1.j; 23 | } 24 | 25 | _Dcomplex _Cmulcc(_Dcomplex num1, _Dcomplex num2){ 26 | return num1 * num2; 27 | } 28 | #endif 29 | 30 | 31 | static double EvaluateCorrelation (double AngularFrequency, _Dcomplex * Velocity, int NumberOfData, double TimeStep, int Increment, int IntMethod); 32 | static PyObject* correlation_par (PyObject* self, PyObject *arg, PyObject *keywords); 33 | 34 | 35 | 36 | // Python Interface 37 | static char function_docstring[] = 38 | "correlation_par(frequency, velocity, timestep, step=10, integration_method=1 )\n\n Calculation of the correlation\n Constant time step method (faster)\n OpenMP parallel"; 39 | 40 | static PyMethodDef extension_funcs[] = { 41 | {"correlation_par", (PyCFunction)correlation_par, METH_VARARGS|METH_KEYWORDS, function_docstring}, 42 | {NULL, NULL, 0, NULL} 43 | }; 44 | 45 | 46 | #if PY_MAJOR_VERSION >= 3 47 | static struct PyModuleDef moduledef = { 48 | PyModuleDef_HEAD_INIT, 49 | "correlation", 50 | "power spectrum direct method module ", 51 | -1, 52 | extension_funcs, 53 | NULL, 54 | NULL, 55 | NULL, 56 | NULL, 57 | }; 58 | #endif 59 | 60 | 61 | static PyObject * 62 | moduleinit(void) 63 | { 64 | PyObject *m; 65 | 66 | #if PY_MAJOR_VERSION >= 3 67 | m = PyModule_Create(&moduledef); 68 | #else 69 | m = Py_InitModule3("correlation", 70 | extension_funcs, "power spectrum direct method module"); 71 | #endif 72 | 73 | return m; 74 | } 75 | 76 | #if PY_MAJOR_VERSION < 3 77 | PyMODINIT_FUNC 78 | initcorrelation(void) 79 | { 80 | import_array(); 81 | moduleinit(); 82 | } 83 | #else 84 | PyMODINIT_FUNC 85 | PyInit_correlation(void) 86 | { 87 | import_array(); 88 | return moduleinit(); 89 | } 90 | 91 | #endif 92 | 93 | #ifndef M_PI 94 | #define M_PI 3.14159265358979323846 95 | #endif 96 | 97 | 98 | // Correlation method for constant time (TimeStep) step trajectories paralellized with OpenMP 99 | static PyObject* correlation_par (PyObject* self, PyObject *arg, PyObject *keywords) 100 | { 101 | // Declaring initial variables 102 | double TimeStep; 103 | double AngularFrequency; 104 | int Increment = 10; //Default value for Increment 105 | int IntMethod = 1; //Define integration method 106 | 107 | // Interface with Python 108 | PyObject *velocity_obj, *frequency_obj; 109 | static char *kwlist[] = {"frequency", "velocity", "time_step", "step", "integration_method", NULL}; 110 | if (!PyArg_ParseTupleAndKeywords(arg, keywords, "OOd|ii", kwlist, &frequency_obj, &velocity_obj, &TimeStep, &Increment, &IntMethod)) return NULL; 111 | 112 | PyObject *velocity_array = PyArray_FROM_OTF(velocity_obj, NPY_CDOUBLE, NPY_ARRAY_IN_ARRAY); 113 | PyObject *frequency_array = PyArray_FROM_OTF(frequency_obj, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY); 114 | 115 | if (velocity_array == NULL || frequency_array == NULL ) { 116 | Py_XDECREF(velocity_array); 117 | Py_XDECREF(frequency_array); 118 | return NULL; 119 | } 120 | 121 | _Dcomplex *Velocity = (_Dcomplex *)PyArray_DATA((PyArrayObject *)velocity_array); 122 | double *Frequency = (double*)PyArray_DATA((PyArrayObject *)frequency_array); 123 | npy_intp NumberOfData = PyArray_DIM((PyArrayObject *)velocity_array, 0); 124 | npy_intp NumberOfFrequencies = PyArray_DIM((PyArrayObject *)frequency_array, 0); 125 | 126 | // Create new numpy array for storing result 127 | PyArrayObject *PowerSpectrum_object; 128 | npy_intp dims[] = {NumberOfFrequencies}; 129 | PowerSpectrum_object = (PyArrayObject *)PyArray_SimpleNew(1, dims, NPY_DOUBLE); 130 | double *PowerSpectrum = (double *)PyArray_DATA(PowerSpectrum_object); 131 | 132 | // Maximum Entropy Method Algorithm 133 | if (IntMethod < 0 || IntMethod > 1) { 134 | puts ("\nIntegration method selected does not exist\n"); 135 | return NULL; 136 | } 137 | 138 | # pragma omp parallel for default(shared) private(AngularFrequency) 139 | for (int i=0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | // Cross compatibility mingw - gcc 10 | #if !defined(_WIN32) 11 | 12 | #define _Dcomplex double _Complex 13 | 14 | _Dcomplex _Cbuild(double real, double imag){ 15 | return real + imag* 1.j; 16 | } 17 | #endif 18 | 19 | // Functions declaration 20 | static double **matrix_multiplication (double **a, double **b, int n, int l, int m); 21 | 22 | static int TwotoOne (int Row, int Column, int NumColumns); 23 | static double **pymatrix_to_c_array_real (PyArrayObject *array); 24 | 25 | static _Dcomplex **pymatrix_to_c_array_complex (PyArrayObject *array); 26 | 27 | static double **matrix_inverse ( double ** a ,int n); 28 | static double Determinant(double **a,int n); 29 | static double **CoFactor(double **a,int n); 30 | static PyObject* atomic_displacements(PyObject* self, PyObject *arg, PyObject *keywords); 31 | 32 | 33 | // Python Interface 34 | static char function_docstring[] = 35 | "atomic_displacements(cell, trajectory, positions )"; 36 | 37 | static PyMethodDef extension_funcs[] = { 38 | {"atomic_displacements", (PyCFunction)atomic_displacements, METH_VARARGS|METH_KEYWORDS, function_docstring}, 39 | {NULL, NULL, 0, NULL} 40 | }; 41 | 42 | 43 | #if PY_MAJOR_VERSION >= 3 44 | static struct PyModuleDef moduledef = { 45 | PyModuleDef_HEAD_INIT, 46 | "displacements", 47 | "atomic displacements module", 48 | -1, 49 | extension_funcs, 50 | NULL, 51 | NULL, 52 | NULL, 53 | NULL, 54 | }; 55 | #endif 56 | 57 | 58 | static PyObject * 59 | moduleinit(void) 60 | { 61 | PyObject *m; 62 | 63 | #if PY_MAJOR_VERSION >= 3 64 | m = PyModule_Create(&moduledef); 65 | #else 66 | m = Py_InitModule3("displacements", 67 | extension_funcs, "This is a module"); 68 | #endif 69 | 70 | return m; 71 | } 72 | 73 | #if PY_MAJOR_VERSION < 3 74 | PyMODINIT_FUNC 75 | initdisplacements(void) 76 | { 77 | import_array(); 78 | moduleinit(); 79 | } 80 | #else 81 | PyMODINIT_FUNC 82 | PyInit_displacements(void) 83 | { 84 | import_array(); 85 | return moduleinit(); 86 | } 87 | 88 | #endif 89 | 90 | 91 | 92 | static PyObject *atomic_displacements(PyObject *self, PyObject *arg, PyObject *keywords) { 93 | 94 | 95 | // Interface with python 96 | PyObject *Cell_obj, *Trajectory_obj, *Positions_obj; 97 | 98 | 99 | static char *kwlist[] = {"trajectory", "positions", "cell", NULL}; 100 | if (!PyArg_ParseTupleAndKeywords(arg, keywords, "OOO", kwlist, &Trajectory_obj, &Positions_obj, &Cell_obj)) return NULL; 101 | 102 | PyObject *Trajectory_array = PyArray_FROM_OTF(Trajectory_obj, NPY_CDOUBLE, NPY_ARRAY_IN_ARRAY); 103 | PyObject *Positions_array = PyArray_FROM_OTF(Positions_obj, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY); 104 | PyObject *Cell_array = PyArray_FROM_OTF(Cell_obj, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY); 105 | 106 | if (Cell_array == NULL || Trajectory_array == NULL) { 107 | Py_XDECREF(Cell_array); 108 | Py_XDECREF(Trajectory_array); 109 | Py_XDECREF(Positions_array); 110 | return NULL; 111 | } 112 | 113 | 114 | // double _Complex *Cell = (double _Complex*)PyArray_DATA(Cell_array); 115 | _Dcomplex *Trajectory = (_Dcomplex*)PyArray_DATA((PyArrayObject *)Trajectory_array); 116 | double *Positions = (double*)PyArray_DATA((PyArrayObject *)Positions_array); 117 | 118 | npy_intp NumberOfData = PyArray_DIM((PyArrayObject *)Trajectory_array, 0); 119 | npy_intp NumberOfDimensions = PyArray_DIM((PyArrayObject *)Cell_array, 0); 120 | 121 | // Create new Numpy array to store the result 122 | _Dcomplex **Displacement; 123 | PyArrayObject *Displacement_object; 124 | 125 | npy_intp dims[] = {NumberOfData, NumberOfDimensions}; 126 | Displacement_object = (PyArrayObject *)PyArray_SimpleNew(2, dims, NPY_CDOUBLE); 127 | Displacement = pymatrix_to_c_array_complex(Displacement_object); 128 | 129 | // Create a pointer array from cell matrix (to be improved) 130 | double **Cell_c = pymatrix_to_c_array_real((PyArrayObject *) Cell_array); 131 | 132 | /* 133 | printf("\nCell Matrix"); 134 | for(int i = 0 ;i < NumberOfDimensions ; i++){ 135 | printf("\n"); 136 | for(int j = 0; j < NumberOfDimensions; j++) printf("%f\t",Cell_c[i][j]); 137 | } 138 | printf("\n\n"); 139 | 140 | */ 141 | 142 | // Matrix inverse 143 | double **Cell_i = matrix_inverse(Cell_c, NumberOfDimensions); 144 | 145 | /* 146 | printf("\nMatrix Inverse"); 147 | for(int i = 0 ;i < NumberOfDimensions ; i++){ 148 | printf("\n"); 149 | for(int j = 0; j < NumberOfDimensions; j++) printf("%f\t",Cell_i[i][j]); 150 | } 151 | printf("\n\n"); 152 | */ 153 | 154 | double ** Difference = malloc(NumberOfDimensions * sizeof(double *)); 155 | for (int i = 0; i < NumberOfDimensions; i++) Difference[i] = (double *) malloc( sizeof(double )); 156 | 157 | for (int i = 0; i < NumberOfData; i++) { 158 | 159 | for (int k = 0; k < NumberOfDimensions; k++) { 160 | Difference[k][0] = creal(Trajectory[TwotoOne(i, k, NumberOfDimensions)]) - Positions[k]; 161 | } 162 | 163 | double ** DifferenceMatrix = matrix_multiplication(Cell_i, Difference, NumberOfDimensions, NumberOfDimensions, 1); 164 | 165 | for (int k = 0; k < NumberOfDimensions; k++) { 166 | DifferenceMatrix[k][0] = round(DifferenceMatrix[k][0]); 167 | } 168 | 169 | double ** PeriodicDisplacement = matrix_multiplication(Cell_c, DifferenceMatrix, NumberOfDimensions, NumberOfDimensions, 1); 170 | 171 | for (int k = 0; k < NumberOfDimensions; k++) { 172 | Displacement[i][k] = _Cbuild(creal(Trajectory[TwotoOne(i, k, NumberOfDimensions)]) - PeriodicDisplacement[k][0] - Positions[k],0); 173 | } 174 | 175 | //Free memory 176 | for (int k=0 ; k 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #if defined(ENABLE_OPENMP) 9 | #include 10 | #endif 11 | 12 | #undef I 13 | 14 | // Cross compatibility mingw - gcc 15 | #if !defined(_WIN32) 16 | 17 | #define _Dcomplex double _Complex 18 | 19 | _Dcomplex _Cbuild(double real, double imag){ 20 | return real + imag* 1.j; 21 | } 22 | 23 | _Dcomplex _Cmulcc(_Dcomplex num1, _Dcomplex num2){ 24 | return num1 * num2; 25 | } 26 | #endif 27 | 28 | 29 | static double FrequencyEvaluation(double Delta, double Coefficients[], int m, double xms); 30 | static double GetCoefficients(double *data, int n, int m, double d[]); 31 | static PyObject* MaximumEntropyMethod (PyObject* self, PyObject *arg, PyObject *keywords); 32 | 33 | 34 | // Python Interface 35 | static char function_docstring[] = 36 | "mem(frequency, velocity, time_step, coefficients=100 )\n\n Maximum Entropy Method\n Constant time step"; 37 | 38 | 39 | static PyMethodDef extension_funcs[] = { 40 | {"mem", (PyCFunction)MaximumEntropyMethod, METH_VARARGS|METH_KEYWORDS, function_docstring}, 41 | {NULL, NULL, 0, NULL} 42 | }; 43 | 44 | 45 | #if PY_MAJOR_VERSION >= 3 46 | static struct PyModuleDef moduledef = { 47 | PyModuleDef_HEAD_INIT, 48 | "mem", 49 | "Maximum entropy method module", 50 | -1, 51 | extension_funcs, 52 | NULL, 53 | NULL, 54 | NULL, 55 | NULL, 56 | }; 57 | #endif 58 | 59 | 60 | static PyObject * 61 | moduleinit(void) 62 | { 63 | PyObject *m; 64 | 65 | #if PY_MAJOR_VERSION >= 3 66 | m = PyModule_Create(&moduledef); 67 | #else 68 | m = Py_InitModule3("mem", 69 | extension_funcs, "Maximum entropy method module"); 70 | #endif 71 | 72 | return m; 73 | } 74 | 75 | #if PY_MAJOR_VERSION < 3 76 | PyMODINIT_FUNC 77 | initmem(void) 78 | { 79 | import_array(); 80 | moduleinit(); 81 | } 82 | #else 83 | PyMODINIT_FUNC 84 | PyInit_mem(void) 85 | { 86 | import_array(); 87 | return moduleinit(); 88 | } 89 | 90 | #endif 91 | 92 | #ifndef M_PI 93 | #define M_PI 3.14159265358979323846 94 | #endif 95 | 96 | 97 | 98 | static PyObject* MaximumEntropyMethod (PyObject* self, PyObject *arg, PyObject *keywords) 99 | { 100 | // Declaring initial variables 101 | double TimeStep; 102 | int NumberOfCoefficients = 100; //Default value for number of coeficients 103 | double AngularFrequency; 104 | 105 | // Interface with Python 106 | PyObject *velocity_obj, *frequency_obj; 107 | static char *kwlist[] = {"frequency", "velocity", "time_step", "coefficients", NULL}; 108 | if (!PyArg_ParseTupleAndKeywords(arg, keywords, "OOd|i", kwlist, &frequency_obj, &velocity_obj, &TimeStep, &NumberOfCoefficients)) return NULL; 109 | 110 | PyObject *velocity_array = PyArray_FROM_OTF(velocity_obj, NPY_CDOUBLE, NPY_ARRAY_IN_ARRAY); 111 | PyObject *frequency_array = PyArray_FROM_OTF(frequency_obj, NPY_DOUBLE, NPY_ARRAY_IN_ARRAY); 112 | 113 | if (velocity_array == NULL || frequency_array == NULL ) { 114 | Py_XDECREF(velocity_array); 115 | Py_XDECREF(frequency_array); 116 | return NULL; 117 | } 118 | 119 | _Dcomplex *Velocity = (_Dcomplex *)PyArray_DATA((PyArrayObject *)velocity_array); 120 | double *Frequency = (double*)PyArray_DATA((PyArrayObject *)frequency_array); 121 | npy_intp NumberOfData = PyArray_DIM((PyArrayObject *)velocity_array, 0); 122 | npy_intp NumberOfFrequencies = PyArray_DIM((PyArrayObject *)frequency_array, 0); 123 | 124 | 125 | //Create new numpy array for storing result 126 | PyArrayObject *PowerSpectrum_object; 127 | npy_intp dims[] = {NumberOfFrequencies}; 128 | PowerSpectrum_object = (PyArrayObject *) PyArray_SimpleNew(1,dims,NPY_DOUBLE); 129 | 130 | 131 | double *PowerSpectrum = (double*)PyArray_DATA(PowerSpectrum_object); 132 | 133 | //Declare variables 134 | double *Coefficients_r =malloc((NumberOfCoefficients+1)*sizeof(double)); 135 | double *Coefficients_i =malloc((NumberOfCoefficients+1)*sizeof(double)); 136 | 137 | 138 | // Divide complex data to 2 double arrays 139 | double *Velocity_r = (double *)malloc(NumberOfData * sizeof(double)); 140 | double *Velocity_i = (double *)malloc(NumberOfData * sizeof(double)); 141 | 142 | for (int i=0; i < NumberOfData; i++) { 143 | Velocity_r[i] = (double)creal(Velocity[i]); 144 | Velocity_i[i] = (double)cimag(Velocity[i]); 145 | } 146 | 147 | // Maximum Entropy Method Algorithm 148 | double MeanSquareDiscrepancy_r = GetCoefficients(Velocity_r, NumberOfData, NumberOfCoefficients, Coefficients_r); 149 | double MeanSquareDiscrepancy_i = GetCoefficients(Velocity_i, NumberOfData, NumberOfCoefficients, Coefficients_i); 150 | 151 | # pragma omp parallel for default(shared) private(AngularFrequency) 152 | for (int i=0; i < NumberOfFrequencies; i++) { 153 | AngularFrequency = Frequency[i]*2.0*M_PI; 154 | 155 | PowerSpectrum[i] = 0.0; 156 | // if (! isnan(MeanSquareDiscrepancy_r)) { 157 | if (MeanSquareDiscrepancy_r != 0.0) { 158 | PowerSpectrum[i] += FrequencyEvaluation(AngularFrequency*TimeStep, Coefficients_r, NumberOfCoefficients, MeanSquareDiscrepancy_r); 159 | } 160 | if (MeanSquareDiscrepancy_i != 0.0) { 161 | PowerSpectrum[i] += FrequencyEvaluation(AngularFrequency*TimeStep, Coefficients_i, NumberOfCoefficients, MeanSquareDiscrepancy_i); 162 | } 163 | PowerSpectrum[i] *= TimeStep; 164 | } 165 | 166 | // Free python memory 167 | Py_DECREF(velocity_array); 168 | Py_DECREF(frequency_array); 169 | 170 | // Free memory 171 | free(Velocity_r); 172 | free(Coefficients_r); 173 | free(Coefficients_i); 174 | 175 | //Returning Python array 176 | return(PyArray_Return(PowerSpectrum_object)); 177 | } 178 | 179 | // Evaluate MEM function 180 | static double FrequencyEvaluation(double Delta, double Coefficients[], int NumberOfCoefficients, double MeanSquareDiscrepancy) { 181 | 182 | _Dcomplex z = cexp(_Cbuild(0, Delta)); 183 | _Dcomplex sum = _Cbuild(1, 0); 184 | _Dcomplex prod = _Cbuild(0, 0); 185 | 186 | for (int i=1; i <= NumberOfCoefficients; i++) { 187 | //sum -= Coefficients[i] * cpow(z, i); 188 | prod = _Cmulcc(_Cbuild(Coefficients[i],0), cpow(z, _Cbuild(i,0))); 189 | sum = _Cbuild(creal(sum) - creal(prod), cimag(sum) - cimag(prod)); 190 | } 191 | return MeanSquareDiscrepancy/creal(_Cmulcc(sum, conj(sum))); 192 | } 193 | 194 | // Get LP coefficients 195 | static double GetCoefficients(double *Data, int NumberOfData, int NumberOfCoefficients, double Coefficients[]) { 196 | 197 | int k, j, i; 198 | double p=0.0; 199 | 200 | double MeanSquareDiscrepancy; 201 | double *wk1 = malloc(NumberOfData*sizeof(double)); 202 | double *wk2 = malloc(NumberOfData*sizeof(double)); 203 | double *wkm = malloc(NumberOfCoefficients*sizeof(double)); 204 | 205 | 206 | for (j=1; j <= NumberOfData; j++) p += pow(Data[j], 2); 207 | MeanSquareDiscrepancy = p / NumberOfData; 208 | 209 | wk1[1] = Data[1]; 210 | wk2[NumberOfData-1] = Data[NumberOfData]; 211 | 212 | for (j=2; j <= NumberOfData-1; j++) { 213 | wk1[j]=Data[j]; 214 | wk2[j-1]=Data[j]; 215 | } 216 | 217 | for (k=1; k <= NumberOfCoefficients; k++) { 218 | double Numerator = 0.0, Denominator = 0.0; 219 | 220 | for (j=1; j <= (NumberOfData - k); j++) { 221 | Numerator += wk1[j] * wk2[j]; 222 | Denominator += pow(wk1[j],2) + pow(wk2[j], 2); 223 | } 224 | 225 | if (fabs(Denominator) < 1.0e-6) return 0.0; 226 | 227 | Coefficients[k] = 2.0 * Numerator / Denominator; 228 | 229 | MeanSquareDiscrepancy *= (1.0 - pow(Coefficients[k], 2)); 230 | 231 | for (i=1; i <= (k-1); i++) Coefficients[i] = wkm[i] - Coefficients[k] * wkm[k-i]; 232 | 233 | if (k == NumberOfCoefficients) continue; 234 | 235 | for (i=1; i<=k; i++) wkm[i] = Coefficients[i]; 236 | 237 | for (j=1; j <= (NumberOfData-k-1); j++) { 238 | wk1[j] -= wkm[k] * wk2[j]; 239 | wk2[j] = wk2[j+1] - wkm[k] * wk1[j+1]; 240 | } 241 | } 242 | // Free memory 243 | free(wk1); 244 | free(wk2); 245 | free(wkm); 246 | 247 | return MeanSquareDiscrepancy; 248 | }; 249 | -------------------------------------------------------------------------------- /doc/QuickGuide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/doc/QuickGuide.pdf -------------------------------------------------------------------------------- /dynaphopy/analysis/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/dynaphopy/analysis/__init__.py -------------------------------------------------------------------------------- /dynaphopy/analysis/coordinates.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | from dynaphopy.displacements import atomic_displacements 4 | 5 | 6 | def progress_bar(progress): 7 | bar_length = 30 8 | status = "" 9 | if isinstance(progress, int): 10 | progress = float(progress) 11 | if not isinstance(progress, float): 12 | progress = 0 13 | status = "Progress error\r\n" 14 | if progress < 0: 15 | progress = 0 16 | status = "Halt ...\r\n" 17 | if progress >= 1: 18 | progress = 1 19 | status = "Done...\r\n" 20 | block = int(round(bar_length*progress)) 21 | text = "\rTrajectory: [{0}] {1:.2f}% {2}".format("#"*block + "-"*(bar_length-block), 22 | progress*100, status) 23 | sys.stdout.write(text) 24 | sys.stdout.flush() 25 | 26 | 27 | # Not used (only for test) 28 | def relativize_trajectory(dynamic, memmap=False): 29 | 30 | cell = dynamic.get_supercell() 31 | number_of_atoms = dynamic.trajectory.shape[1] 32 | supercell = dynamic.get_supercell_matrix() 33 | position = dynamic.structure.get_positions(supercell=supercell) 34 | # normalized_trajectory = np.zeros_like(dynamic.trajectory.real) 35 | normalized_trajectory = dynamic.trajectory.copy() 36 | 37 | trajectory = dynamic.trajectory 38 | 39 | if memmap: 40 | normalized_trajectory = np.memmap('r_trajectory.map', dtype='complex', mode='w+', shape=trajectory.shape) 41 | else: 42 | normalized_trajectory = dynamic.trajectory.copy() 43 | 44 | # progress_bar(0) 45 | 46 | for i in range(number_of_atoms): 47 | normalized_trajectory[:, i, :] = atomic_displacements(trajectory[:, i, :], position[i], cell) 48 | 49 | # progress_bar(float(i+1)/number_of_atoms) 50 | return normalized_trajectory 51 | 52 | # Not used (only for test) 53 | def relativize_trajectory_py(dynamic): 54 | 55 | print('Using python rutine for calculating atomic displacements') 56 | cell = dynamic.get_supercell() 57 | number_of_atoms = dynamic.trajectory.shape[1] 58 | supercell = dynamic.get_supercell_matrix() 59 | position = dynamic.structure.get_positions(supercell=supercell) 60 | normalized_trajectory = dynamic.trajectory.real.copy() 61 | 62 | progress_bar(0) 63 | 64 | for j in range(number_of_atoms): 65 | for i in range(0, normalized_trajectory.shape[0]): 66 | 67 | difference = normalized_trajectory[i, j, :] - position[j] 68 | 69 | # difference_matrix = np.array(np.dot(np.linalg.inv(cell),(IniSep)),dtype=int) 70 | difference_matrix = np.around(np.dot(np.linalg.inv(cell), difference), decimals=0) 71 | normalized_trajectory[i, j, :] -= np.dot(difference_matrix, cell) + position[j] 72 | 73 | progress_bar(float(j+1)/number_of_atoms) 74 | 75 | return normalized_trajectory 76 | 77 | 78 | def trajectory_projection(dynamic, direction): 79 | 80 | direction = np.array(direction)/np.linalg.norm(direction) 81 | 82 | supercell = dynamic.get_supercell_matrix() 83 | trajectory = dynamic.get_relative_trajectory() 84 | atom_type_index = dynamic.structure.get_atom_type_index(supercell=supercell) 85 | number_of_atom_types = dynamic.structure.get_number_of_atom_types() 86 | 87 | projections = [] 88 | 89 | for j in range(number_of_atom_types): 90 | projection = np.array([]) 91 | for i in range(0, trajectory.shape[1]): 92 | if atom_type_index[i] == j: 93 | # print('atom:', i, 'type:', atom_type_index[i]) 94 | projection = np.append(projection, np.dot(trajectory[:, i, :].real, 95 | direction/np.linalg.norm(direction))) 96 | projections.append(projection) 97 | 98 | return np.array(projections) 99 | -------------------------------------------------------------------------------- /dynaphopy/analysis/energy.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | import scipy.stats as stats 4 | 5 | kb_boltzmann = 0.831446 # u * A^2 / ( ps^2 * K ) 6 | 7 | 8 | def boltzmann_distribution(trajectory, parameters): 9 | 10 | print("\nMaxwell-Boltzmann distribution analysis") 11 | print("----------------------------------------------") 12 | 13 | velocity = np.reshape(np.linalg.norm(trajectory.get_velocity_mass_average(), axis=2), -1) 14 | 15 | average = np.average(velocity) 16 | deviation = np.std(velocity) 17 | print('Average: {0:3.7e} Angstrom/ps'.format(average)) 18 | print('Deviation: {0:3.7e} Angstrom/ps'.format(deviation)) 19 | maxwell = stats.maxwell 20 | 21 | params = maxwell.fit(velocity, floc=0, scale=np.average([average, deviation])) 22 | print('Distribution parameter: {0:3.7e} Angstrom/ps'.format(params[1])) 23 | 24 | temperature = pow(params[1], 2)/ kb_boltzmann 25 | print('Temperature fit: {0:7.6f} K'.format(temperature)) 26 | 27 | if not parameters.silent: 28 | x = np.linspace(0, float(average + 3 * deviation), 100) 29 | fig = plt.figure() 30 | ax = fig.add_subplot(111) 31 | plt.xlabel('Velocity [Angstrom/ps]') 32 | ax.plot(x, maxwell.pdf(x, *params), lw=3) 33 | ax.text(0.95, 0.90, 'Temperature: {0:7.1f} K'.format(temperature), 34 | verticalalignment='bottom', 35 | horizontalalignment='right', 36 | transform=ax.transAxes, 37 | fontsize=15) 38 | 39 | fig.suptitle('Velocity distribution') 40 | ax.hist(velocity, bins=parameters.number_of_bins_histogram, density=True) 41 | 42 | plt.show() 43 | 44 | 45 | 46 | return temperature -------------------------------------------------------------------------------- /dynaphopy/analysis/fitting/__init__.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pyplot as plt 3 | from scipy.integrate import simpson 4 | from dynaphopy.analysis.fitting import fitting_functions 5 | 6 | h_planck = 4.135667662e-3 # eV/ps 7 | h_planck_bar = h_planck/(2.0*np.pi) # eV/ps 8 | kb_boltzmann = 8.6173324e-5 # eV/K 9 | 10 | 11 | def degenerate_sets(freqs, cutoff=1e-4): 12 | indices = [] 13 | done = [] 14 | for i in range(len(freqs)): 15 | if i in done: 16 | continue 17 | else: 18 | f_set = [i] 19 | done.append(i) 20 | for j in range(i + 1, len(freqs)): 21 | if (np.abs(freqs[f_set] - freqs[j]) < cutoff).any(): 22 | f_set.append(j) 23 | done.append(j) 24 | indices.append(f_set[:]) 25 | 26 | return indices 27 | 28 | 29 | def average_phonon(index, data, degeneracy): 30 | for i, set in enumerate(degeneracy): 31 | if index in set: 32 | return np.average([data[:, j] for j in degeneracy[i]], axis=0) 33 | 34 | 35 | def phonon_fitting_analysis(original, ps_frequencies, 36 | harmonic_frequencies=None, 37 | thermal_expansion_shift=None, 38 | fitting_function_type=0, 39 | show_plots=True, 40 | use_degeneracy=True, 41 | show_occupancy=True): 42 | 43 | widths = [] 44 | positions = [] 45 | errors = [] 46 | dt_Q2_s = [] 47 | 48 | for i in range(original.shape[1]): 49 | 50 | if use_degeneracy: 51 | degeneracy = degenerate_sets(harmonic_frequencies) 52 | power_spectrum = average_phonon(i, original, degeneracy) 53 | else: 54 | power_spectrum = original[:, i] 55 | 56 | guess_height = np.max(power_spectrum) 57 | guess_position = ps_frequencies[np.argmax(power_spectrum)] 58 | 59 | Fitting_function_class = fitting_functions.fitting_functions[fitting_function_type] 60 | fitting_function = Fitting_function_class(ps_frequencies, 61 | power_spectrum, 62 | guess_height=guess_height, 63 | guess_position=guess_position) 64 | 65 | fitting_parameters = fitting_function.get_fitting() 66 | 67 | if not fitting_parameters['all_good']: 68 | positions.append(0) 69 | widths.append(0) 70 | errors.append(0) 71 | dt_Q2_s.append(0) 72 | print ('Warning: Fitting not successful in peak #{0}'.format(i+1)) 73 | continue 74 | 75 | position = fitting_parameters['peak_position'] 76 | area = fitting_parameters['area'] 77 | width = fitting_parameters['width'] 78 | base_line = fitting_parameters['base_line'] 79 | maximum = fitting_parameters['maximum'] 80 | error = fitting_parameters['global_error'] 81 | 82 | total_integral = simpson(power_spectrum, x=ps_frequencies) 83 | 84 | # Calculated properties 85 | dt_Q2_lor = 2 * area 86 | dt_Q2_tot = 2 * total_integral 87 | 88 | try: 89 | # Only within harmonic approximation 90 | # Q2_lor = dt_Q2_lor / pow(position * 2 * np.pi, 2) 91 | # Q2_tot = dt_Q2_tot / pow(position * 2 * np.pi,2) 92 | 93 | occupancy_lor = dt_Q2_lor / (position * h_planck_bar) - 0.5 94 | occupancy_tot = dt_Q2_tot / (position * h_planck_bar) - 0.5 95 | 96 | # fit_temperature = dt_Q2_lor / kb_boltzmann # High temperature limit 97 | fit_temperature = h_planck_bar * position / (kb_boltzmann * np.log((1.0 / occupancy_lor + 1.0))) 98 | fit_temperature_tot = h_planck_bar * position / (kb_boltzmann * np.log((1.0 / occupancy_tot + 1.0))) 99 | 100 | except RuntimeWarning: 101 | # This warning happens in acoustic branches at gamma point because the peak 102 | # position is zero (If this warning is raised at GAMMA it is OK!) 103 | occupancy_lor = np.nan 104 | occupancy_tot = np.nan 105 | fit_temperature = np.nan 106 | fit_temperature_tot = np.nan 107 | error = np.nan 108 | pass 109 | 110 | #Print section 111 | print ('\nPeak # {0}'.format(i+1)) 112 | print ('----------------------------------------------') 113 | print ('Width {0:15.6f} THz'.format(width)) 114 | print ('Position {0:15.6f} THz'.format(position)) 115 | print ('Area () ({0:.10s}) {1:15.6f} eV'.format(fitting_function.curve_name, area)) # Kinetic energy 116 | print ('Area () (Total) {0:15.6f} eV'.format(total_integral)) # 1/2 Kinetic energy 117 | print ('<|dQ/dt|^2> {0:15.6f} eV'.format(dt_Q2_lor)) # Kinetic energy 118 | # print '<|dQ/dt|^2> (tot): ', dt_Q2_tot, 'eV' # Kinetic energy 119 | # print '<|Q|^2> (lor): ', Q2_lor, 'eV' # potential energy 120 | # print '<|Q|^2> (tot): ', Q2_tot, 'eV' # potential energy 121 | if show_occupancy: 122 | print ('Occupation number {0:15.6f}'.format(occupancy_lor)) 123 | print ('Fit temperature {0:15.6f} K'.format(fit_temperature)) 124 | #print ('Fit temperature (Total) {0:15.6f} K'.format(fit_temperature_tot)) 125 | 126 | print ('Base line {0:15.6f} eV * ps'.format(base_line)) 127 | print ('Maximum height {0:15.6f} eV * ps'.format(maximum)) 128 | print ('Fitting global error {0:15.6f}'.format(error)) 129 | 130 | if 'asymmetry' in fitting_parameters: 131 | asymmetry = fitting_parameters['asymmetry'] 132 | print ('Peak asymmetry {0:15.6f}'.format(asymmetry)) 133 | 134 | if harmonic_frequencies is not None: 135 | print ('Frequency shift {0:15.6f} THz'.format(position - harmonic_frequencies[i])) 136 | 137 | if thermal_expansion_shift is not None: 138 | print ('Frequency shift (+T. exp.) {0:15.6f} THz'.format(position - harmonic_frequencies[i] + thermal_expansion_shift[i])) 139 | position += thermal_expansion_shift[i] 140 | 141 | positions.append(position) 142 | widths.append(width) 143 | errors.append(error/maximum) 144 | dt_Q2_s.append(dt_Q2_lor) 145 | 146 | if show_plots: 147 | plt.figure(i+1) 148 | 149 | plt.xlabel('Frequency [THz]') 150 | plt.ylabel('eV * ps') 151 | 152 | plt.title('Curve fitting') 153 | 154 | plt.suptitle('Phonon {0}'.format(i+1)) 155 | plt.text(position+width, guess_height/2, 'Width: ' + "{:10.4f}".format(width), 156 | fontsize=12) 157 | 158 | plt.plot(ps_frequencies, power_spectrum, 159 | label='Power spectrum') 160 | 161 | plt.plot(ps_frequencies, fitting_function.get_curve(ps_frequencies), 162 | label=fitting_function.curve_name, 163 | linewidth=3) 164 | 165 | # plt.plot(test_frequencies_range, dumped_harmonic(test_frequencies_range, *fit_params[:4]), 166 | # label='Lorentzian fit', 167 | # linewidth=3) 168 | 169 | # plt.plot(test_frequencies_range, lorentzian_asymmetric(test_frequencies_range, *fit_params), 170 | # label=('As. Lorentzian fit' if asymmetric_peaks else 'Lorentizian fit'), 171 | # linewidth=3) 172 | 173 | plt.axvline(x=position, color='k', ls='dashed') 174 | plt.ylim(bottom=0) 175 | plt.xlim([ps_frequencies[0], ps_frequencies[-1]]) 176 | try: 177 | plt.fill_between([position-width/2, position+width/2], plt.gca().get_ylim()[1], color='red', alpha='0.2') 178 | except TypeError: 179 | pass 180 | plt.legend() 181 | 182 | if show_plots: 183 | plt.show() 184 | 185 | return {'positions': positions, 186 | 'widths': widths, 187 | 'error': errors, 188 | 'dt_Q2': dt_Q2_s} -------------------------------------------------------------------------------- /dynaphopy/analysis/modes.py: -------------------------------------------------------------------------------- 1 | from matplotlib import pyplot as plt 2 | from matplotlib.patches import FancyArrowPatch 3 | from matplotlib import lines 4 | from mpl_toolkits.mplot3d import proj3d 5 | import numpy as np 6 | 7 | 8 | class Arrow3D(FancyArrowPatch): 9 | def __init__(self, xs, ys, zs, *args, **kwargs): 10 | FancyArrowPatch.__init__(self, (0.0, 0.0), (0.0, 0.0), *args, **kwargs) 11 | self._verts3d = xs, ys, zs 12 | 13 | def draw(self, renderer): 14 | xs3d, ys3d, zs3d = self._verts3d 15 | xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M) 16 | self.set_positions((xs[0], ys[0]), (xs[1], ys[1])) 17 | FancyArrowPatch.draw(self, renderer) 18 | 19 | 20 | def plot_phonon_modes(structure, eigenvectors, q_vector, 21 | supercell=(1, 1, 1), 22 | draw_primitive=False, 23 | vectors_scale=10, 24 | by_element=True): 25 | 26 | atom_type = structure.get_atom_type_index(supercell=supercell) 27 | positions = structure.get_positions(supercell=supercell) 28 | masses = structure.get_masses(supercell=supercell) 29 | elements = structure.get_atomic_elements(supercell=supercell) 30 | np.set_printoptions(precision=8, suppress=True) 31 | 32 | cell_t = structure.get_cell() 33 | if draw_primitive: 34 | cell_t = structure.get_primitive_cell() 35 | 36 | for i_phonon in range(eigenvectors.shape[0]): 37 | 38 | fig = plt.figure(i_phonon+1) 39 | if draw_primitive: 40 | fig.suptitle('Primitive cell') 41 | else: 42 | fig.suptitle('Unit cell') 43 | 44 | ax = fig.add_subplot(111, projection='3d') 45 | 46 | color_atom=['g','b','m', 'c', 'y', 'k', 'w', 'g', 'b', 'm', 'c', 'y', 'k', 'w','g','b','m', 'c', 'y', 47 | 'k', 'w', 'g', 'b', 'm', 'c', 'y', 'k', 'w','g','b','m', 'c', 'y', 'k', 'w', 'g', 'b'] 48 | 49 | if by_element: 50 | elements_unique = np.unique(elements, return_inverse=True)[1] 51 | else: 52 | elements_unique = atom_type 53 | 54 | # Atom positions 55 | for i, atom in enumerate(positions): 56 | ax.plot(atom[0][None], atom[1][None], atom[2][None], 'o', markersize=atom_radius[elements[i]]*30, color=color_atom[elements_unique[i]], alpha=0.8) 57 | 58 | # Cell frame 59 | for i in range(3): 60 | cell_side = [(0, cell_t[i, 0]), (0, cell_t[i, 1]), (0, cell_t[i, 2])] 61 | ax.plot3D(*cell_side, color='b') 62 | for j in range(3): 63 | if i != j: 64 | cell_side = [(cell_t[i, l], 65 | cell_t[i, l]+cell_t[j, l]) for l in range(3)] 66 | 67 | ax.plot3D(*cell_side, color='b') 68 | for k in range(3): 69 | if k != i and k != j and j > i: 70 | cell_side = [(cell_t[i, l]+cell_t[j, l], 71 | cell_t[i, l]+cell_t[j, l]+cell_t[k, l]) for l in range(3)] 72 | 73 | ax.plot3D(*cell_side, color='b') 74 | 75 | # Atom positions 76 | for i, position in enumerate(positions): 77 | eigenvector_atom = np.array(eigenvectors[i_phonon, atom_type[i], :]) 78 | phase = 1.j * np.dot(position, q_vector) 79 | vector = (eigenvector_atom / np.sqrt(masses[atom_type[i]]) * np.exp(phase) * vectors_scale).real 80 | # vector = np.dot(vector, np.linalg.inv(structure.get_primitive_matrix().T)) 81 | a = Arrow3D([position[0], position[0]+vector[0]], [position[1], position[1]+vector[1]], 82 | [position[2], position[2]+vector[2]], mutation_scale=20, lw=3, arrowstyle="-|>", color="r") 83 | ax.add_artist(a) 84 | 85 | # Legend 86 | atom_type_index_unique = np.unique(atom_type, return_index=True)[0] 87 | 88 | 89 | 90 | if by_element: 91 | atomic_types_unique = np.unique(elements, return_inverse=True)[0] 92 | else: 93 | atomic_types_unique = [elements[i] for i in atom_type_index_unique] 94 | 95 | legend_atoms = [ lines.Line2D([0],[0], linestyle='none', c=color_atom[i], marker='o') for i, element in enumerate(atomic_types_unique)] 96 | ax.legend(legend_atoms, atomic_types_unique, numpoints = 1) 97 | 98 | # ax.set_axis_off() 99 | ax.set_xlabel('X') 100 | ax.set_ylabel('Y') 101 | ax.set_zlabel('Z') 102 | 103 | plt.title('Phonon {0}'.format(i_phonon+1)) 104 | plt.axis('auto') 105 | plt.show() 106 | 107 | return 108 | 109 | 110 | atom_radius = { 111 | 'H':0.32, 112 | 'He':0.93, 113 | 'Li':1.23, 114 | 'Be':0.9, 115 | 'B':0.82, 116 | 'C':0.77, 117 | 'N':0.75, 118 | 'O':0.73, 119 | 'F':0.72, 120 | 'Ne':0.71, 121 | 'Na':1.54, 122 | 'Mg':1.36, 123 | 'Al':1.18, 124 | 'Si':1.11, 125 | 'P':1.06, 126 | 'S':1.02, 127 | 'Cl':0.99, 128 | 'Ar':0.98, 129 | 'K':2.03, 130 | 'Ca':1.74, 131 | 'Sc':1.44, 132 | 'Ti':1.32, 133 | 'V':1.22, 134 | 'Cr':1.18, 135 | 'Mn':1.17, 136 | 'Fe':1.17, 137 | 'Co':1.16, 138 | 'Ni':1.15, 139 | 'Cu':1.17, 140 | 'Zn':1.25, 141 | 'Ga':1.26, 142 | 'Ge':1.22, 143 | 'As':1.2, 144 | 'Se':1.16, 145 | 'Br':1.14, 146 | 'Kr':1.12, 147 | 'Rb':2.16, 148 | 'Sr':1.91, 149 | 'Y':1.62, 150 | 'Zr':1.45, 151 | 'Nb':1.34, 152 | 'Mo':1.3, 153 | 'Tc':1.27, 154 | 'Ru':1.25, 155 | 'Rh':1.25, 156 | 'Pd':1.28, 157 | 'Ag':1.34, 158 | 'Cd':1.48, 159 | 'In':1.44, 160 | 'Sn':1.41, 161 | 'Sb':1.4, 162 | 'Te':1.36, 163 | 'I':1.33, 164 | 'Xe':1.31, 165 | 'Cs':2.35, 166 | 'Ba':1.98, 167 | 'La':1.69, 168 | 'Ce':1.65, 169 | 'Pr':1.65, 170 | 'Nd':1.64, 171 | 'Pm':1.63, 172 | 'Sm':1.62, 173 | 'Eu':1.85, 174 | 'Gd':1.61, 175 | 'Tb':1.59, 176 | 'Dy':1.59, 177 | 'Ho':1.58, 178 | 'Er':1.57, 179 | 'Tm':1.56, 180 | 'Yb':1.74, 181 | 'Lu':1.56, 182 | 'Hf':1.44, 183 | 'Ta':1.34, 184 | 'W':1.3, 185 | 'Re':1.28, 186 | 'Os':1.26, 187 | 'Ir':1.27, 188 | 'Pt':1.3, 189 | 'Au':1.34, 190 | 'Hg':1.49, 191 | 'Tl':1.48, 192 | 'Pb':1.47, 193 | 'Bi':1.46, 194 | 'Po':1.46, 195 | 'At':1.45, 196 | 'Rn':0.0, 197 | 'Fr':0.0, 198 | 'Ra':0.0, 199 | 'Ac':0.0, 200 | 'Th':1.65, 201 | 'Pa':0.0, 202 | 'U':1.42, 203 | 'Np':0.0, 204 | 'Pu':0.0, 205 | 'Am':0.0, 206 | 'Cm':0.0, 207 | 'Bk':0.0, 208 | 'Cf':0.0, 209 | 'Es':0.0, 210 | 'Fm':0.0, 211 | 'Md':0.0, 212 | 'No':0.0, 213 | 'Lr':0.0, 214 | 'Rf':0.0, 215 | 'Db':0.0, 216 | 'Sg':0.0, 217 | 'Bh':0.0, 218 | 'Hs':0.0, 219 | 'Mt':0.0, 220 | } -------------------------------------------------------------------------------- /dynaphopy/analysis/peaksearch.py: -------------------------------------------------------------------------------- 1 | from scipy import signal 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | def get_frequencies_from_correlation(correlation_vector,test_frequencies_range): 6 | 7 | frequencies = [] 8 | for branch in range(correlation_vector.shape[1]): 9 | peakind = signal.find_peaks_cwt(correlation_vector[:,branch].real, np.arange(1,200) ) 10 | 11 | # plt.plot(test_frequencies_range,correlation_vector[:,branch].real) 12 | # plt.plot([test_frequencies_range[i] for i in peakind],[correlation_vector[i,branch].real for i in peakind],'ro') 13 | # plt.show() 14 | 15 | heights = [correlation_vector[i,branch] for i in peakind] 16 | max_height_index = heights.index(max(heights)) 17 | frequencies.append(test_frequencies_range[peakind[max_height_index]]) 18 | 19 | return np.array(frequencies) 20 | 21 | 22 | -------------------------------------------------------------------------------- /dynaphopy/analysis/thermal_properties.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import matplotlib.pylab as pl 3 | import warnings 4 | from scipy import integrate 5 | 6 | N_a = 6.022140857e23 7 | k_b = 1.38064852e-23 # J / K 8 | h_bar = 6.626070040e-22 # J * ps 9 | 10 | warnings.simplefilter("ignore") 11 | 12 | 13 | def get_dos(temp, frequency, power_spectrum, n_size, bose_einstein_statistics=False): 14 | 15 | conversion_factor = 1.60217662e-19 # eV -> J 16 | 17 | def n(temp, freq): 18 | return pow(np.exp(freq*h_bar/(k_b*temp))-1, -1) 19 | 20 | if bose_einstein_statistics: 21 | def energy(freq, temp): 22 | return h_bar*freq*(0.5+n(temp, freq)) 23 | else: 24 | def energy(freq, temp): 25 | return k_b * temp 26 | 27 | dos = np.nan_to_num([2.0*conversion_factor*power_spectrum[i]/(energy(freq, temp)*n_size) 28 | for i, freq in enumerate(frequency)]) 29 | return dos 30 | 31 | 32 | def get_total_energy(temperature, frequency, dos): 33 | 34 | def n(temp, freq): 35 | return pow(np.exp(freq*h_bar/(k_b*temp))-1, -1) 36 | 37 | total_energy = np.nan_to_num([dos[i] * h_bar * freq * (0.5 + n(temperature, freq)) 38 | for i, freq in enumerate(frequency)]) 39 | 40 | total_energy = integrate.simpson(total_energy, x=frequency) * N_a / 1000 # KJ/K/mol 41 | return total_energy 42 | 43 | 44 | def get_free_energy(temperature, frequency, dos): 45 | 46 | free_energy = np.nan_to_num([dos[i] * k_b * temperature * np.log(2 * np.sinh(h_bar * freq / (2 * k_b * temperature))) 47 | for i, freq in enumerate(frequency)]) 48 | 49 | free_energy[0] = 0 50 | free_energy = integrate.simpson(free_energy, x=frequency) * N_a / 1000 # KJ/K/mol 51 | return free_energy 52 | 53 | 54 | def get_free_energy_correction_shift(temperature, frequency, dos, shift): 55 | 56 | def n(temp, freq): 57 | return pow(np.exp(freq*h_bar/(k_b*temp))-1, -1) 58 | 59 | free_energy_c = np.nan_to_num([dos[i] * -h_bar/2 *shift*(n(temperature, freq) + 1 / 2.) 60 | for i, freq in enumerate(frequency)]) 61 | 62 | free_energy_c = integrate.simpson(free_energy_c, x=frequency) * N_a / 1000 # KJ/K/mol 63 | return free_energy_c 64 | 65 | 66 | def get_free_energy_correction_dos(temperature, frequency, dos, dos_r): 67 | 68 | def n(temp, freq): 69 | return pow(np.exp(freq*h_bar/(k_b*temp))-1, -1) 70 | 71 | free_energy_1 = np.nan_to_num([ dos_r[i] * -h_bar/2 * freq*(n(temperature, freq) + 1 / 2.) 72 | for i, freq in enumerate(frequency)]) 73 | 74 | free_energy_2 = np.nan_to_num([ dos[i] * -h_bar/2 * freq*(n(temperature, freq) + 1 / 2.) 75 | for i, freq in enumerate(frequency)]) 76 | 77 | free_energy_c = free_energy_1 - free_energy_2 78 | 79 | free_energy_c = integrate.simpson(free_energy_c, x=frequency) * N_a / 1000 # KJ/K/mol 80 | return free_energy_c 81 | 82 | 83 | def get_entropy(temperature, frequency, dos): 84 | 85 | def coth(x): 86 | return np.cosh(x)/np.sinh(x) 87 | 88 | entropy = np.nan_to_num([dos[i]*(1.0 / (2. * temperature) * h_bar * freq * coth(h_bar * freq / (2 * k_b * temperature)) 89 | - k_b * np.log(2 * np.sinh(h_bar * freq / (2 * k_b * temperature)))) 90 | for i, freq in enumerate(frequency)]) 91 | entropy = integrate.simpson(entropy, x=frequency) * N_a # J/K/mol 92 | return entropy 93 | 94 | # Alternative way to calculate entropy (not used) 95 | def get_entropy2(temperature, frequency, dos): 96 | 97 | def n(temp, freq): 98 | return pow(np.exp(freq*h_bar/(k_b*temp))-1, -1) 99 | 100 | entropy = np.nan_to_num([dos[i] * k_b * ((n(temperature, freq) + 1) * np.log(n(temperature, freq) + 1) 101 | - n(temperature, freq) * np.log(n(temperature, freq))) 102 | for i, freq in enumerate(frequency)]) 103 | entropy = integrate.simpson(entropy, x=frequency) * N_a # J/K/mol 104 | return entropy 105 | 106 | 107 | def get_cv(temperature, frequency, dos): 108 | 109 | def z(temp, freq): 110 | return h_bar*freq/(k_b*temp) 111 | 112 | c_v = np.nan_to_num([dos[i] * k_b * pow(z(temperature, freq), 2) * np.exp(z(temperature, freq)) / pow(np.exp(z(temperature, freq)) - 1, 2) 113 | for i, freq in enumerate(frequency)]) 114 | c_v = integrate.simpson(c_v, x=frequency) * N_a # J/K/mol 115 | 116 | return c_v 117 | 118 | if __name__ == "__main__": 119 | 120 | shift = 0.05 121 | 122 | #temp = 300 123 | #dos_file = open('/Users/abel/TEST_GPU/GaN/total_dos.dat', mode='r') 124 | #dos_r_file = open('/Users/abel/TEST_GPU/GaN/total_dos_o.dat', mode='r') 125 | #power_file = open('/Users/abel/TEST_GPU/GaN/power_spectrum.dat', mode='r') 126 | 127 | temp=900 128 | dos_file = open('/home/abel/LAMMPS/Si/total_dos_h.dat', mode='r') 129 | dos_r_file = open('/home/abel/LAMMPS/Si/total_dos_o.dat', mode='r') 130 | power_file = open('/home/abel/LAMMPS/Si/power_spectrum_900_12_fft_vlong.dat', mode='r') 131 | 132 | frequency = [] 133 | dos = [] 134 | for line in dos_file.readlines()[1:]: 135 | frequency.append(float(line.split()[0])) 136 | dos.append(float(line.split()[1])) 137 | 138 | frequency_r = [] 139 | dos_r = [] 140 | for line in dos_r_file.readlines()[1:]: 141 | frequency_r.append(float(line.split()[0])) 142 | dos_r.append(float(line.split()[1])) 143 | 144 | frequency_p = [] 145 | power_spectrum = [] 146 | for line in power_file.readlines(): 147 | frequency_p.append(float(line.split()[0])) 148 | power_spectrum.append(float(line.split()[1])) 149 | 150 | # power_spectrum = get_dos(temp,frequency_p,power_spectrum, 12*12*6) 151 | 152 | power_spectrum = get_dos(temp, frequency_p, power_spectrum, 12*12*12) 153 | 154 | pl.plot(frequency_p, power_spectrum, label='power') 155 | pl.plot(frequency, dos,label='dos') 156 | pl.plot(frequency_r, dos_r, label='dos_r') 157 | pl.legend() 158 | pl.show() 159 | 160 | # free_energy = get_free_energy(temp,frequency,dos) + get_free_energy_correction(temp, frequency, dos, shift) 161 | 162 | print (get_free_energy_correction_shift(temp, frequency, dos, shift), 163 | get_free_energy_correction_dos(temp, frequency, dos, dos_r)) 164 | 165 | free_energy = get_free_energy(temp, frequency_r, dos_r) + get_free_energy_correction_dos(temp, frequency, dos_r, dos) 166 | entropy = get_entropy(temp, frequency_r, dos_r) 167 | c_v = get_cv(temp, frequency_r, dos_r) 168 | print ('Renormalized') 169 | print ('-------------------------') 170 | print ('Free energy: {0} KJ/K/mol'.format(free_energy)) 171 | print ('Entropy: {0} J/K/mol'.format(entropy)) 172 | print ('Cv: {0} J/K/mol'.format(c_v)) 173 | print (np.trapz(dos_r, x=frequency_r))/(8*3) 174 | print (integrate.simpson(dos_r,x=frequency_r)/(8*3)) 175 | 176 | print ('\nFrom MD') 177 | print ('-------------------------') 178 | free_energy = get_free_energy(temp, frequency_p, power_spectrum) 179 | entropy = get_entropy(temp, frequency_p, power_spectrum) 180 | c_v = get_cv(temp, frequency_p, power_spectrum) 181 | 182 | print ('Free energy: {0} KJ/K/mol'.format(free_energy)) 183 | print ('Entropy: {0} J/K/mol'.format(entropy)) 184 | print ('Cv: {0} J/K/mol'.format(c_v)) 185 | print (np.trapz(power_spectrum, x=frequency_p))/(8*3) 186 | print (integrate.simpson(power_spectrum, x=frequency_p))/(8*3) 187 | 188 | print ('\nHARMONIC') 189 | print ('-------------------------') 190 | free_energy = get_free_energy(temp, frequency, dos) 191 | entropy = get_entropy(temp, frequency, dos) 192 | c_v = get_cv(temp, frequency, dos) 193 | 194 | print ('Free energy: {0} KJ/K/mol'.format(free_energy)) 195 | print ('Entropy: {0} J/K/mol'.format(entropy)) 196 | print ('Cv: {0} J/K/mol'.format(c_v)) 197 | print (np.trapz(dos, x=frequency)/(8*3)) 198 | print (integrate.simpson(dos, x=frequency)/(8*3)) -------------------------------------------------------------------------------- /dynaphopy/generate_cell.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def generate_VASP_structure(structure, scaled=False, supercell=(1, 1, 1)): 5 | 6 | cell = structure.get_cell(supercell=supercell) 7 | 8 | types = structure.get_atomic_elements(supercell=supercell) 9 | 10 | atom_type_unique = np.unique(types, return_index=True) 11 | 12 | # To use unique without sorting 13 | sort_index = np.argsort(atom_type_unique[1]) 14 | elements = np.array(atom_type_unique[0])[sort_index] 15 | elements_count= np.diff(np.append(np.array(atom_type_unique[1])[sort_index], [len(types)])) 16 | 17 | 18 | vasp_POSCAR = 'Generated using dynaphopy\n' 19 | vasp_POSCAR += '1.0\n' 20 | for row in cell: 21 | vasp_POSCAR += '{0:20.10f} {1:20.10f} {2:20.10f}\n'.format(*row) 22 | vasp_POSCAR += ' '.join(elements) 23 | vasp_POSCAR += ' \n' 24 | vasp_POSCAR += ' '.join([str(i) for i in elements_count]) 25 | 26 | if scaled: 27 | scaled_positions = structure.get_scaled_positions(supercell=supercell) 28 | vasp_POSCAR += '\nDirect\n' 29 | for row in scaled_positions: 30 | vasp_POSCAR += '{0:15.15f} {1:15.15f} {2:15.15f}\n'.format(*row) 31 | 32 | else: 33 | positions = structure.get_positions(supercell=supercell) 34 | vasp_POSCAR += '\nCartesian\n' 35 | for row in positions: 36 | vasp_POSCAR += '{0:20.10f} {1:20.10f} {2:20.10f}\n'.format(*row) 37 | 38 | return vasp_POSCAR 39 | 40 | 41 | def generate_LAMMPS_structure(structure, supercell=(1, 1, 1), by_element=True): 42 | 43 | types = structure.get_atomic_elements(supercell=supercell) 44 | 45 | if by_element: 46 | 47 | type_index_unique = np.unique(types, return_index=True)[1] 48 | 49 | # To use unique without sorting 50 | sort_index = np.argsort(type_index_unique) 51 | type_index_unique = np.array(type_index_unique)[sort_index] 52 | 53 | count_index_unique = np.diff(np.append(type_index_unique, [len(types)])) 54 | 55 | atom_index = [] 56 | for i, index in enumerate(count_index_unique): 57 | atom_index += [i for j in range(index)] 58 | 59 | else: 60 | atom_index = structure.get_atom_type_index(supercell=supercell) 61 | 62 | atom_index_unique = np.unique(atom_index, return_index=True)[1] 63 | 64 | masses = structure.get_masses(supercell=supercell) 65 | charges = structure.get_charges(supercell=supercell) 66 | 67 | positions = structure.get_positions(supercell=supercell) 68 | number_of_atoms = len(positions) 69 | 70 | lammps_data_file = 'Generated using dynaphopy\n\n' 71 | lammps_data_file += '{0} atoms\n\n'.format(number_of_atoms) 72 | lammps_data_file += '{0} atom types\n\n'.format(len(atom_index_unique)) 73 | 74 | cell = structure.get_cell(supercell=supercell) 75 | 76 | # generate lammps oriented lattice vectors 77 | ax = np.linalg.norm(cell[0]) 78 | bx = np.dot(cell[1], cell[0]/np.linalg.norm(cell[0])) 79 | by = np.linalg.norm(np.cross(cell[0]/np.linalg.norm(cell[0]), cell[1])) 80 | cx = np.dot(cell[2], cell[0]/np.linalg.norm(cell[0])) 81 | cy = (np.dot(cell[1], cell[2])- bx*cx)/by 82 | cz = np.sqrt(np.dot(cell[2],cell[2])-pow(cx,2)-pow(cy,2)) 83 | 84 | # get rotation matrix (poscar->lammps) from lattice vectors matrix 85 | lammps_cell = np.array([[ax, bx, cx],[0, by, cy],[0,0,cz]]) 86 | trans_cell = np.dot(np.linalg.inv(cell), lammps_cell.T) 87 | 88 | # rotate positions to lammps orientation 89 | positions = np.dot(positions, trans_cell) 90 | 91 | # build lammps lattice vectors 92 | a, b, c, alpha, beta, gamma = structure.get_cell_parameters(supercell=supercell) 93 | 94 | xhi = a 95 | xy = b * np.cos(gamma) 96 | xz = c * np.cos(beta) 97 | yhi = np.sqrt(pow(b,2)-pow(xy,2)) 98 | yz = (b*c*np.cos(alpha)-xy * xz)/yhi 99 | zhi = np.sqrt(pow(c,2)-pow(xz,2)-pow(yz,2)) 100 | 101 | xhi = xhi + max(0,0, xy, xz, xy+xz) 102 | yhi = yhi + max(0,0, yz) 103 | 104 | if xy > 0: 105 | xhi -= xy 106 | if xz > 0: 107 | xhi -= xz 108 | if yz > 0: 109 | yhi -= yz 110 | 111 | # write lammpstrj file 112 | lammps_data_file += '\n{0:20.10f} {1:20.10f} xlo xhi\n'.format(0, xhi) 113 | lammps_data_file += '{0:20.10f} {1:20.10f} ylo yhi\n'.format(0, yhi) 114 | lammps_data_file += '{0:20.10f} {1:20.10f} zlo zhi\n'.format(0, zhi) 115 | lammps_data_file += '{0:20.10f} {1:20.10f} {2:20.10f} xy xz yz\n\n'.format(xy, xz, yz) 116 | 117 | lammps_data_file += 'Masses\n\n' 118 | 119 | for i, index in enumerate(atom_index_unique): 120 | lammps_data_file += '{0} {1:20.10f} \n'.format(i+1, masses[index]) 121 | 122 | lammps_data_file += '\nAtoms\n\n' 123 | 124 | if charges is not None: 125 | for i, row in enumerate(positions): 126 | lammps_data_file += '{0} {1} {2} {3:20.10f} {4:20.10f} {5:20.10f}\n'.format(i + 1, atom_index[i] + 1, 127 | charges[i], row[0], row[1], row[2]) 128 | else: 129 | for i, row in enumerate(positions): 130 | lammps_data_file += '{0} {1} {2:20.10f} {3:20.10f} {4:20.10f}\n'.format(i+1, atom_index[i]+1, row[0],row[1],row[2]) 131 | 132 | return lammps_data_file 133 | 134 | if __name__ == "__main__": 135 | 136 | import dynaphopy.interface.iofile as reading 137 | input_parameters = reading.read_parameters_from_input_file('/home/abel/VASP/Ag2Cu2O4/MD/input_dynaphopy') 138 | structure = reading.read_from_file_structure_poscar(input_parameters['structure_file_name_poscar']) 139 | # print(generate_VASP_structure(structure)) 140 | print(generate_LAMMPS_structure(structure)) -------------------------------------------------------------------------------- /dynaphopy/interface/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'abel' 2 | -------------------------------------------------------------------------------- /dynaphopy/interface/lammps_link.py: -------------------------------------------------------------------------------- 1 | import dynaphopy.dynamics as dyn 2 | import numpy as np 3 | from dynaphopy.power_spectrum import _progress_bar 4 | from lammps import lammps 5 | from dynaphopy.interface.iofile import get_correct_arrangement 6 | 7 | 8 | def generate_lammps_trajectory(structure, 9 | input_file, 10 | total_time=0.1, # picoseconds 11 | time_step=0.002, # picoseconds 12 | relaxation_time=0, 13 | silent=False, 14 | supercell=(1, 1, 1), 15 | memmap=False, # not fully implemented yet! 16 | velocity_only=False, 17 | lammps_log=True, 18 | temperature=None, 19 | thermostat_mass=0.5, 20 | sampling_interval=1): # in timesteps 21 | 22 | cmdargs_lammps = ['-echo','none', '-screen', 'none'] 23 | if not lammps_log: 24 | cmdargs_lammps += ['-log', 'none'] 25 | 26 | lmp = lammps(cmdargs=cmdargs_lammps) 27 | 28 | lmp.file(input_file) 29 | lmp.command('timestep {}'.format(time_step)) 30 | 31 | lmp.command('replicate {} {} {}'.format(*supercell)) 32 | 33 | # Force reset temperature (overwrites lammps script) 34 | # This forces NVT simulation 35 | if temperature is not None: 36 | print ('Temperature reset to {} (NVT)'.format(temperature)) 37 | lmp.command('fix int all nvt temp {0} {0} {1}'.format(temperature, 38 | thermostat_mass)) 39 | # Check if correct number of atoms 40 | if lmp.extract_global("natoms",0) < 2: 41 | print ('Number of atoms in MD should be higher than 1!') 42 | exit() 43 | 44 | # Check if initial velocities all zero 45 | if not np.array(lmp.gather_atoms("v", 1, 3)).any(): 46 | print('Set lammps initial velocities') 47 | t = temperature if temperature is not None else 100 48 | lmp.command('velocity all create {} 3627941 dist gaussian mom yes'.format(t)) 49 | lmp.command('velocity all scale {}'.format(t)) 50 | 51 | lmp.command('run 0') 52 | 53 | # natoms = lmp.extract_global("natoms",0) 54 | # mass = lmp.extract_atom("mass",2) 55 | # temp = lmp.extract_compute("thermo_temp",0,0) 56 | # print("Temperature from compute =",temp) 57 | # print("Natoms, mass, x[0][0] coord =", natoms, mass[1], x[0][0]) 58 | # print ('thermo', lmp.get_thermo('1')) 59 | 60 | try: 61 | xlo =lmp.extract_global("boxxlo") 62 | xhi =lmp.extract_global("boxxhi") 63 | ylo =lmp.extract_global("boxylo") 64 | yhi =lmp.extract_global("boxyhi") 65 | zlo =lmp.extract_global("boxzlo") 66 | zhi =lmp.extract_global("boxzhi") 67 | xy =lmp.extract_global("xy") 68 | yz =lmp.extract_global("yz") 69 | xz =lmp.extract_global("xz") 70 | 71 | except TypeError: 72 | xlo =lmp.extract_global("boxxlo", 1) 73 | xhi =lmp.extract_global("boxxhi", 1) 74 | ylo =lmp.extract_global("boxylo", 1) 75 | yhi =lmp.extract_global("boxyhi", 1) 76 | zlo =lmp.extract_global("boxzlo", 1) 77 | zhi =lmp.extract_global("boxzhi", 1) 78 | xy =lmp.extract_global("xy", 1) 79 | yz =lmp.extract_global("yz", 1) 80 | xz =lmp.extract_global("xz", 1) 81 | 82 | except UnboundLocalError: 83 | boxlo, boxhi, xy, yz, xz, periodicity, box_change = lmp.extract_box() 84 | xlo, ylo, zlo = boxlo 85 | xhi, yhi, zhi = boxhi 86 | 87 | simulation_cell = np.array([[xhi-xlo, xy, xz], 88 | [0, yhi-ylo, yz], 89 | [0, 0, zhi-zlo]]).T 90 | 91 | positions = [] 92 | velocity = [] 93 | energy = [] 94 | 95 | na = lmp.get_natoms() 96 | id = lmp.extract_atom("id", 0) 97 | id = np.array([id[i] - 1 for i in range(na)], dtype=int) 98 | 99 | xp = lmp.extract_atom("x", 3) 100 | reference = np.array([[xp[i][0], xp[i][1], xp[i][2]] for i in range(na)], dtype=float)[id, :] 101 | 102 | # xc = lmp.gather_atoms("x", 1, 3) 103 | # reference = np.array([xc[i] for i in range(na*3)]).reshape((na,3)) 104 | 105 | template = get_correct_arrangement(reference, structure) 106 | indexing = np.argsort(template) 107 | 108 | lmp.command('variable energy equal pe'.format(int(relaxation_time/time_step))) 109 | lmp.command('run {}'.format(int(relaxation_time/time_step))) 110 | 111 | if not silent: 112 | _progress_bar(0, 'lammps') 113 | 114 | n_loops = int(total_time / time_step / sampling_interval) 115 | for i in range(n_loops): 116 | if not silent: 117 | _progress_bar(float((i+1) * time_step * sampling_interval) / total_time, 'lammps', ) 118 | 119 | lmp.command('run {}'.format(sampling_interval)) 120 | 121 | # xc = lmp.gather_atoms("x", 1, 3) 122 | # vc = lmp.gather_atoms("v", 1, 3) 123 | energy.append(lmp.extract_variable('energy', 'all', 0)) 124 | 125 | id = lmp.extract_atom("id", 0) 126 | id = np.array([id[i] - 1 for i in range(na)], dtype=int) 127 | 128 | vc = lmp.extract_atom("v", 3) 129 | velocity.append(np.array([[vc[i][0], vc[i][1], vc[i][2]] for i in range(na)], dtype=float)[id, :][indexing, :]) 130 | # velocity.append(np.array([vc[i] for i in range(na * 3)]).reshape((na, 3))[indexing, :]) 131 | 132 | if not velocity_only: 133 | xc = lmp.extract_atom("x", 3) 134 | positions.append(np.array([[xc[i][0], xc[i][1], xc[i][2]] for i in range(na)], dtype=float)[id, :][indexing, :]) 135 | # positions.append(np.array([xc[i] for i in range(na * 3)]).reshape((na, 3))[indexing, :]) 136 | 137 | positions = np.array(positions, dtype=complex) 138 | velocity = np.array(velocity, dtype=complex) 139 | energy = np.array(energy) 140 | 141 | if velocity_only: 142 | positions = None 143 | 144 | lmp.close() 145 | 146 | time = np.array([i * time_step * sampling_interval for i in range(n_loops)], dtype=float) 147 | 148 | 149 | return dyn.Dynamics(structure=structure, 150 | trajectory=positions, 151 | velocity=velocity, 152 | time=time, 153 | energy=energy, 154 | supercell=simulation_cell, 155 | memmap=memmap) 156 | 157 | 158 | if __name__ == '__main__': 159 | 160 | structure = None 161 | print (generate_lammps_trajectory(structure, 'in.demo')) -------------------------------------------------------------------------------- /dynaphopy/parameters.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | # This class contains all the default parameters for DynaPhoPy 4 | 5 | class Parameters: 6 | 7 | def __init__(self, 8 | # General 9 | silent=False, 10 | 11 | # Projections 12 | reduced_q_vector=(0, 0, 0), # default reduced wave vector 13 | 14 | # Maximum Entropy Method 15 | number_of_coefficients_mem=1000, 16 | mem_scan_range=np.array(np.linspace(40, 1000, 100), dtype=int), 17 | 18 | # Fourier transform Method 19 | correlation_function_step=10, 20 | integration_method=1, # 0: Trapezoid 1:Rectangles 21 | 22 | # Fast Fourier tranform Method 23 | zero_padding=0, 24 | 25 | # Power spectra 26 | # 0: Correlation functions parallel (OpenMP) [Recommended] 27 | # 1: Maximum Entropy Method parallel (OpenMP) [Recommended] 28 | # 2: FFT via numpy 29 | # 3: FFT via FFTW 30 | power_spectra_algorithm=1, 31 | spectrum_resolution=0.05, 32 | frequency_range=np.arange(0, 40.05, 0.05), 33 | # Fitting function 34 | # 0: Correlation functions parallel (OpenMP) [Recommended] 35 | # 1: Maximum Entropy Method parallel (OpenMP) [Recommended] 36 | # 2: FFT via numpy 37 | # 3: FFT via FFTW 38 | fitting_function=0, # Default fitting function 39 | 40 | # Phonon dispersion diagram 41 | use_NAC=False, 42 | band_ranges=None, 43 | band_resolution=100, 44 | number_of_bins_histogram=30, 45 | 46 | # Force constants 47 | symmetrize=False, 48 | use_symmetry=True, 49 | 50 | # Renormalized frequencies 51 | save_renormalized_frequencies=False, 52 | 53 | # Modes (eigenvectors) display 54 | modes_vectors_scale=10, 55 | 56 | #Density of states mesh (phonopy) 57 | mesh_phonopy=(40, 40, 40), 58 | 59 | #Use supercell 60 | use_MD_cell_commensurate=False, 61 | 62 | #(On development (temporal)) 63 | project_on_atom=-1 64 | ): 65 | 66 | self._silent = silent 67 | self._number_of_coefficients_mem = number_of_coefficients_mem 68 | self._mem_scan_range = mem_scan_range 69 | self._correlation_function_step = correlation_function_step 70 | self._integration_method = integration_method 71 | self._power_spectra_algorithm = power_spectra_algorithm 72 | self._fitting_function = fitting_function 73 | self._zero_padding = zero_padding 74 | self._frequency_range = frequency_range 75 | self._spectrum_resolution = spectrum_resolution 76 | self._reduced_q_vector = reduced_q_vector 77 | self._use_NAC = use_NAC 78 | self._band_ranges = band_ranges 79 | self._number_of_bins_histogram = number_of_bins_histogram 80 | self._band_resolution = band_resolution 81 | 82 | self._symmetrize = symmetrize 83 | self._use_symmetry = use_symmetry 84 | self._save_renormalized_frequencies = save_renormalized_frequencies 85 | 86 | self._modes_vectors_scale = modes_vectors_scale 87 | self._mesh_phonopy = mesh_phonopy 88 | self._use_MD_cell_commensurate = use_MD_cell_commensurate 89 | 90 | self._project_on_atom = project_on_atom 91 | 92 | def get_data_from_dict(self, data_dictionary): 93 | for data in self.__dict__: 94 | try: 95 | self.__dict__[data] = data_dictionary[data] 96 | except KeyError: 97 | continue 98 | 99 | 100 | #Properties 101 | @property 102 | def silent(self): 103 | return self._silent 104 | 105 | @silent.setter 106 | def silent(self, silent): 107 | self._silent = silent 108 | 109 | @property 110 | def reduced_q_vector(self): 111 | return self._reduced_q_vector 112 | 113 | @reduced_q_vector.setter 114 | def reduced_q_vector(self,reduced_q_vector): 115 | self._reduced_q_vector = reduced_q_vector 116 | 117 | @property 118 | def number_of_coefficients_mem(self): 119 | return self._number_of_coefficients_mem 120 | 121 | @number_of_coefficients_mem.setter 122 | def number_of_coefficients_mem(self,number_of_coefficients_mem): 123 | self._number_of_coefficients_mem = number_of_coefficients_mem 124 | 125 | @property 126 | def mem_scan_range(self): 127 | return self._mem_scan_range 128 | 129 | @mem_scan_range.setter 130 | def mem_scan_range(self,mem_scan_range): 131 | self._mem_scan_range = mem_scan_range 132 | 133 | @property 134 | def correlation_function_step(self): 135 | return self._correlation_function_step 136 | 137 | @correlation_function_step.setter 138 | def correlation_function_step(self,correlation_function_step): 139 | self._correlation_function_step = correlation_function_step 140 | 141 | @property 142 | def integration_method(self): 143 | return self._integration_method 144 | 145 | @integration_method.setter 146 | def integration_method(self,integration_method): 147 | self._integration_method = integration_method 148 | 149 | @property 150 | def frequency_range(self): 151 | return self._frequency_range 152 | 153 | @frequency_range.setter 154 | def frequency_range(self, frequency_range): 155 | self._frequency_range = frequency_range 156 | 157 | @property 158 | def spectrum_resolution(self): 159 | return self._spectrum_resolution 160 | 161 | @spectrum_resolution.setter 162 | def spectrum_resolution(self, spectrum_resolution): 163 | self._spectrum_resolution = spectrum_resolution 164 | 165 | @property 166 | def power_spectra_algorithm(self): 167 | return self._power_spectra_algorithm 168 | 169 | @power_spectra_algorithm.setter 170 | def power_spectra_algorithm(self,power_spectra_algorithm): 171 | self._power_spectra_algorithm = power_spectra_algorithm 172 | 173 | @property 174 | def use_NAC(self): 175 | return self._use_NAC 176 | 177 | @use_NAC.setter 178 | def use_NAC(self,use_NAC): 179 | self._use_NAC = use_NAC 180 | 181 | @property 182 | def band_ranges(self): 183 | return self._band_ranges 184 | 185 | @band_ranges.setter 186 | def band_ranges(self,band_ranges): 187 | self._band_ranges = band_ranges 188 | 189 | @property 190 | def number_of_bins_histogram(self): 191 | return self._number_of_bins_histogram 192 | 193 | @number_of_bins_histogram.setter 194 | def number_of_bins_histogram(self, number_of_bins_histogram): 195 | self._number_of_bins_histogram = number_of_bins_histogram 196 | 197 | @property 198 | def band_resolution(self): 199 | return self._band_resolution 200 | 201 | @band_resolution.setter 202 | def band_resolution(self, band_resolution): 203 | self._band_resolution = band_resolution 204 | 205 | @property 206 | def modes_vectors_scale(self): 207 | return self._modes_vectors_scale 208 | 209 | @modes_vectors_scale.setter 210 | def modes_vectors_scale(self, modes_vectors_scale): 211 | self._modes_vectors_scale = modes_vectors_scale 212 | 213 | @property 214 | def fitting_function(self): 215 | return self._fitting_function 216 | 217 | @fitting_function.setter 218 | def fitting_function(self, fitting_function): 219 | self._fitting_function = fitting_function 220 | 221 | @property 222 | def zero_padding(self): 223 | return self._zero_padding 224 | 225 | @zero_padding.setter 226 | def zero_padding(self, zero_padding): 227 | self._zero_padding = zero_padding 228 | 229 | @property 230 | def use_symmetry(self): 231 | return self._use_symmetry 232 | 233 | @use_symmetry.setter 234 | def use_symmetry(self, use_symmetry): 235 | self._use_symmetry = use_symmetry 236 | 237 | @property 238 | def symmetrize(self): 239 | return self._symmetrize 240 | 241 | @symmetrize.setter 242 | def symmetrize(self, symmetrize): 243 | self._symmetrize = symmetrize 244 | 245 | @property 246 | def save_renormalized_frequencies(self): 247 | return self._save_renormalized_frequencies 248 | 249 | @save_renormalized_frequencies.setter 250 | def save_renormalized_frequencies(self, save_renormalized_frequencies): 251 | self._save_renormalized_frequenciese = save_renormalized_frequencies 252 | 253 | @property 254 | def mesh_phonopy(self): 255 | return self._mesh_phonopy 256 | 257 | @mesh_phonopy.setter 258 | def mesh_phonopy(self, mesh_phonopy): 259 | self._mesh_phonopy = mesh_phonopy 260 | 261 | @property 262 | def use_MD_cell_commensurate(self): 263 | return self._use_MD_cell_commensurate 264 | 265 | @use_MD_cell_commensurate.setter 266 | def use_MD_cell_commensurate(self, use_MD_cell_commensurate): 267 | self._use_MD_cell_commensurate = use_MD_cell_commensurate 268 | 269 | # On development --------- 270 | @property 271 | def project_on_atom(self): 272 | return self._project_on_atom 273 | 274 | @project_on_atom.setter 275 | def project_on_atom(self, project_on_atom): 276 | self._project_on_atom = project_on_atom 277 | # ---------------------- 278 | -------------------------------------------------------------------------------- /dynaphopy/projection.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | 4 | def project_onto_wave_vector(trajectory, q_vector, project_on_atom=-1): 5 | 6 | number_of_primitive_atoms = trajectory.structure.get_number_of_primitive_atoms() 7 | velocity = trajectory.get_velocity_mass_average() 8 | # velocity = trajectory.velocity # (use the velocity without mass average, just for testing) 9 | 10 | number_of_atoms = velocity.shape[1] 11 | number_of_dimensions = velocity.shape[2] 12 | supercell = trajectory.get_supercell_matrix() 13 | 14 | coordinates = trajectory.structure.get_positions(supercell) 15 | atom_type = trajectory.structure.get_atom_type_index(supercell=supercell) 16 | 17 | velocity_projected = np.zeros((velocity.shape[0], number_of_primitive_atoms, number_of_dimensions), dtype=complex) 18 | 19 | if q_vector.shape[0] != coordinates.shape[1]: 20 | print("Warning!! Q-vector and coordinates dimension do not match") 21 | exit() 22 | 23 | #Projection into wave vector 24 | for i in range(number_of_atoms): 25 | # Projection on atom 26 | if project_on_atom > -1: 27 | if atom_type[i] != project_on_atom: 28 | continue 29 | 30 | for k in range(number_of_dimensions): 31 | velocity_projected[:, atom_type[i], k] += velocity[:,i,k]*np.exp(-1j*np.dot(q_vector, coordinates[i,:])) 32 | 33 | #Normalize velocities (method 1) 34 | # for i in range(velocity_projected.shape[1]): 35 | # velocity_projected[:,i,:] /= atom_type.count(i) 36 | 37 | #Normalize velocities (method 2) 38 | number_of_primitive_cells = number_of_atoms/number_of_primitive_atoms 39 | velocity_projected /= np.sqrt(number_of_primitive_cells) 40 | return velocity_projected 41 | 42 | 43 | def project_onto_phonon(vc, eigenvectors): 44 | 45 | number_of_cell_atoms = vc.shape[1] 46 | number_of_frequencies = eigenvectors.shape[0] 47 | 48 | #Projection in phonon coordinate 49 | velocity_projected=np.zeros((vc.shape[0], number_of_frequencies), dtype=complex) 50 | for k in range(number_of_frequencies): 51 | for i in range(number_of_cell_atoms): 52 | velocity_projected[:, k] += np.dot(vc[:, i, :], eigenvectors[k, i, :].conj()) 53 | 54 | return velocity_projected 55 | 56 | 57 | #Just for testing (slower implementation) [but equivalent] 58 | def project_onto_phonon2(vc,eigenvectors): 59 | 60 | number_of_cell_atoms = vc.shape[1] 61 | number_of_frequencies = eigenvectors.shape[0] 62 | 63 | #Projection in phonon coordinate 64 | velocity_projected=np.zeros((vc.shape[0],number_of_frequencies),dtype=complex) 65 | 66 | for i in range (vc.shape[0]): 67 | for k in range(number_of_frequencies): 68 | velocity_projected[i,k] = np.trace(np.dot(vc[i,:,:], eigenvectors[k,:,:].T.conj())) 69 | # velocity_projected[i,k] = np.sum(np.linalg.eigvals(np.dot(vc[i,:,:],eigenvectors[k,:,:].T.conj()))) 70 | return velocity_projected 71 | 72 | -------------------------------------------------------------------------------- /examples/GaN_lammps/GaN.tersoff: -------------------------------------------------------------------------------- 1 | # DATE: 2007-10-22 CONTRIBUTOR: Xiaowang Zhou, xzhou @ sandia.gov CITATION: Nord, Albe, Erhart and Nordlund, J. Phys Condens Matter, 15, 5649 (2003) 2 | # Tersoff parameters for various elements and mixtures 3 | # multiple entries can be added to this file, LAMMPS reads the ones it needs 4 | # these entries are in LAMMPS "metal" units: 5 | # A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms 6 | # other quantities are unitless 7 | 8 | # format of a single entry (one or more lines): 9 | # element 1, element 2, element 3, 10 | # m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A 11 | 12 | # The following GaN potential is from J. Nord, K. Albe, P. Erhart 13 | # and K. Nordlund, J. Phys.: Condens. Matter, 15, 5649(2003). 14 | # This file is from Xiaowang Zhou, xzhou @ sandia.gov 15 | 16 | Ga Ga Ga 1.0 0.007874 1.846 1.918000 0.75000 -0.301300 1.0 1.0 17 | 1.44970 410.132 2.87 0.15 1.60916 535.199 18 | N N N 1.0 0.766120 0.000 0.178493 0.20172 -0.045238 1.0 1.0 19 | 2.38426 423.769 2.20 0.20 3.55779 1044.77 20 | Ga Ga N 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 0.0 21 | 0.00000 0.00000 2.90 0.20 0.00000 0.00000 22 | Ga N N 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 1.0 23 | 2.63906 3864.27 2.90 0.20 2.93516 6136.44 24 | N Ga Ga 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 1.0 25 | 2.63906 3864.27 2.90 0.20 2.93516 6136.44 26 | N Ga N 1.0 0.766120 0.000 0.178493 0.20172 -0.045238 1.0 0.0 27 | 0.00000 0.00000 2.20 0.20 0.00000 0.00000 28 | N N Ga 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 0.0 29 | 0.00000 0.00000 2.90 0.20 0.00000 0.00000 30 | Ga N Ga 1.0 0.007874 1.846 1.918000 0.75000 -0.301300 1.0 0.0 31 | 0.00000 0.00000 2.87 0.15 0.00000 0.00000 32 | -------------------------------------------------------------------------------- /examples/GaN_lammps/POSCAR_unitcell: -------------------------------------------------------------------------------- 1 | Ga N 2 | 1.0 3 | 3.1900000572 0.000000000 0.0000000000 4 | -1.5950000286 2.762621076 0.0000000000 5 | 0.0000000000 0.000000000 5.1890001297 6 | Ga N 7 | 2 2 8 | Direct 9 | 0.66666669 0.33333334 0.000000000 10 | 0.33333331 0.66666663 0.500000000 11 | 0.66666669 0.33333334 0.375000000 12 | 0.33333331 0.66666663 0.875000000 13 | -------------------------------------------------------------------------------- /examples/GaN_lammps/README: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Example: GaN with LAMMPS at 2000 K # 3 | # -------------------------------------------------------------------------- # 4 | # Calculation of anharmonic properties of GaN using LAMMPS MD. # 5 | # The results include the phonon frequency shift and linewidth, renormalized # 6 | # force constants, phonon dispersion relations and thermal properties. # 7 | ############################################################################## 8 | 9 | 1. Generate the MD initial crystal structure for LAMMPS from a POSCAR type 10 | file (POSCAR_unitcell): 11 | 12 | $ dynaphopy input_gan -c_lammps data.gan --dim 3 3 3 13 | 14 | 2. Compute a MD simulation using LAMMPS (input provided: in.md). For this 15 | example the tersoff empirical potential file included in LAMMPS standard 16 | package is necessary (GaN.tersoff) 17 | 18 | $ lammps -in in.md_pos 19 | 20 | 3. Compute the phonon anharmonic properties using DynaPhoPy: 21 | 22 | a) Using command line interface 23 | $ dynaphopy input_gan gan_2000_test.lammpstrj -ts 0.001 -sdata -thm --normalize_dos -sfc renormalized_fc 24 | 25 | b) Using interactive menu interface (renormalized phonon dispersion and DOS) 26 | $ dynaphopy input_gan gan_2000_test.lammpstrj -ts 0.001 --normalize_dos -i 27 | 28 | Result files: 29 | - renormalized_fc : Renormalized force constants in PHONOPY format. 30 | - quasiparticles_data.yaml : Phonon frequencies and linewidths at each commensurate q-point 31 | in yaml format 32 | 33 | Note: This example also includes an alternative LAMMPS input that tells LAMMPS to store the MD 34 | atomic velocities instead of the positions (in.md_vel). Reading the velocities can save RAM 35 | memory in dynaphopy calculation and may increase the accuracy of the calculation. This option is 36 | preferable when working with long MD simulation. 37 | 38 | Note: Tersoff potentials files included in these examples are part of LAMMPS package. 39 | These files are included here just for convenience. 40 | -------------------------------------------------------------------------------- /examples/GaN_lammps/data.gan: -------------------------------------------------------------------------------- 1 | Generated using dynaphopy 2 | 3 | 108 atoms 4 | 5 | 2 atom types 6 | 7 | 8 | 0.0000000000 9.5700001716 xlo xhi 9 | 0.0000000000 8.2878632280 ylo yhi 10 | 0.0000000000 15.5670003891 zlo zhi 11 | -4.7850000858 0.0000000000 0.0000000000 xy xz yz 12 | 13 | Masses 14 | 15 | 1 69.7230000000 16 | 2 14.0067000000 17 | 18 | Atoms 19 | 20 | 1 1 1.5950000924 0.9208737104 0.0000000000 21 | 2 1 4.7850001496 0.9208737104 0.0000000000 22 | 3 1 7.9750002068 0.9208737104 0.0000000000 23 | 4 1 0.0000000638 3.6834947864 0.0000000000 24 | 5 1 3.1900001210 3.6834947864 0.0000000000 25 | 6 1 6.3800001782 3.6834947864 0.0000000000 26 | 7 1 -1.5949999648 6.4461158624 0.0000000000 27 | 8 1 1.5950000924 6.4461158624 0.0000000000 28 | 9 1 4.7850001496 6.4461158624 0.0000000000 29 | 10 1 1.5950000924 0.9208737104 5.1890001297 30 | 11 1 4.7850001496 0.9208737104 5.1890001297 31 | 12 1 7.9750002068 0.9208737104 5.1890001297 32 | 13 1 0.0000000638 3.6834947864 5.1890001297 33 | 14 1 3.1900001210 3.6834947864 5.1890001297 34 | 15 1 6.3800001782 3.6834947864 5.1890001297 35 | 16 1 -1.5949999648 6.4461158624 5.1890001297 36 | 17 1 1.5950000924 6.4461158624 5.1890001297 37 | 18 1 4.7850001496 6.4461158624 5.1890001297 38 | 19 1 1.5950000924 0.9208737104 10.3780002594 39 | 20 1 4.7850001496 0.9208737104 10.3780002594 40 | 21 1 7.9750002068 0.9208737104 10.3780002594 41 | 22 1 0.0000000638 3.6834947864 10.3780002594 42 | 23 1 3.1900001210 3.6834947864 10.3780002594 43 | 24 1 6.3800001782 3.6834947864 10.3780002594 44 | 25 1 -1.5949999648 6.4461158624 10.3780002594 45 | 26 1 1.5950000924 6.4461158624 10.3780002594 46 | 27 1 4.7850001496 6.4461158624 10.3780002594 47 | 28 1 -0.0000000160 1.8417472827 2.5945000649 48 | 29 1 3.1900000412 1.8417472827 2.5945000649 49 | 30 1 6.3800000984 1.8417472827 2.5945000649 50 | 31 1 -1.5950000446 4.6043683587 2.5945000649 51 | 32 1 1.5950000126 4.6043683587 2.5945000649 52 | 33 1 4.7850000698 4.6043683587 2.5945000649 53 | 34 1 -3.1900000732 7.3669894347 2.5945000649 54 | 35 1 -0.0000000160 7.3669894347 2.5945000649 55 | 36 1 3.1900000412 7.3669894347 2.5945000649 56 | 37 1 -0.0000000160 1.8417472827 7.7835001946 57 | 38 1 3.1900000412 1.8417472827 7.7835001946 58 | 39 1 6.3800000984 1.8417472827 7.7835001946 59 | 40 1 -1.5950000446 4.6043683587 7.7835001946 60 | 41 1 1.5950000126 4.6043683587 7.7835001946 61 | 42 1 4.7850000698 4.6043683587 7.7835001946 62 | 43 1 -3.1900000732 7.3669894347 7.7835001946 63 | 44 1 -0.0000000160 7.3669894347 7.7835001946 64 | 45 1 3.1900000412 7.3669894347 7.7835001946 65 | 46 1 -0.0000000160 1.8417472827 12.9725003242 66 | 47 1 3.1900000412 1.8417472827 12.9725003242 67 | 48 1 6.3800000984 1.8417472827 12.9725003242 68 | 49 1 -1.5950000446 4.6043683587 12.9725003242 69 | 50 1 1.5950000126 4.6043683587 12.9725003242 70 | 51 1 4.7850000698 4.6043683587 12.9725003242 71 | 52 1 -3.1900000732 7.3669894347 12.9725003242 72 | 53 1 -0.0000000160 7.3669894347 12.9725003242 73 | 54 1 3.1900000412 7.3669894347 12.9725003242 74 | 55 2 1.5950000924 0.9208737104 1.9458750486 75 | 56 2 4.7850001496 0.9208737104 1.9458750486 76 | 57 2 7.9750002068 0.9208737104 1.9458750486 77 | 58 2 0.0000000638 3.6834947864 1.9458750486 78 | 59 2 3.1900001210 3.6834947864 1.9458750486 79 | 60 2 6.3800001782 3.6834947864 1.9458750486 80 | 61 2 -1.5949999648 6.4461158624 1.9458750486 81 | 62 2 1.5950000924 6.4461158624 1.9458750486 82 | 63 2 4.7850001496 6.4461158624 1.9458750486 83 | 64 2 1.5950000924 0.9208737104 7.1348751783 84 | 65 2 4.7850001496 0.9208737104 7.1348751783 85 | 66 2 7.9750002068 0.9208737104 7.1348751783 86 | 67 2 0.0000000638 3.6834947864 7.1348751783 87 | 68 2 3.1900001210 3.6834947864 7.1348751783 88 | 69 2 6.3800001782 3.6834947864 7.1348751783 89 | 70 2 -1.5949999648 6.4461158624 7.1348751783 90 | 71 2 1.5950000924 6.4461158624 7.1348751783 91 | 72 2 4.7850001496 6.4461158624 7.1348751783 92 | 73 2 1.5950000924 0.9208737104 12.3238753080 93 | 74 2 4.7850001496 0.9208737104 12.3238753080 94 | 75 2 7.9750002068 0.9208737104 12.3238753080 95 | 76 2 0.0000000638 3.6834947864 12.3238753080 96 | 77 2 3.1900001210 3.6834947864 12.3238753080 97 | 78 2 6.3800001782 3.6834947864 12.3238753080 98 | 79 2 -1.5949999648 6.4461158624 12.3238753080 99 | 80 2 1.5950000924 6.4461158624 12.3238753080 100 | 81 2 4.7850001496 6.4461158624 12.3238753080 101 | 82 2 -0.0000000160 1.8417472827 4.5403751135 102 | 83 2 3.1900000412 1.8417472827 4.5403751135 103 | 84 2 6.3800000984 1.8417472827 4.5403751135 104 | 85 2 -1.5950000446 4.6043683587 4.5403751135 105 | 86 2 1.5950000126 4.6043683587 4.5403751135 106 | 87 2 4.7850000698 4.6043683587 4.5403751135 107 | 88 2 -3.1900000732 7.3669894347 4.5403751135 108 | 89 2 -0.0000000160 7.3669894347 4.5403751135 109 | 90 2 3.1900000412 7.3669894347 4.5403751135 110 | 91 2 -0.0000000160 1.8417472827 9.7293752432 111 | 92 2 3.1900000412 1.8417472827 9.7293752432 112 | 93 2 6.3800000984 1.8417472827 9.7293752432 113 | 94 2 -1.5950000446 4.6043683587 9.7293752432 114 | 95 2 1.5950000126 4.6043683587 9.7293752432 115 | 96 2 4.7850000698 4.6043683587 9.7293752432 116 | 97 2 -3.1900000732 7.3669894347 9.7293752432 117 | 98 2 -0.0000000160 7.3669894347 9.7293752432 118 | 99 2 3.1900000412 7.3669894347 9.7293752432 119 | 100 2 -0.0000000160 1.8417472827 14.9183753729 120 | 101 2 3.1900000412 1.8417472827 14.9183753729 121 | 102 2 6.3800000984 1.8417472827 14.9183753729 122 | 103 2 -1.5950000446 4.6043683587 14.9183753729 123 | 104 2 1.5950000126 4.6043683587 14.9183753729 124 | 105 2 4.7850000698 4.6043683587 14.9183753729 125 | 106 2 -3.1900000732 7.3669894347 14.9183753729 126 | 107 2 -0.0000000160 7.3669894347 14.9183753729 127 | 108 2 3.1900000412 7.3669894347 14.9183753729 128 | -------------------------------------------------------------------------------- /examples/GaN_lammps/dos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/examples/GaN_lammps/dos.png -------------------------------------------------------------------------------- /examples/GaN_lammps/in.md_pos: -------------------------------------------------------------------------------- 1 | # GaN molecular dynamics using Tersoff potential 2 | 3 | units metal 4 | 5 | boundary p p p 6 | 7 | box tilt large 8 | 9 | 10 | atom_style atomic 11 | 12 | read_data data.gan 13 | 14 | pair_style tersoff 15 | pair_coeff * * GaN.tersoff Ga N 16 | 17 | variable t equal 2000 18 | 19 | neighbor 0.3 bin 20 | 21 | timestep 0.001 22 | 23 | thermo_style custom step etotal temp vol press 24 | thermo 1000 25 | 26 | velocity all create $t 3627941 dist gaussian mom yes 27 | velocity all scale $t 28 | 29 | fix int all nvt temp $t $t 0.5 #between 0.2-2.0 30 | 31 | run 10000 32 | dump dynaphopy all custom 1 gan_${t}_test.lammpstrj x y z 33 | dump_modify dynaphopy sort id 34 | 35 | run 50000 36 | -------------------------------------------------------------------------------- /examples/GaN_lammps/in.md_vel: -------------------------------------------------------------------------------- 1 | # NaCl test problem for embedded atom method (EIM) potential 2 | 3 | units metal 4 | 5 | boundary p p p 6 | 7 | box tilt large 8 | 9 | 10 | atom_style atomic 11 | 12 | read_data data.gan 13 | 14 | pair_style tersoff 15 | pair_coeff * * GaN.tersoff Ga N 16 | 17 | variable t equal 2000 18 | 19 | neighbor 0.3 bin 20 | 21 | timestep 0.001 22 | 23 | thermo_style custom step etotal temp vol press 24 | thermo 1000 25 | 26 | velocity all create $t 3627941 dist gaussian mom yes 27 | velocity all scale $t 28 | 29 | fix int all nvt temp $t $t 0.5 #between 0.2-2.0 30 | 31 | run 10000 32 | dump dynaphopy all custom 1 gan_${t}_test.lammpstrj vx vy vz 33 | dump_modify dynaphopy sort id 34 | 35 | run 50000 36 | -------------------------------------------------------------------------------- /examples/GaN_lammps/input_gan: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | POSCAR_unitcell 3 | 4 | FORCE CONSTANTS 5 | FORCE_CONSTANTS_3x3x3 6 | 7 | PRIMITIVE MATRIX 8 | 1.0 0.0 0.0 9 | 0.0 1.0 0.0 10 | 0.0 0.0 1.0 11 | 12 | SUPERCELL MATRIX 13 | 3 0 0 14 | 0 3 0 15 | 0 0 3 16 | 17 | MESH PHONOPY 18 | 10 10 10 19 | 20 | BANDS 21 | 0.0, 0.0, 0.0 0.333, 0.333, 0.0 22 | 0.333, 0.333, 0.0 0.5, 0.0, 0.0 23 | 0.5, 0.0, 0.0 0.0, 0.0, 0.0 24 | 0.0, 0.0, 0.0 0.0, 0.0, 0.5 25 | 26 | -------------------------------------------------------------------------------- /examples/GaN_lammps/log.lammps: -------------------------------------------------------------------------------- 1 | LAMMPS (11 Nov 2013) 2 | WARNING: OMP_NUM_THREADS environment is not set. (../comm.cpp:100) 3 | using 1 OpenMP thread(s) per MPI task 4 | # NaCl test problem for embedded atom method (EIM) potential 5 | 6 | units metal 7 | 8 | boundary p p p 9 | 10 | box tilt large 11 | 12 | 13 | atom_style atomic 14 | 15 | read_data data.gan 16 | triclinic box = (0 0 0) to (9.57 8.28786 15.567) with tilt (-4.785 0 0) 17 | 1 by 1 by 1 MPI processor grid 18 | 108 atoms 19 | 20 | pair_style tersoff 21 | pair_coeff * * GaN.tersoff Ga N 22 | 23 | variable t equal 2000 24 | 25 | neighbor 0.3 bin 26 | 27 | timestep 0.001 28 | 29 | thermo_style custom step etotal temp vol press 30 | thermo 1000 31 | 32 | velocity all create $t 3627941 dist gaussian mom yes 33 | velocity all create 2000 3627941 dist gaussian mom yes 34 | velocity all scale $t 35 | velocity all scale 2000 36 | 37 | fix int all nvt temp $t $t 0.5 #between 0.2-2.0 38 | fix int all nvt temp 2000 $t 0.5 39 | fix int all nvt temp 2000 2000 0.5 40 | 41 | run 10000 42 | Memory usage per processor = 1.56623 Mbytes 43 | Step TotEng Temp Volume Press 44 | 0 -461.30525 2000 1234.6943 14400.541 45 | 1000 -450.81683 1329.837 1234.6943 2452.045 46 | 2000 -434.74732 1963.1645 1234.6943 30467.567 47 | 3000 -427.27189 2170.7495 1234.6943 41558.233 48 | 4000 -435.47021 1721.662 1234.6943 28304.557 49 | 5000 -434.13606 1839.1505 1234.6943 22159.544 50 | 6000 -428.49992 2077.2721 1234.6943 35120.292 51 | 7000 -435.26768 1951.1346 1234.6943 22492.689 52 | 8000 -433.07582 1931.6571 1234.6943 36102.945 53 | 9000 -422.4141 2262.002 1234.6943 69587.379 54 | 10000 -431.44962 2115.8553 1234.6943 21111.891 55 | Loop time of 4.99223 on 1 procs (1 MPI x 1 OpenMP) for 10000 steps with 108 atoms 56 | 57 | Pair time (%) = 4.84373 (97.0254) 58 | Neigh time (%) = 0.10759 (2.15516) 59 | Comm time (%) = 0.0182981 (0.366533) 60 | Outpt time (%) = 0.000142097 (0.00284637) 61 | Other time (%) = 0.0224681 (0.450061) 62 | 63 | Nlocal: 108 ave 108 max 108 min 64 | Histogram: 1 0 0 0 0 0 0 0 0 0 65 | Nghost: 353 ave 353 max 353 min 66 | Histogram: 1 0 0 0 0 0 0 0 0 0 67 | Neighs: 0 ave 0 max 0 min 68 | Histogram: 1 0 0 0 0 0 0 0 0 0 69 | FullNghs: 1716 ave 1716 max 1716 min 70 | Histogram: 1 0 0 0 0 0 0 0 0 0 71 | 72 | Total # of neighbors = 1716 73 | Ave neighs/atom = 15.8889 74 | Neighbor list builds = 1000 75 | Dangerous builds = 1000 76 | dump dynaphopy all custom 1 gan_${t}_vel.lammpstrj vx vy vz 77 | dump dynaphopy all custom 1 gan_2000_vel.lammpstrj vx vy vz 78 | dump_modify dynaphopy sort id 79 | 80 | run 50000 81 | Memory usage per processor = 1.72665 Mbytes 82 | Step TotEng Temp Volume Press 83 | 10000 -431.44962 2115.8553 1234.6943 21111.891 84 | 11000 -435.75599 1863.8344 1234.6943 37244.074 85 | 12000 -429.50528 2228.0867 1234.6943 40796.398 86 | 13000 -434.72544 1813.9526 1234.6943 26950.51 87 | 14000 -435.36682 1834.8049 1234.6943 24885.963 88 | 15000 -430.84641 2101.4901 1234.6943 62263.742 89 | 16000 -433.38424 2105.4062 1234.6943 34164.214 90 | 17000 -439.80946 1746.0289 1234.6943 22381.763 91 | 18000 -432.00765 2112.9803 1234.6943 37976.49 92 | 19000 -430.7678 2108.3618 1234.6943 25088.621 93 | 20000 -437.62829 1690.1722 1234.6943 20295.178 94 | 21000 -431.88477 2178.6593 1234.6943 13021.978 95 | 22000 -432.36154 2035.5694 1234.6943 26095.057 96 | 23000 -436.52731 1873.3499 1234.6943 36169.243 97 | 24000 -433.92615 1905.5961 1234.6943 37844.639 98 | 25000 -430.16816 2115.6303 1234.6943 50601.199 99 | 26000 -436.71119 1963.069 1234.6943 54895.473 100 | 27000 -433.02155 1925.6784 1234.6943 54558.587 101 | 28000 -429.6066 2273.5039 1234.6943 22669.701 102 | 29000 -435.98314 2139.6157 1234.6943 16128.947 103 | 30000 -428.18875 2045.1935 1234.6943 61352.471 104 | 31000 -430.76836 2124.7648 1234.6943 45990.678 105 | 32000 -434.6573 1920.4088 1234.6943 27374.562 106 | 33000 -426.13457 2238.3991 1234.6943 54461.115 107 | 34000 -430.89902 2043.2103 1234.6943 40390.212 108 | 35000 -433.70158 1870.6629 1234.6943 31090.07 109 | 36000 -428.74618 2162.7468 1234.6943 29483.296 110 | 37000 -430.27057 2164.518 1234.6943 52073.165 111 | 38000 -433.86091 1984.1991 1234.6943 15942.694 112 | 39000 -428.79799 2074.795 1234.6943 22889.629 113 | 40000 -426.98911 2107.0135 1234.6943 49451.819 114 | 41000 -434.11893 1925.965 1234.6943 14575.304 115 | 42000 -431.1455 2073.71 1234.6943 29495.202 116 | 43000 -429.06606 2076.5843 1234.6943 56470.784 117 | 44000 -435.26774 1809.1764 1234.6943 19583.195 118 | 45000 -429.34707 2010.8281 1234.6943 27459.427 119 | 46000 -436.05632 1789.1002 1234.6943 40106.572 120 | 47000 -434.02866 2050.5843 1234.6943 9535.9824 121 | 48000 -430.17628 2228.7978 1234.6943 38393.36 122 | 49000 -438.27747 1827.6831 1234.6943 24054.287 123 | 50000 -433.946 1896.6182 1234.6943 37502.257 124 | 51000 -431.21251 2038.5059 1234.6943 36860.865 125 | 52000 -437.61169 1702.2971 1234.6943 24749.074 126 | 53000 -433.94503 1908.6372 1234.6943 26518.83 127 | 54000 -431.53181 2096.2715 1234.6943 22007.784 128 | 55000 -435.20747 1926.4077 1234.6943 56477.028 129 | 56000 -436.48191 1611.2032 1234.6943 17193.314 130 | 57000 -431.06068 2198.2179 1234.6943 45533.404 131 | 58000 -434.9283 1730.1782 1234.6943 38706.246 132 | 59000 -437.07986 1766.4199 1234.6943 28807.341 133 | 60000 -429.73461 2228.2316 1234.6943 40591.43 134 | Loop time of 29.0344 on 1 procs (1 MPI x 1 OpenMP) for 50000 steps with 108 atoms 135 | 136 | Pair time (%) = 24.5423 (84.5284) 137 | Neigh time (%) = 0.536974 (1.84944) 138 | Comm time (%) = 0.0940127 (0.323798) 139 | Outpt time (%) = 3.73478 (12.8633) 140 | Other time (%) = 0.126319 (0.435067) 141 | 142 | Nlocal: 108 ave 108 max 108 min 143 | Histogram: 1 0 0 0 0 0 0 0 0 0 144 | Nghost: 339 ave 339 max 339 min 145 | Histogram: 1 0 0 0 0 0 0 0 0 0 146 | Neighs: 0 ave 0 max 0 min 147 | Histogram: 1 0 0 0 0 0 0 0 0 0 148 | FullNghs: 1678 ave 1678 max 1678 min 149 | Histogram: 1 0 0 0 0 0 0 0 0 0 150 | 151 | Total # of neighbors = 1678 152 | Ave neighs/atom = 15.537 153 | Neighbor list builds = 5000 154 | Dangerous builds = 5000 155 | -------------------------------------------------------------------------------- /examples/GaN_lammps/phonon_dispersion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/examples/GaN_lammps/phonon_dispersion.png -------------------------------------------------------------------------------- /examples/GaN_lammps/phonon_dispersion_and_linewidths.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/examples/GaN_lammps/phonon_dispersion_and_linewidths.png -------------------------------------------------------------------------------- /examples/Si_VASP/FORCE_SETS_2x2x2: -------------------------------------------------------------------------------- 1 | 64 2 | 1 3 | 4 | 1 5 | 0.0100000000000000 0.0000000000000000 0.0000000000000000 6 | -0.1296921300 0.0000006700 -0.0000042800 7 | 0.0001945900 0.0000016500 -0.0000001300 8 | 0.0004351600 -0.0000044600 0.0000018500 9 | -0.0000447700 0.0000015000 0.0000004100 10 | 0.0004374800 0.0000017700 -0.0000021000 11 | -0.0000466300 0.0000003700 0.0000018300 12 | -0.0038517300 -0.0000049800 0.0000042800 13 | 0.0002095300 0.0000025800 0.0000013500 14 | 0.0020320200 -0.0002357500 -0.0002374700 15 | -0.0001890300 -0.0002559100 -0.0002542600 16 | -0.0004930300 -0.0003976300 -0.0003234100 17 | 0.0002193600 -0.0002394200 -0.0002354000 18 | -0.0004907500 -0.0003183000 -0.0003995300 19 | 0.0002202800 -0.0002317500 -0.0002385100 20 | 0.0315839800 -0.0216510700 -0.0216473200 21 | -0.0001217700 -0.0003257300 -0.0003279400 22 | -0.0042188600 -0.0008799300 -0.0008827300 23 | -0.0000049200 -0.0000803700 -0.0000766800 24 | -0.0042260900 -0.0008936500 0.0008976800 25 | -0.0000046200 -0.0000788100 0.0000844900 26 | -0.0042312700 0.0008974500 -0.0008980100 27 | -0.0000087000 0.0000804000 -0.0000796300 28 | -0.0042192000 0.0008828100 0.0008805500 29 | -0.0000072700 0.0000778400 0.0000785700 30 | 0.0315862400 0.0216506500 0.0216502400 31 | -0.0001236800 0.0003283700 0.0003245300 32 | -0.0004906600 0.0003169700 0.0003949300 33 | 0.0002203600 0.0002282800 0.0002390500 34 | -0.0004899300 0.0004011500 0.0003227600 35 | 0.0002202900 0.0002377100 0.0002337700 36 | 0.0020290000 0.0002373000 0.0002349300 37 | -0.0001913100 0.0002524000 0.0002570000 38 | 0.0018468200 0.0008915600 0.0018167100 39 | 0.0018634000 0.0008973900 -0.0018245000 40 | 0.0003463500 0.0000741900 -0.0006120900 41 | 0.0003504700 0.0000770900 0.0006110100 42 | 0.0018458600 -0.0008848700 -0.0018159500 43 | 0.0018631000 -0.0008992000 0.0018297400 44 | 0.0003503400 -0.0000821700 0.0006174000 45 | 0.0003512900 -0.0000772400 -0.0006199000 46 | 0.0002141900 0.0002288400 -0.0002321500 47 | -0.0004941400 0.0003311000 -0.0003957900 48 | -0.0001231000 0.0003249200 -0.0003281000 49 | 0.0318881300 0.0222394000 -0.0222400500 50 | -0.0001908800 0.0002583700 -0.0002548000 51 | 0.0020397200 0.0002388800 -0.0002338900 52 | 0.0002217500 0.0002303500 -0.0002294300 53 | -0.0004938700 0.0003921600 -0.0003228300 54 | 0.0018484000 0.0018163000 0.0008856100 55 | 0.0018662200 -0.0018273500 0.0008961200 56 | 0.0018474400 -0.0018179900 -0.0008892700 57 | 0.0018646800 0.0018275600 -0.0009001500 58 | 0.0003494500 -0.0006161800 0.0000767600 59 | 0.0003496400 0.0006135600 0.0000783200 60 | 0.0003487600 0.0006128700 -0.0000775700 61 | 0.0003473200 -0.0006130900 -0.0000754300 62 | 0.0002149600 -0.0002306700 0.0002280900 63 | -0.0004938400 -0.0003918600 0.0003268300 64 | -0.0001865000 -0.0002581600 0.0002568300 65 | 0.0020379900 -0.0002407800 0.0002354300 66 | -0.0001235300 -0.0003231300 0.0003269100 67 | 0.0318878000 -0.0222367300 0.0222394900 68 | 0.0002146800 -0.0002276300 0.0002313500 69 | -0.0004948200 -0.0003295700 0.0003944500 70 | -------------------------------------------------------------------------------- /examples/Si_VASP/INCAR: -------------------------------------------------------------------------------- 1 | PREC = Normal 2 | ENCUT = 180 3 | NWRITE = 2 4 | IBRION = 0 5 | ISYM = 0 6 | SMASS = 0 7 | POTIM = 2.0 8 | MDALGO = 2 9 | TEBEG = 800 10 | NSW = 100000 11 | NELMIN = 4 12 | NELM = 100 13 | ISMEAR = 0 14 | SIGMA = 0.01 15 | EDIFF = 1e-5 16 | MAXMIX = 40 17 | IALGO = 38 18 | LREAL = AUTO 19 | GGA = PS 20 | LWAVE = .FALSE. 21 | LCHARG = .FALSE. 22 | NCORE = 2 23 | -------------------------------------------------------------------------------- /examples/Si_VASP/KPOINTS: -------------------------------------------------------------------------------- 1 | Automatic mesh 2 | 0 3 | Monkhorst-pack 4 | 2 2 2 5 | 0. 0. 0. 6 | -------------------------------------------------------------------------------- /examples/Si_VASP/POSCAR: -------------------------------------------------------------------------------- 1 | Generated using dynaphopy 2 | 1.0 3 | 10.9000000000 0.0000000000 0.0000000000 4 | 0.0000000000 10.9000000000 0.0000000000 5 | 0.0000000000 0.0000000000 10.9000000000 6 | Si 7 | 64 8 | Direct 9 | 0.375000000000000 0.375000000000000 0.375000000000000 10 | 0.875000000000000 0.375000000000000 0.375000000000000 11 | 0.375000000000000 0.875000000000000 0.375000000000000 12 | 0.875000000000000 0.875000000000000 0.375000000000000 13 | 0.375000000000000 0.375000000000000 0.875000000000000 14 | 0.875000000000000 0.375000000000000 0.875000000000000 15 | 0.375000000000000 0.875000000000000 0.875000000000000 16 | 0.875000000000000 0.875000000000000 0.875000000000000 17 | 0.250000000000000 0.000000000000000 0.000000000000000 18 | 0.750000000000000 0.000000000000000 0.000000000000000 19 | 0.250000000000000 0.500000000000000 0.000000000000000 20 | 0.750000000000000 0.500000000000000 0.000000000000000 21 | 0.250000000000000 0.000000000000000 0.500000000000000 22 | 0.750000000000000 0.000000000000000 0.500000000000000 23 | 0.250000000000000 0.500000000000000 0.500000000000000 24 | 0.750000000000000 0.500000000000000 0.500000000000000 25 | 0.375000000000000 0.125000000000000 0.125000000000000 26 | 0.875000000000000 0.125000000000000 0.125000000000000 27 | 0.375000000000000 0.625000000000000 0.125000000000000 28 | 0.875000000000000 0.625000000000000 0.125000000000000 29 | 0.375000000000000 0.125000000000000 0.625000000000000 30 | 0.875000000000000 0.125000000000000 0.625000000000000 31 | 0.375000000000000 0.625000000000000 0.625000000000000 32 | 0.875000000000000 0.625000000000000 0.625000000000000 33 | 0.250000000000000 0.250000000000000 0.250000000000000 34 | 0.750000000000000 0.250000000000000 0.250000000000000 35 | 0.250000000000000 0.750000000000000 0.250000000000000 36 | 0.750000000000000 0.750000000000000 0.250000000000000 37 | 0.250000000000000 0.250000000000000 0.750000000000000 38 | 0.750000000000000 0.250000000000000 0.750000000000000 39 | 0.250000000000000 0.750000000000000 0.750000000000000 40 | 0.750000000000000 0.750000000000000 0.750000000000000 41 | 0.125000000000000 0.375000000000000 0.125000000000000 42 | 0.625000000000000 0.375000000000000 0.125000000000000 43 | 0.125000000000000 0.875000000000000 0.125000000000000 44 | 0.625000000000000 0.875000000000000 0.125000000000000 45 | 0.125000000000000 0.375000000000000 0.625000000000000 46 | 0.625000000000000 0.375000000000000 0.625000000000000 47 | 0.125000000000000 0.875000000000000 0.625000000000000 48 | 0.625000000000000 0.875000000000000 0.625000000000000 49 | 0.000000000000000 0.000000000000000 0.250000000000000 50 | 0.500000000000000 0.000000000000000 0.250000000000000 51 | 0.000000000000000 0.500000000000000 0.250000000000000 52 | 0.500000000000000 0.500000000000000 0.250000000000000 53 | 0.000000000000000 0.000000000000000 0.750000000000000 54 | 0.500000000000000 0.000000000000000 0.750000000000000 55 | 0.000000000000000 0.500000000000000 0.750000000000000 56 | 0.500000000000000 0.500000000000000 0.750000000000000 57 | 0.125000000000000 0.125000000000000 0.375000000000000 58 | 0.625000000000000 0.125000000000000 0.375000000000000 59 | 0.125000000000000 0.625000000000000 0.375000000000000 60 | 0.625000000000000 0.625000000000000 0.375000000000000 61 | 0.125000000000000 0.125000000000000 0.875000000000000 62 | 0.625000000000000 0.125000000000000 0.875000000000000 63 | 0.125000000000000 0.625000000000000 0.875000000000000 64 | 0.625000000000000 0.625000000000000 0.875000000000000 65 | 0.000000000000000 0.250000000000000 0.000000000000000 66 | 0.500000000000000 0.250000000000000 0.000000000000000 67 | 0.000000000000000 0.750000000000000 0.000000000000000 68 | 0.500000000000000 0.750000000000000 0.000000000000000 69 | 0.000000000000000 0.250000000000000 0.500000000000000 70 | 0.500000000000000 0.250000000000000 0.500000000000000 71 | 0.000000000000000 0.750000000000000 0.500000000000000 72 | 0.500000000000000 0.750000000000000 0.500000000000000 73 | -------------------------------------------------------------------------------- /examples/Si_VASP/POSCAR_unitcell: -------------------------------------------------------------------------------- 1 | Fd-3m (227) / F 4d 2 3 -1d (525) 2 | 1.0 3 | 5.4500000000000000 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 5.4500000000000000 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 5.4500000000000000 6 | Si 7 | 8 8 | Direct 9 | 0.7500000000000000 0.7500000000000000 0.7500000000000000 10 | 0.5000000000000000 0.0000000000000000 0.0000000000000000 11 | 0.7500000000000000 0.2500000000000000 0.2500000000000000 12 | 0.5000000000000000 0.5000000000000000 0.5000000000000000 13 | 0.2500000000000000 0.7500000000000000 0.2500000000000000 14 | 0.0000000000000000 0.0000000000000000 0.5000000000000000 15 | 0.2500000000000000 0.2500000000000000 0.7500000000000000 16 | 0.0000000000000000 0.5000000000000000 0.0000000000000000 17 | -------------------------------------------------------------------------------- /examples/Si_VASP/README: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Example: Si with VASP at 800 K # 3 | # -------------------------------------------------------------------------- # 4 | # Calculation of anharmonic properties of Si using VASP MD. # 5 | # The results include the phonon frequency shift and linewidth, renormalized # 6 | # force constants, phonon dispersion relations and thermal properties. # 7 | ############################################################################## 8 | 9 | 1. Generate the MD initial crystal structure for VASP from a POSCAR type 10 | file (POSCAR_unitcell): 11 | 12 | $ dynaphopy input_si -c_poscar POSCAR --dim 2 2 2 13 | 14 | 2. Compute a MD simulation using VASP. For this example DFT method using the 15 | PBESol functional was used. (This calculations requires the PAW pseudopotentials included 16 | in the standard distribution of VASP): 17 | 18 | $ vasp 19 | 20 | 3. Compute the phonon anharmonic properties using DynaPhoPy: 21 | 22 | a) Using command line interface 23 | $ dynaphopy input_si XDATCAR -ts 0.002 -n 8000 -sdata -thm --normalize_dos --silent -sfc renormalized_fc 24 | 25 | b) Using interactive menu interface (renormalized phonon dispersion and DOS) 26 | $ dynaphopy input_si XDATCAR -ts 0.002 --normalize_dos -i 27 | 28 | Result files: 29 | - renormalized_fc : Renormalized force constants in PHONOPY format. 30 | - quasiparticles_data.yaml : Phonon frequencies and linewidths at each commensurate q-point 31 | in yaml format 32 | -------------------------------------------------------------------------------- /examples/Si_VASP/dos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/examples/Si_VASP/dos.png -------------------------------------------------------------------------------- /examples/Si_VASP/input_si: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | POSCAR_unitcell 3 | 4 | FORCE SETS 5 | FORCE_SETS_2x2x2 6 | 7 | 8 | PRIMITIVE MATRIX 9 | 0.0 0.5 0.5 10 | 0.5 0.0 0.5 11 | 0.5 0.5 0.0 12 | 13 | SUPERCELL MATRIX 14 | 2 0 0 15 | 0 2 0 16 | 0 0 2 17 | 18 | MESH PHONOPY 19 | 40 40 40 20 | 21 | BANDS 22 | 0.0, 0.0, 0.0 0.5, 0.0, 0.5 23 | 0.5, 0.0, 0.5 0.625 0.25 0.625 24 | 0.375, 0.375, 0.75 0.0, 0.0, 0.0 25 | 0.0, 0.0, 0.0 0.5, 0.5, 0.5 26 | 27 | -------------------------------------------------------------------------------- /examples/Si_VASP/phonon_dispersion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abelcarreras/DynaPhoPy/c117802509e9ac0d46d610395f1399675013ee46/examples/Si_VASP/phonon_dispersion.png -------------------------------------------------------------------------------- /examples/api_scripts/script_silicon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import numpy as np 4 | import phonopy.file_IO as file_IO 5 | import dynaphopy.interface.iofile as io 6 | import dynaphopy.interface.iofile.trajectory_parsers as parsers 7 | import dynaphopy 8 | 9 | from dynaphopy.interface.phonopy_link import get_force_sets_from_file, get_force_constants_from_file 10 | 11 | ################################## STRUCTURE FILES ####################################### 12 | # 1. Set the directory in where the FORCE_SETS and structure POSCAR are placed 13 | 14 | directory ='/home/user/VASP/Si/2x2x2/' 15 | structure = io.read_from_file_structure_poscar(directory + 'POSCAR') 16 | 17 | 18 | ############################### PHONOPY CELL INFORMATION #################################### 19 | # 2. Set primitive matrix that defines the primitive cell respect the unit cell 20 | structure.set_primitive_matrix([[0.0, 0.5, 0.5], 21 | [0.5, 0.0, 0.5], 22 | [0.5, 0.5, 0.0]]) 23 | 24 | 25 | # 3. Set the hamonic phonon data (input for phonopy) 26 | # fs_supercell: supercell matrix used in PHONOPY to obtain the force_sets 27 | # FORCE_SETS : force set file obtained from PHONOPY calculation that contains the forces 28 | structure.set_force_set(get_force_sets_from_file(file_name=directory + 'FORCE_SETS', 29 | fs_supercell=[[2, 0, 0], 30 | [0, 2, 0], 31 | [0, 0, 2]])) 32 | 33 | # Alternatively get_force_constants_from_file function can be used to obtain the harmonic information. 34 | # Check unittest files (unittest folder) 35 | 36 | ############################### READING TRAJECTORY FILES ##################################### 37 | # 4. Set the location of OUTCAR/LAMMPS file containing the Molecular Dynamics trajectory 38 | 39 | # trajectory = parsers.read_vasp_trajectory('/home/user/VASP/Si/2x2x2//OUTCAR', structure, initial_cut=10000, end_cut=60000) 40 | # or 41 | trajectory = parsers.read_VASP_XDATCAR('/home/user/VASP/Si/2x2x2/XDATCAR', structure, initial_cut=10000, end_cut=40000, time_step=0.0005) 42 | # or 43 | #trajectory = parsers.read_lammps_trajectory('/home/user/LAMMPS/Si/Si_400.lammpstrj', structure, initial_cut=10000, end_cut=12000, time_step=0.001) 44 | 45 | quasiparticle = dynaphopy.Quasiparticle(trajectory) 46 | 47 | 48 | ############################# DEFINE CALCULATION PARAMETERS ################################## 49 | # 5. All this options are totally optional and independent, just comment or uncomment the desired ones 50 | # Other option not yet shown in this example script may be available (take a look at dynaphopt/__init__.py) 51 | 52 | # 5a. Set the power spectrum algorithm 53 | # 0: Direct Fourier transform (Not recommended) 54 | # 1: Maximum entropy method (MEM) 55 | # 2; numpy FFT 56 | # 3: FFTW (Needs FFTW installed in the system) 57 | # 4: CUDA (Needs cuda_functions installed in the system) 58 | quasiparticle.select_power_spectra_algorithm(1) # MEM 59 | quasiparticle.set_number_of_mem_coefficients(1000) # Only is used if MEM is selected 60 | 61 | # 5b. Set wave vector into which is going to be projected the velocity (default: gamma point) 62 | quasiparticle.set_reduced_q_vector([0.5, 0.0, 0.0]) # X Point 63 | 64 | # 5c. Define range of frequency to analyze (example: 0 - 20 THz) 65 | quasiparticle.set_frequency_limits([0, 20]) 66 | 67 | # 5c. Define power spectrum resolution (example: 0.05 THz) 68 | quasiparticle.set_spectra_resolution(0.05) 69 | 70 | # 5d. Define phonon dispersion relations path 71 | quasiparticle.set_band_ranges([[[0.0, 0.0, 0.0], [0.5, 0.0, 0.5]], 72 | [[0.5, 0.0, 0.5], [0.625, 0.25, 0.625]], 73 | [[0.375, 0.375, 0.75], [0.0, 0.0, 0.0]], 74 | [[0.0, 0.0, 0.0], [0.5, 0.5, 0.5]]]) 75 | 76 | 77 | ############################## DEFINE CALCULATION REQUESTS ##################################### 78 | # 6. All this options are totally optional and independent, just comment or uncomment the desired ones 79 | # Other option not yet shown in this example script may be available (take a look at dynaphopt/__init__.py) 80 | 81 | # 6a. Request Boltzmann distribution trajectory analysis 82 | quasiparticle.show_boltzmann_distribution() 83 | 84 | # 6b. Request plot full power spectrum 85 | quasiparticle.plot_power_spectrum_full() 86 | 87 | # 6c. Request plot wave-vector-projected power spectrum 88 | quasiparticle.plot_power_spectrum_wave_vector() 89 | 90 | # 6d. Request plot phonon-mode-projected power spectra 91 | quasiparticle.plot_power_spectrum_phonon() 92 | 93 | # 6e. Request save full power spectrum into file 94 | quasiparticle.write_power_spectrum_full('/home/user/full_ps.out') 95 | 96 | # 6f. Request save wave-vector-projected power spectrum into file 97 | quasiparticle.write_power_spectrum_wave_vector('/home/user/correlation_wave_vector.out') 98 | 99 | # 6g. Request save phonon-mode-projected power spectra into file 100 | quasiparticle.write_power_spectrum_phonon('/home/user/mem_phonon.out') 101 | 102 | # 6h. Request peak analysis 103 | quasiparticle.phonon_individual_analysis() 104 | 105 | # 6i. Request calculation of renormalized force constants and write them into a file 106 | quasiparticle.write_renormalized_constants(filename="FORCE_CONSTANTS") 107 | 108 | # 6j. Request calculation of thermal properties 109 | quasiparticle.display_thermal_properties() 110 | 111 | # 6k. Request to display the renormalized phonon dispersion relations 112 | quasiparticle.plot_renormalized_phonon_dispersion_bands() 113 | quasiparticle.plot_renormalized_phonon_dispersion_bands() 114 | 115 | # 6l. Request the calculation of the anisotropic displacement parameters 116 | quasiparticle.get_anisotropic_displacement_parameters() -------------------------------------------------------------------------------- /examples/api_scripts/silicon_pure.py: -------------------------------------------------------------------------------- 1 | # 2 | # This is an example of how to call dynaphopy from python API using 3 | # python objects (trajectory is still read from file) 4 | # 5 | from dynaphopy import Quasiparticle 6 | from dynaphopy.atoms import Structure 7 | from phonopy.file_IO import parse_FORCE_CONSTANTS, write_FORCE_CONSTANTS 8 | from dynaphopy.interface.phonopy_link import ForceConstants 9 | import dynaphopy.interface.iofile.trajectory_parsers as parsers 10 | 11 | # reading force constants in phonopy format 12 | force_constants_phonopy = parse_FORCE_CONSTANTS(filename='FORCE_CONSTANTS') # FORCE_CONSTANTS file in phonopy format 13 | force_constants = ForceConstants(force_constants=force_constants_phonopy, 14 | supercell=[[2, 0, 0], # force constants supercell 15 | [0, 2, 0], 16 | [0, 0, 2]]) 17 | 18 | # prepare unit cell structure 19 | structure = Structure(scaled_positions=[[0.7500000000000000, 0.7500000000000000, 0.7500000000000000], 20 | [0.5000000000000000, 0.0000000000000000, 0.0000000000000000], 21 | [0.7500000000000000, 0.2500000000000000, 0.2500000000000000], 22 | [0.5000000000000000, 0.5000000000000000, 0.5000000000000000], 23 | [0.2500000000000000, 0.7500000000000000, 0.2500000000000000], 24 | [0.0000000000000000, 0.0000000000000000, 0.5000000000000000], 25 | [0.2500000000000000, 0.2500000000000000, 0.7500000000000000], 26 | [0.0000000000000000, 0.5000000000000000, 0.0000000000000000]], 27 | atomic_elements=['Si'] * 8, 28 | cell=[[5.45, 0.00, 0.00], 29 | [0.00, 5.45, 0.00], 30 | [0.00, 0.00, 5.45]], 31 | primitive_matrix=[[0.0, 0.5, 0.5], 32 | [0.5, 0.0, 0.5], 33 | [0.5, 0.5, 0.0]], 34 | force_constants=force_constants) 35 | 36 | # get trajectory from XDATCAR 37 | trajectory = parsers.read_VASP_XDATCAR('XDATCAR', # trajectory filename 38 | structure, 39 | initial_cut=10000, 40 | end_cut=40000, 41 | time_step=0.0005) 42 | # set main object 43 | quasiparticle = Quasiparticle(trajectory) 44 | 45 | # set parameters for calculation 46 | quasiparticle.select_power_spectra_algorithm(1) # MEM 47 | quasiparticle.set_number_of_mem_coefficients(1000) # Only is used if MEM is selected 48 | 49 | quasiparticle.set_reduced_q_vector([0.5, 0.0, 0.0]) # X Point 50 | quasiparticle.set_frequency_limits([0, 20]) 51 | quasiparticle.set_spectra_resolution(0.05) 52 | 53 | # get the renormalized force constants 54 | renormalized_fc = quasiparticle.get_renormalized_force_constants() 55 | 56 | # store force constants in phonopy format 57 | renormalized_fc_phonopy = renormalized_fc.get_array() 58 | write_FORCE_CONSTANTS(renormalized_fc_phonopy, 'RENORMALIZED_FORCE_CONSTANTS') 59 | -------------------------------------------------------------------------------- /examples/inputs/input_AlN: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE OUTCAR 2 | /home/abel/VASP/AlN-phonon/6x6x3/OUTCAR 3 | 4 | FORCE SETS 5 | /home/abel/VASP/AlN-phonon/6x6x3/FORCE_SETS 6 | 7 | PRIMITIVE MATRIX 8 | 1.0 0.0 0.0 9 | 0.0 1.0 0.0 10 | 0.0 0.0 1.0 11 | 12 | SUPERCELL MATRIX 13 | 6 0 0 14 | 0 6 0 15 | 0 0 3 16 | 17 | BANDS 18 | 0.0, 0.0, 0.0 0.33, 0.33, 0.0 19 | 0.33, 0.33, 0.0 0.5, 0.0, 0.0 20 | 0.5, 0.0, 0.0 0.0 ,0.0, 0.0 21 | 0.0, 0.0, 0.0 0.0, 0.0, 0.5 22 | -------------------------------------------------------------------------------- /examples/inputs/input_GaN: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | /home/abel/VASP/GaN/GaN-phonon/2x2x2/POSCAR 3 | 4 | FORCE SETS 5 | /home/abel/VASP/GaN/GaN-phonon/2x2x2/FORCE_SETS 6 | 7 | PRIMITIVE MATRIX 8 | 1.0 0.0 0.0 9 | 0.0 1.0 0.0 10 | 0.0 0.0 1.0 11 | 12 | SUPERCELL MATRIX 13 | 2 0 0 14 | 0 2 0 15 | 0 0 2 16 | 17 | BANDS 18 | 0.0, 0.0, 0.0 0.33, 0.33, 0.0 19 | 0.33, 0.33, 0.0 0.5, 0.0, 0.0 20 | 0.5, 0.0, 0.0 0.0 ,0.0, 0.0 21 | 0.0, 0.0, 0.0 0.0, 0.0, 0.5 22 | -------------------------------------------------------------------------------- /examples/inputs/input_Ge: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | /home/abel/VASP/Ge-phonon/4x4x4/POSCAR 3 | 4 | FORCE SETS 5 | /home/abel/VASP/Ge-phonon/4x4x4/FORCE_SETS 6 | 7 | 8 | PRIMITIVE MATRIX 9 | 0.0 0.5 0.5 10 | 0.5 0.0 0.5 11 | 0.5 0.5 0.0 12 | 13 | SUPERCELL MATRIX 14 | 4 0 0 15 | 0 4 0 16 | 0 0 4 17 | 18 | 19 | BANDS 20 | 0.0, 0.0, 0.0 0.5, 0.0, 0.5 21 | 0.5, 0.0, 0.5 0.625 0.25 0.625 22 | 0.375, 0.375, 0.75 0.0, 0.0, 0.0 23 | 0.0, 0.0, 0.0 0.5, 0.5, 0.5 24 | -------------------------------------------------------------------------------- /examples/inputs/input_MgO: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | /home/abel/VASP/MgO/MgO-FINAL/PHONON/4x4x4/POSCAR 3 | 4 | FORCE SETS 5 | /home/abel/VASP/MgO/MgO-FINAL/PHONON/4x4x4/FORCE_SETS 6 | 7 | 8 | PRIMITIVE MATRIX 9 | 0.0 0.5 0.5 10 | 0.5 0.0 0.5 11 | 0.5 0.5 0.0 12 | 13 | SUPERCELL MATRIX 14 | 4 0 0 15 | 0 4 0 16 | 0 0 4 17 | 18 | BANDS 19 | 0.5, 0.0, 0.5 0.25, 0.0, 0.25 20 | 0.25, 0.0, 0.25 0.0, 0.0, 0.0 21 | 0.0, 0.0, 0.0 0.25, 0.25, 0.5 22 | 0.25, 0.25 0.5 0.5, 0.5, 1.0 23 | 0.5 0.0 0.5 0.5, 0.25, 0.75 24 | 0.5, 0.25, 0.75 0.5 0.0 0.5 25 | 0.5 0.0 0.5 0.25 0.0 0.25 26 | 0.25 0.0 0.25 0.0 0.0 0.0 27 | 0.0 0.0 0.0 0.5, 0.5, 0.5 28 | -------------------------------------------------------------------------------- /examples/inputs/input_diamond: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | /home/abel/VASP/C-phonon/4x4x4/POSCAR 3 | 4 | FORCE SETS 5 | /home/abel/VASP/C-phonon/4x4x4/FORCE_SETS 6 | 7 | 8 | PRIMITIVE MATRIX 9 | 0.0 0.5 0.5 10 | 0.5 0.0 0.5 11 | 0.5 0.5 0.0 12 | 13 | SUPERCELL MATRIX 14 | 4 0 0 15 | 0 4 0 16 | 0 0 4 17 | 18 | 19 | BANDS 20 | 0.0, 0.0, 0.0 0.5, 0.0, 0.5 21 | 0.5, 0.0, 0.5 0.625 0.25 0.625 22 | 0.375, 0.375, 0.75 0.0, 0.0, 0.0 23 | 0.0, 0.0, 0.0 0.5, 0.5, 0.5 24 | -------------------------------------------------------------------------------- /examples/inputs/input_silicon: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | /home/abel/VASP/Si/Si-phonon/4x4x4B_GGA/POSCAR_original 3 | 4 | FORCE SETS 5 | /home/abel/VASP/Si/Si-phonon/4x4x4B_GGA/FORCE_SETS 6 | 7 | PRIMITIVE MATRIX 8 | 0.0 0.5 0.5 9 | 0.5 0.0 0.5 10 | 0.5 0.5 0.0 11 | 12 | SUPERCELL MATRIX 13 | 4 0 0 14 | 0 4 0 15 | 0 0 4 16 | 17 | 18 | BANDS 19 | 0.0, 0.0, 0.0 0.5, 0.0, 0.5 20 | 0.5, 0.0, 0.5 0.625 0.25 0.625 21 | 0.375, 0.375, 0.75 0.0, 0.0, 0.0 22 | 0.0, 0.0, 0.0 0.5, 0.5, 0.5 -------------------------------------------------------------------------------- /examples/lammps_interface/GaN/GaN.tersoff: -------------------------------------------------------------------------------- 1 | # DATE: 2007-10-22 CONTRIBUTOR: Xiaowang Zhou, xzhou @ sandia.gov CITATION: Nord, Albe, Erhart and Nordlund, J. Phys Condens Matter, 15, 5649 (2003) 2 | # Tersoff parameters for various elements and mixtures 3 | # multiple entries can be added to this file, LAMMPS reads the ones it needs 4 | # these entries are in LAMMPS "metal" units: 5 | # A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms 6 | # other quantities are unitless 7 | 8 | # format of a single entry (one or more lines): 9 | # element 1, element 2, element 3, 10 | # m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A 11 | 12 | # The following GaN potential is from J. Nord, K. Albe, P. Erhart 13 | # and K. Nordlund, J. Phys.: Condens. Matter, 15, 5649(2003). 14 | # This file is from Xiaowang Zhou, xzhou @ sandia.gov 15 | 16 | Ga Ga Ga 1.0 0.007874 1.846 1.918000 0.75000 -0.301300 1.0 1.0 17 | 1.44970 410.132 2.87 0.15 1.60916 535.199 18 | N N N 1.0 0.766120 0.000 0.178493 0.20172 -0.045238 1.0 1.0 19 | 2.38426 423.769 2.20 0.20 3.55779 1044.77 20 | Ga Ga N 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 0.0 21 | 0.00000 0.00000 2.90 0.20 0.00000 0.00000 22 | Ga N N 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 1.0 23 | 2.63906 3864.27 2.90 0.20 2.93516 6136.44 24 | N Ga Ga 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 1.0 25 | 2.63906 3864.27 2.90 0.20 2.93516 6136.44 26 | N Ga N 1.0 0.766120 0.000 0.178493 0.20172 -0.045238 1.0 0.0 27 | 0.00000 0.00000 2.20 0.20 0.00000 0.00000 28 | N N Ga 1.0 0.001632 0.000 65.20700 2.82100 -0.518000 1.0 0.0 29 | 0.00000 0.00000 2.90 0.20 0.00000 0.00000 30 | Ga N Ga 1.0 0.007874 1.846 1.918000 0.75000 -0.301300 1.0 0.0 31 | 0.00000 0.00000 2.87 0.15 0.00000 0.00000 32 | -------------------------------------------------------------------------------- /examples/lammps_interface/GaN/POSCAR_unitcell: -------------------------------------------------------------------------------- 1 | Ga N 2 | 1.0 3 | 3.1900000572 0.000000000 0.0000000000 4 | -1.5950000286 2.762621076 0.0000000000 5 | 0.0000000000 0.000000000 5.1890001297 6 | Ga N 7 | 2 2 8 | Direct 9 | 0.66666669 0.33333334 0.000000000 10 | 0.33333331 0.66666663 0.500000000 11 | 0.66666669 0.33333334 0.375000000 12 | 0.33333331 0.66666663 0.875000000 13 | -------------------------------------------------------------------------------- /examples/lammps_interface/GaN/README.txt: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Example: GaN with LAMMPS interface at 300 K # 3 | # -------------------------------------------------------------------------- # 4 | # Calculation of anharmonic properties of GaN using LAMMPS python interface. # 5 | # This mode requires LAMMPS python interface to be installed in your system. # 6 | # Please check LAMMPS website for detailed information: # 7 | # http://lammps.sandia.gov/doc/Section_python.html # 8 | ############################################################################## 9 | 10 | 1. Prepare LAMMPS input script. This script contains the atoms positions and 11 | definition of the crystal unit cell (the same defined in the POSCAR file) 12 | 13 | 2. Calculate the harmonic force constants. For this purpose you can use phonoLAMMPS 14 | (https://github.com/abelcarreras/phonolammps). 15 | 16 | 3. Run dynaphopy using "--run_lammps" with arguments. These arguments 17 | are: [lammps input script, MD simulation total time [ps], time step [ps], and 18 | stabilization time [ps]. Also you may want to define "--dim" to set the size of 19 | the supercell respect to the unit cell used in the molecular dynamics (MD) 20 | simulation (by default the unitcell is used). Ex: 21 | 22 | dynaphopy input_dynaphopy --run_lammps in.lammps 50 0.001 20 --dim 6 6 6 -i 23 | 24 | Note: The LAMMPS interface allows to perform dynamphopy calculations using LAMMPS MD without 25 | writing data on files. Note that the full MD will be calculated every time 26 | dynaphopy is executed. Use option flags (or interactive mode) to calculate several 27 | properties in one run. Alternatively, the trajectory can be stored in the disk in hdf5 format 28 | for later analysis using "--save_data" option. 29 | 30 | Note: The Tersoff potential file included in this example (SiCGe.tersoff) is part of LAMMPS package. 31 | This file is included here only for convenience. -------------------------------------------------------------------------------- /examples/lammps_interface/GaN/in.lammps: -------------------------------------------------------------------------------- 1 | units metal 2 | 3 | boundary p p p 4 | 5 | box tilt large 6 | 7 | atom_style atomic 8 | 9 | lattice custom 1.0 & 10 | a1 3.1900000572 0.000000000 0.0000000000 & 11 | a2 -1.5950000280 2.762621076 0.0000000000 & 12 | a3 0.0000000000 0.000000000 5.1890001297 & 13 | basis 0.66666669 0.33333334 0.000000000 & 14 | basis 0.33333331 0.66666663 0.500000000 & 15 | basis 0.66666669 0.33333334 0.375000000 & 16 | basis 0.33333331 0.66666663 0.875000000 17 | 18 | region box1 prism 0 0.6666666 0 1 0 1 -0.33333333 0 0 units lattice 19 | 20 | create_box 2 box1 21 | 22 | create_atoms 1 box basis 1 1 & 23 | basis 2 1 & 24 | basis 3 2 & 25 | basis 4 2 26 | 27 | mass 1 69.7230 28 | mass 2 14.0067 29 | 30 | pair_style tersoff 31 | pair_coeff * * GaN.tersoff Ga N 32 | 33 | variable t equal 300 34 | neighbor 0.3 bin 35 | 36 | velocity all create $t 3627941 dist gaussian mom yes 37 | velocity all scale $t 38 | 39 | fix int all nvt temp $t $t 0.5 #between 0.2-2.0 40 | 41 | -------------------------------------------------------------------------------- /examples/lammps_interface/GaN/input_dynaphopy: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | POSCAR_unitcell 3 | 4 | FORCE CONSTANTS 5 | FORCE_CONSTANTS_LAMMPS 6 | 7 | PRIMITIVE MATRIX 8 | 1.0 0.0 0.0 9 | 0.0 1.0 0.0 10 | 0.0 0.0 1.0 11 | 12 | SUPERCELL MATRIX PHONOPY 13 | 3 0 0 14 | 0 3 0 15 | 0 0 3 16 | 17 | -------------------------------------------------------------------------------- /examples/lammps_interface/Si/POSCAR_unitcell: -------------------------------------------------------------------------------- 1 | Si 2 | 1.00000000000000 3 | 5.4500000000000000 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 5.4500000000000000 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 5.4500000000000000 6 | Si 7 | 8 8 | Direct 9 | 0.8750000000000000 0.8750000000000000 0.8750000000000000 10 | 0.8750000000000000 0.3750000000000000 0.3750000000000000 11 | 0.3750000000000000 0.8750000000000000 0.3750000000000000 12 | 0.3750000000000000 0.3750000000000000 0.8750000000000000 13 | 0.1250000000000000 0.1250000000000000 0.1250000000000000 14 | 0.1250000000000000 0.6250000000000000 0.6250000000000000 15 | 0.6250000000000000 0.1250000000000000 0.6250000000000000 16 | 0.6250000000000000 0.6250000000000000 0.1250000000000000 17 | 18 | -------------------------------------------------------------------------------- /examples/lammps_interface/Si/README.txt: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Example: Si with LAMMPS interface at 900 K # 3 | # -------------------------------------------------------------------------- # 4 | # Calculation of anharmonic properties of Si using LAMMPS python interface. # 5 | # This mode requires LAMMPS python interface to be installed in your system. # 6 | # Please check LAMMPS website for detailed information: # 7 | # http://lammps.sandia.gov/doc/Section_python.html # 8 | ############################################################################## 9 | 10 | 1. Prepare LAMMPS input script. The atoms positions are written in an external 11 | file (data_unitcell.si). The unit cell defined in this file should be the same 12 | as the ones defined in the POSCAR_unitcell file. 13 | 14 | 2. Calculate the harmonic force constants. For this purpose you can use phonoLAMMPS 15 | (https://github.com/abelcarreras/phonolammps). 16 | 17 | 3. Run dynaphopy using "--run_lammps" with arguments. These arguments 18 | are: [lammps input script, MD simulation total time [ps], time step [ps], and 19 | stabilization time [ps]. Also you may want to define "--dim" to set the size of 20 | the supercell respect to the unit cell used in the molecular dynamics (MD) 21 | simulation (by default the unitcell is used). Ex: 22 | 23 | dynaphopy input_si --run_lammps in.lammps 50 0.001 50 --dim 2 2 2 -i 24 | 25 | Note: The LAMMPS interface allows to perform dynamphopy calculations using LAMMPS MD without 26 | writing data on files. Note that the full MD will be calculated every time 27 | dynaphopy is executed. Use option flags (or interactive mode) to calculate several 28 | properties in one run. Alternatively, the trajectory can be stored in the disk in hdf5 format 29 | for later analysis using "--save_data" option. 30 | 31 | Note: The Tersoff potential file included in this example (SiCGe.tersoff) is part of LAMMPS package. 32 | This file is included here only for convenience. -------------------------------------------------------------------------------- /examples/lammps_interface/Si/SiCGe.tersoff: -------------------------------------------------------------------------------- 1 | # DATE: 2009-03-18 CONTRIBUTOR: Aidan Thompson, athomps@sandia.gov CITATION: Tersoff, Phys Rev B, 39, 5566 (1989) 2 | 3 | # Tersoff parameters for various elements and mixtures 4 | # multiple entries can be added to this file, LAMMPS reads the ones it needs 5 | # these entries are in LAMMPS "metal" units: 6 | # A,B = eV; lambda1,lambda2,lambda3 = 1/Angstroms; R,D = Angstroms 7 | # other quantities are unitless 8 | 9 | # Aidan Thompson (athomps at sandia.gov) takes full blame for this 10 | # file. It specifies various potentials published by J. Tersoff for 11 | # silicon, carbon and germanium. Since Tersoff published several 12 | # different silicon potentials, I refer to them using atom types 13 | # Si(B), Si(C) and Si(D). The last two are almost almost identical but 14 | # refer to two different publications. These names should be used in 15 | # the LAMMPS command when the file is invoked. For example: 16 | # pair_coeff * * SiCGe.tersoff Si(B). The Si(D), C and Ge potentials 17 | # can be used pure silicon, pure carbon, pure germanium, binary SiC, 18 | # and binary SiGe, but not binary GeC or ternary SiGeC. LAMMPS will 19 | # generate an error if this file is used with any combination 20 | # involving C and Ge, since there are no entries for the GeC 21 | # interactions (Tersoff did not publish parameters for this 22 | # cross-interaction.) 23 | 24 | # format of a single entry (one or more lines): 25 | # element 1, element 2, element 3, 26 | # m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A 27 | 28 | # The original Tersoff potential for Silicon, Si(B) 29 | # J. Tersoff, PRB, 37, 6991 (1988) 30 | 31 | Si(B) Si(B) Si(B) 3.0 1.0 1.3258 4.8381 2.0417 0.0000 22.956 32 | 0.33675 1.3258 95.373 3.0 0.2 3.2394 3264.7 33 | 34 | # The later Tersoff potential for Silicon, Si(C) 35 | # J. Tersoff, PRB, 38, 9902 (1988) 36 | 37 | Si(C) Si(C) Si(C) 3.0 1.0 1.7322 1.0039e5 16.218 -0.59826 0.78734 38 | 1.0999e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 39 | 40 | # The later Tersoff potential for Carbon, Silicon, and Germanium 41 | # J. Tersoff, PRB, 39, 5566 (1989) + errata (PRB 41, 3248) 42 | # The Si and C parameters are very close to those in SiC.tersoff 43 | 44 | C C C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 2.2119 346.74 1.95 0.15 3.4879 1393.6 45 | Si(D) Si(D) Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.7322 471.18 2.85 0.15 2.4799 1830.8 46 | Ge Ge Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.7047 419.23 2.95 0.15 2.4451 1769.0 47 | 48 | C Si(D) Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 1.5724e-7 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 49 | C Si(D) C 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 1.95 0.15 0.0 0.0 50 | C C Si(D) 3.0 1.0 0.0 3.8049e4 4.3484 -0.57058 0.72751 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 51 | 52 | Si(D) C C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.97205 395.1451 2.3573 0.1527 2.9839 1597.3111 53 | Si(D) Si(D) C 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.3573 0.1527 0.0 0.0 54 | Si(D) C Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 55 | 56 | Si(D) Ge Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 1.1000e-6 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 57 | Si(D) Si(D) Ge 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 58 | Si(D) Ge Si(D) 3.0 1.0 0.0 1.0039e5 16.217 -0.59825 0.78734 0.0 0.0 0.0 2.85 0.15 0.0 0.0 59 | 60 | Ge Si(D) Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 9.0166e-7 1.71845 444.7177 2.8996 0.1500 2.4625 1799.6347 61 | Ge Si(D) Ge 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.95 0.15 0.0 0.0 62 | Ge Ge Si(D) 3.0 1.0 0.0 1.0643e5 15.652 -0.43884 0.75627 0.0 0.0 0.0 2.8996 0.1500 0.0 0.0 63 | 64 | -------------------------------------------------------------------------------- /examples/lammps_interface/Si/data_unitcell.si: -------------------------------------------------------------------------------- 1 | Generated using dynaphopy 2 | 3 | 8 atoms 4 | 5 | 1 atom types 6 | 7 | 8 | 0.0000000000 5.4500000000 xlo xhi 9 | 0.0000000000 5.4500000000 ylo yhi 10 | 0.0000000000 5.4500000000 zlo zhi 11 | 0.0000000000 0.0000000000 0.0000000000 xy xz yz 12 | 13 | Masses 14 | 15 | 1 28.0855000000 16 | 17 | Atoms 18 | 19 | 1 1 4.7687500000 4.7687500000 4.7687500000 20 | 2 1 4.7687500000 2.0437500000 2.0437500000 21 | 3 1 2.0437500000 4.7687500000 2.0437500000 22 | 4 1 2.0437500000 2.0437500000 4.7687500000 23 | 5 1 0.6812500000 0.6812500000 0.6812500000 24 | 6 1 0.6812500000 3.4062500000 3.4062500000 25 | 7 1 3.4062500000 0.6812500000 3.4062500000 26 | 8 1 3.4062500000 3.4062500000 0.6812500000 27 | -------------------------------------------------------------------------------- /examples/lammps_interface/Si/in.lammps: -------------------------------------------------------------------------------- 1 | # NaCl test problem for embedded atom method (EIM) potential 2 | 3 | units metal 4 | 5 | boundary p p p 6 | 7 | box tilt large 8 | 9 | atom_style atomic 10 | 11 | read_data data_unitcell.si 12 | 13 | pair_style tersoff 14 | pair_coeff * * SiCGe.tersoff Si(C) 15 | 16 | variable t equal 900 17 | 18 | neighbor 0.3 bin 19 | 20 | velocity all create $t 3627941 dist gaussian mom yes 21 | velocity all scale $t 22 | 23 | fix int all nvt temp $t $t 0.5 24 | -------------------------------------------------------------------------------- /examples/lammps_interface/Si/input_si: -------------------------------------------------------------------------------- 1 | STRUCTURE FILE POSCAR 2 | POSCAR_unitcell 3 | 4 | #FORCE CONSTANTS 5 | FORCE_CONSTANTS_LAMMPS 6 | 7 | FORCE SETS 8 | FORCE_SETS 9 | 10 | SUPERCELL MATRIX PHONOPY 11 | 2 0 0 12 | 0 2 0 13 | 0 0 2 14 | 15 | PRIMITIVE MATRIX 16 | 0.0 0.5 0.5 17 | 0.5 0.0 0.5 18 | 0.5 0.5 0.0 19 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ################################### 2 | # Required packages for DynaPhoPY # 3 | ################################### 4 | 5 | # 6 | # These are the requirements for dynaphopy 7 | # Install these packages using: 8 | # pip install -r requirements.txt --user 9 | # 10 | # The packages commented are optional and require 11 | # the instalations of additional libraries on 12 | # your system. Uncomment them to install. 13 | # 14 | 15 | 16 | ### These packages are mandatory to run the software ### 17 | 18 | phonopy >=2.0 19 | # Note: dynaphopy also may work with phonopy <=1.12.6.26, >=1.9.6 20 | numpy>=1.8.2 21 | scipy 22 | matplotlib 23 | seekpath 24 | PyYAML 25 | windows-curses; sys_platform == 'windows' 26 | 27 | ### These packages are optional (uncomment to install) ### 28 | 29 | # h5py may require to install libhdf5-serial-dev or libhdf5-openmp-dev libraries on your system 30 | # h5py 31 | 32 | # To use pyfftw FFTW libraries must be installed on your system (check pyfftw homepage for more information) 33 | # pyfftw 34 | 35 | # CUDA acceleration requires CUDA libraries and a nVidia CUDA compatible gpu card 36 | # cuda_functions -------------------------------------------------------------------------------- /scripts/concath5: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import h5py 4 | import sys 5 | import numpy as np 6 | import argparse 7 | 8 | parser = argparse.ArgumentParser(description='concath5') 9 | 10 | parser.add_argument('input', metavar='input_files', type=str, nargs='+', 11 | help='files to be joined') 12 | 13 | parser.add_argument('output', metavar='output_file', type=str, nargs=1, 14 | help='joined file') 15 | 16 | parser.add_argument('-f', metavar='N', type=int, nargs=1, default=[0], 17 | help='first steps to be skipped (default:0)') 18 | 19 | parser.add_argument('--velocity_only', action='store_true', 20 | help='Do not save trajectory in output file') 21 | 22 | args = parser.parse_args() 23 | 24 | #print(args.n) 25 | #print(args.input) 26 | #print(args.output) 27 | 28 | def read_file_hdf5(file_name): 29 | 30 | trajectory = None 31 | velocity = None 32 | vc = None 33 | reduced_q_vector = None 34 | 35 | hdf5_file = h5py.File(file_name, "r") 36 | 37 | time = hdf5_file['time'][:] 38 | supercell = hdf5_file['super_cell'][:] 39 | 40 | if 'trajectory' in hdf5_file: 41 | trajectory = hdf5_file['trajectory'][:] 42 | if 'velocity' in hdf5_file: 43 | velocity = hdf5_file['velocity'][:] 44 | if 'vc' in hdf5_file: 45 | vc = hdf5_file['vc'][:] 46 | reduced_q_vector = hdf5_file['reduced_q_vector'][:] 47 | 48 | 49 | hdf5_file.close() 50 | 51 | return vc, velocity, trajectory, time, supercell, reduced_q_vector 52 | 53 | def save_data_hdf5(file_name, time, supercell, trajectory=None, velocity=None, vc=None, reduced_q_vector=None): 54 | 55 | hdf5_file = h5py.File(file_name, "w") 56 | 57 | hdf5_file.create_dataset('time', data=time) 58 | hdf5_file.create_dataset('super_cell', data=supercell) 59 | 60 | if reduced_q_vector is not None: 61 | hdf5_file.create_dataset('reduced_q_vector', data=reduced_q_vector) 62 | 63 | steps = 0 64 | 65 | if trajectory is not None: 66 | hdf5_file.create_dataset('trajectory', data=trajectory) 67 | 68 | if velocity is not None: 69 | hdf5_file.create_dataset('velocity', data=velocity) 70 | steps = velocity.shape[0] 71 | 72 | if vc is not None: 73 | hdf5_file.create_dataset('vc', data=vc) 74 | steps = vc.shape[0] 75 | 76 | 77 | print ('saved {0} steps'.format(steps)) 78 | 79 | hdf5_file.close() 80 | 81 | if len(sys.argv) == 1: 82 | print('Usage: concath5 file.h5 file2.h5 ... concatenated.h5') 83 | exit() 84 | 85 | 86 | first = args.f[0] 87 | print("skipping first {0} steps".format(first)) 88 | vc, velocity, trajectory, time, supercell, r_q_vector = read_file_hdf5(args.input[0]) 89 | 90 | 91 | if args.velocity_only: 92 | trajectory = None 93 | vc = None 94 | 95 | if velocity is not None: 96 | velocity = velocity[first:] 97 | 98 | if vc is not None: 99 | vc = vc[first:] 100 | 101 | if trajectory is not None: 102 | trajectory = trajectory[first:] 103 | 104 | print(args.input[0]) 105 | 106 | for arg in args.input[1:]: 107 | print(arg) 108 | new_vc, new_velocity, new_trajectory = read_file_hdf5(arg)[0:3] 109 | 110 | if trajectory is not None: 111 | trajectory = np.concatenate((trajectory, new_trajectory[first:]), axis=0) 112 | 113 | if velocity is not None: 114 | velocity = np.concatenate((velocity, new_velocity[first:]), axis=0) 115 | 116 | if vc is not None: 117 | vc = np.concatenate((vc, new_vc[first:]), axis=0) 118 | 119 | print ('Final: ', args.output[0]) 120 | 121 | save_data_hdf5(args.output[0], 122 | time, 123 | supercell, 124 | trajectory=trajectory, 125 | velocity=velocity, 126 | vc=vc, 127 | reduced_q_vector=r_q_vector) 128 | -------------------------------------------------------------------------------- /scripts/fitdata: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import numpy as np 4 | import dynaphopy.analysis.fitting as fitting 5 | import dynaphopy.interface.iofile as reading 6 | import matplotlib.pyplot as plt 7 | 8 | import argparse 9 | 10 | 11 | # Arguments definition 12 | parser = argparse.ArgumentParser(description='fitdata') 13 | parser.add_argument('file', metavar='file', type=str, 14 | help='file containing power spectra information') 15 | 16 | parser.add_argument('-bi', metavar='indices', type=str, nargs='+', default=None, 17 | help='band indices (ex: "1,2 3 4, 5")') 18 | 19 | parser.add_argument('-sm', '--smooth', action='store_true', 20 | help='smooth before fitting (LOESS method)') 21 | 22 | parser.add_argument('-f', metavar='N', type=float, default=0.02, 23 | help='smooth factor [Default: 0.02]') 24 | 25 | parser.add_argument('-s', metavar='file', type=str, 26 | help='save spectra to file') 27 | 28 | parser.add_argument('--silent', action='store_true', 29 | help='do not show plots') 30 | 31 | parser.add_argument('--fitting_function', type=int, default=0, metavar='N', 32 | help='Select fitting function') 33 | 34 | args = parser.parse_args() 35 | 36 | 37 | # LOESS method definition 38 | def loess(x, y, f=2./3.): 39 | 40 | n = len(x) 41 | r = int(np.ceil(f*n)) 42 | h = [np.sort(np.abs(x - x[i]))[r] for i in range(n)] 43 | w = np.clip(np.abs((x[:, None] - x[None, :]) / h), 0.0, 1.0) 44 | w = (1.0 - w**3)**3 45 | y_smooth = np.zeros(n) 46 | delta = np.ones(n) 47 | for i in range(n): 48 | weights = delta * w[:, i] 49 | b = np.array([np.sum(weights*y), np.sum(weights*y*x)]) 50 | a = np.array([[np.sum(weights), np.sum(weights*x)], 51 | [np.sum(weights*x), np.sum(weights*x*x)]]) 52 | beta = np.linalg.solve(a, b) 53 | y_smooth[i] = beta[0] + beta[1]*x[i] 54 | 55 | return y_smooth 56 | 57 | #Process input data 58 | try: 59 | input_file = open(args.file, "r") 60 | except IOError: 61 | print("File not found") 62 | exit() 63 | 64 | if args.bi is None: 65 | data_num = len(input_file.readline().split()) 66 | degeneracy = [[i] for i in range(1, data_num)] 67 | else: 68 | degeneracy = [[int(j) for j in i.split()] for i in ' '.join(args.bi).split(',')] 69 | 70 | 71 | initial_data = [] 72 | for line in input_file: 73 | initial_data.append(line.split()) 74 | initial_data = np.array(initial_data,dtype=float) 75 | 76 | 77 | test_frequencies_range = np.array(initial_data[:,0]) 78 | data = [] 79 | for phonon in degeneracy: 80 | data_temp = np.zeros_like(test_frequencies_range) 81 | for degenerate in phonon: 82 | data_temp += initial_data[:, degenerate]/len(phonon) 83 | data.append(data_temp) 84 | 85 | 86 | 87 | # Smoothing using LOESS method 88 | if args.smooth: 89 | 90 | y_smooth = [] 91 | for i, datum in enumerate(data): 92 | 93 | y2 = loess(test_frequencies_range, datum, f=args.f) 94 | 95 | if not args.silent: 96 | plt.figure(i+1) 97 | plt.title('Band '+str(i+1)) 98 | plt.suptitle('Smoothing LOESS') 99 | 100 | plt.plot(test_frequencies_range, datum, label='Original') 101 | plt.plot(test_frequencies_range, y2, label='Smooth', linewidth=3) 102 | plt.legend() 103 | 104 | y_smooth.append(y2) 105 | 106 | if not args.silent: 107 | plt.show() 108 | 109 | data = np.array(y_smooth).T 110 | else: 111 | data = np.array(data).T 112 | 113 | # Analysis using Dynaphopy functions 114 | fitting.phonon_fitting_analysis(data, test_frequencies_range, 115 | show_plots=not args.silent, 116 | fitting_function_type=args.fitting_function, 117 | use_degeneracy=None) 118 | 119 | if args.s: 120 | reading.write_curve_to_file(test_frequencies_range, data, args.s) 121 | -------------------------------------------------------------------------------- /scripts/qha_extract: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import dynaphopy.interface.iofile as iofile 3 | import dynaphopy.interface.phonopy_link as phonopy_link 4 | 5 | import numpy as np 6 | import yaml 7 | import argparse 8 | import glob 9 | 10 | from phonopy import PhonopyQHA 11 | from scipy.interpolate import interp1d 12 | 13 | parser = argparse.ArgumentParser(description='thermal_extractor options') 14 | parser.add_argument('input_file', metavar='data_file', type=str, 15 | help='input file containing structure related data') 16 | 17 | parser.add_argument('-fc', metavar='data_file', type=str, nargs='*', required=True, 18 | help='phonopy force constant files') 19 | 20 | parser.add_argument('-tp', metavar='data_file', type=str, nargs='*', required=True, 21 | help='phonopy thermal properties files') 22 | 23 | parser.add_argument('-ev', metavar='data', type=str, required=True, 24 | help='Energy volume file') 25 | 26 | parser.add_argument('-t', metavar='F', type=float, required=True, 27 | help='temperature at which the renormalized force constants will be calculated') 28 | 29 | parser.add_argument('-p', action='store_true', 30 | help='plot QHA data') 31 | 32 | parser.add_argument('-sfc', metavar='filename', type=str, default='FORCE_CONSTANTS_QHA', 33 | help='select custom filename to store the renormalized force constants') 34 | 35 | 36 | args = parser.parse_args() 37 | 38 | # Read energy volume data 39 | target_temperature = args.t 40 | ev_file = np.loadtxt(args.ev) 41 | volumes = ev_file.T[0] 42 | electronic_energies = ev_file.T[1] 43 | 44 | # Read force constants 45 | fc_filenames = [] 46 | for i in args.fc: 47 | fc_filenames += list(sorted(glob.iglob(i))) 48 | 49 | # Read and setup thermal_properties 50 | tp_filenames = [] 51 | for i in args.tp: 52 | tp_filenames += list(sorted(glob.iglob(i))) 53 | 54 | temperatures = [] 55 | fe_phonon = [] 56 | entropy = [] 57 | cv = [] 58 | 59 | for filename in tp_filenames: 60 | temperatures = [] 61 | entropy_i = [] 62 | fe_i = [] 63 | cv_i = [] 64 | 65 | with open(filename, 'r') as stream: 66 | thermal_properties = dict(yaml.safe_load(stream)) 67 | for tp in thermal_properties['thermal_properties']: 68 | temperatures.append(tp['temperature']) 69 | entropy_i.append(tp['entropy']) 70 | fe_i.append(tp['free_energy']) 71 | cv_i.append(tp['heat_capacity']) 72 | 73 | fe_phonon.append(fe_i) 74 | entropy.append(entropy_i) 75 | cv.append(cv_i) 76 | 77 | sort_index = np.argsort(volumes) 78 | 79 | volumes = np.array(volumes)[sort_index] 80 | electronic_energies = np.array(electronic_energies)[sort_index] 81 | temperatures = np.array(temperatures) 82 | fe_phonon = np.array(fe_phonon).T[:, sort_index] 83 | entropy = np.array(entropy).T[:, sort_index] 84 | cv = np.array(cv).T[:, sort_index] 85 | 86 | # Apply QHA using phonopy 87 | phonopy_qha = PhonopyQHA(np.array(volumes), 88 | np.array(electronic_energies), 89 | eos="vinet", 90 | temperatures=np.array(temperatures), 91 | free_energy=np.array(fe_phonon), 92 | cv=np.array(cv), 93 | entropy=np.array(entropy), 94 | #t_max=target_temperature, 95 | verbose=False) 96 | 97 | if args.p: 98 | phonopy_qha.plot_qha().show() 99 | 100 | try: 101 | volume_temperature = phonopy_qha.get_volume_temperature() 102 | except DeprecationWarning: 103 | volume_temperature = phonopy_qha.volume_temperature 104 | 105 | qha_temperatures = temperatures[:len(volume_temperature)] 106 | 107 | 108 | # Fit force constants as a function of the temperature 109 | fit_vt = interp1d(qha_temperatures, volume_temperature, kind='quadratic') 110 | try: 111 | target_volume = fit_vt(target_temperature) 112 | except ValueError: 113 | raise Exception('Error interpolating this temperature!\n' 114 | 'Make sure the requested temperature is within the range of thermal_properties.yaml files') 115 | 116 | input_parameters = iofile.read_parameters_from_input_file(args.input_file) 117 | 118 | # if 'structure_file_name_outcar' in input_parameters: 119 | # structure = iofile.read_from_file_structure_outcar(input_parameters['structure_file_name_outcar']) 120 | # else: 121 | # structure = iofile.read_from_file_structure_poscar(input_parameters['structure_file_name_poscar']) 122 | # structure.get_data_from_dict(input_parameters) 123 | 124 | fc_supercell = input_parameters['supercell_phonon'] 125 | 126 | force_constants_mat = [] 127 | for filename in fc_filenames: 128 | force_constants = phonopy_link.get_force_constants_from_file(filename, fc_supercell=fc_supercell) 129 | force_constants_mat.append(force_constants.get_array()) 130 | 131 | force_constants_mat = np.array(force_constants_mat).T 132 | f_temperature = interp1d(volumes, force_constants_mat, kind='quadratic') 133 | 134 | # Get force constants at the requested temperature 135 | try: 136 | target_fc = f_temperature(target_volume).T 137 | except ValueError: 138 | raise Exception('Error interpolating minimum volume!\n' 139 | 'Make sure the free energy-volume curve has a minimum ') 140 | 141 | phonopy_link.write_FORCE_CONSTANTS(target_fc,filename=args.sfc) 142 | 143 | print ('QHA Renormalized force constants written in file: {}'.format(args.sfc)) 144 | -------------------------------------------------------------------------------- /scripts/rfc_calc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import numpy as np 4 | import matplotlib.pyplot as plt 5 | import argparse 6 | 7 | import dynaphopy.interface.phonopy_link as pho_interface 8 | import dynaphopy.interface.iofile as reading 9 | 10 | 11 | parser = argparse.ArgumentParser(description='rfc_calc options') 12 | parser.add_argument('input_file', metavar='data_file', type=str, nargs=1, 13 | help='input file containing structure related data') 14 | 15 | group = parser.add_mutually_exclusive_group (required=True) 16 | group.add_argument('-cp', action='store_true', 17 | help='get commensurate points') 18 | group.add_argument('frequency_file', metavar='data_file', type=str, nargs='?', 19 | help='input file containing renormalized phonon frequencies') 20 | 21 | parser.add_argument('-p', action='store_true', 22 | help='plot phonon band structure') 23 | 24 | parser.add_argument('-s', metavar='FORCE_CONSTANTS', type=str, nargs=1, 25 | help='save force_constants into a file') 26 | 27 | parser.add_argument('--fcsymm', action='store_true', 28 | help='symmetrize force constants') 29 | 30 | parser.add_argument('--dim', metavar='N', type=int, nargs=3, default=None, 31 | help='define custom supercell') 32 | 33 | args = parser.parse_args() 34 | 35 | 36 | def get_renormalized_constants(freq_filename, structure, symmetrize=False, degenerate=True): 37 | 38 | if 'force_sets_file_name' in input_parameters: 39 | structure.set_force_set(pho_interface.get_force_sets_from_file(file_name=input_parameters['force_sets_file_name'], fs_supercell=input_parameters['supercell_phonon'])) 40 | if 'force_constants_file_name' in input_parameters: 41 | structure.set_force_constants(pho_interface.get_force_constants_from_file(file_name=input_parameters['force_constants_file_name'], fc_supercell=input_parameters['supercell_phonon'] )) 42 | 43 | structure.get_data_from_dict(input_parameters) 44 | 45 | fc_supercell = structure.get_supercell_phonon() 46 | if args.dim is None: 47 | if 'supercell_phonon' in input_parameters: 48 | fc_supercell = input_parameters['supercell_phonon'] 49 | else: 50 | print('please define supercell phonon in inputfile') 51 | exit() 52 | 53 | com_points = pho_interface.get_commensurate_points(structure, fc_supercell) 54 | 55 | # Seems thet the commenurate points have to be in the same original order. 56 | renormalized_frequencies = [] 57 | import yaml 58 | with open(freq_filename, 'r') as stream: 59 | data_dict = yaml.safe_load(stream) 60 | for wv in com_points: 61 | for q_point in data_dict.values(): 62 | # print q_point 63 | # print q_point['frequencies'] 64 | if np.array(q_point['reduced_wave_vector'] == wv).all(): 65 | renormalized_frequencies.append(q_point['frequencies']) 66 | # com_points.append(q_point['reduced_wave_vector']) 67 | 68 | renormalized_frequencies = np.array(renormalized_frequencies) 69 | #com_points = np.array(com_points) 70 | 71 | eigenvectors = [pho_interface.obtain_eigenvectors_and_frequencies(structure, point, print_data=False)[0] for point in com_points] 72 | 73 | renormalized_force_constants = pho_interface.get_renormalized_force_constants(renormalized_frequencies, 74 | eigenvectors, 75 | structure, 76 | fc_supercell, 77 | symmetrize=symmetrize) 78 | 79 | return renormalized_force_constants 80 | 81 | 82 | def plot_renormalized_phonon_bands(structure, renormalized_force_constants): 83 | 84 | if '_band_ranges' in input_parameters: 85 | band_ranges = input_parameters['_band_ranges'] 86 | else: 87 | band_ranges = structure.get_path_using_seek_path()['ranges'] 88 | 89 | 90 | bands = pho_interface.obtain_phonon_dispersion_bands(structure, 91 | band_ranges, 92 | NAC=False) 93 | 94 | renormalized_bands = pho_interface.obtain_phonon_dispersion_bands(structure, 95 | band_ranges, 96 | force_constants=renormalized_force_constants, 97 | NAC=False) 98 | 99 | for i,freq in enumerate(renormalized_bands[1]): 100 | plt.plot(bands[1][i],bands[2][i],color ='b', label='Harmonic (0K)') 101 | plt.plot(renormalized_bands[1][i],renormalized_bands[2][i],color ='r', label='Renormalized') 102 | plt.axes().get_xaxis().set_visible(False) 103 | plt.axes().get_xaxis().set_ticks([]) 104 | plt.ylabel('Frequency [THz]') 105 | plt.xlabel('Wave vector') 106 | plt.xlim([0, renormalized_bands[1][-1][-1]]) 107 | plt.axhline(y=0, color='k', ls='dashed') 108 | plt.suptitle('Renormalized phonon dispersion') 109 | handles, labels = plt.gca().get_legend_handles_labels() 110 | plt.legend([handles[0], handles[-1]], ['Harmonic','Renormalized']) 111 | plt.show() 112 | 113 | 114 | # Get data from input file & process parameters 115 | input_parameters = reading.read_parameters_from_input_file(args.input_file[0]) 116 | 117 | if 'structure_file_name_outcar' in input_parameters: 118 | structure = reading.read_from_file_structure_outcar(input_parameters['structure_file_name_outcar']) 119 | else: 120 | structure = reading.read_from_file_structure_poscar(input_parameters['structure_file_name_poscar']) 121 | 122 | structure.get_data_from_dict(input_parameters) 123 | 124 | # if args.dim is not None: 125 | # structure.set_supercell_phonon_renormalized(np.diag(np.array(args.dim, dtype=int))) 126 | 127 | # Process options 128 | if args.cp: 129 | 130 | if args.dim is None: 131 | if 'supercell_phonon' in input_parameters: 132 | fc_supercell = input_parameters['supercell_phonon'] 133 | else: 134 | print('Warning: No supercell matrix defined! using unitcell as supercell') 135 | fc_supercell = np.identity(3) 136 | com_points = pho_interface.get_commensurate_points(structure, fc_supercell) 137 | else: 138 | com_points = pho_interface.get_commensurate_points(structure, np.diag(args.dim)) 139 | 140 | for q_point in com_points: 141 | print(q_point) 142 | exit() 143 | 144 | renormalized_force_constants = get_renormalized_constants(args.frequency_file, structure, symmetrize=args.fcsymm) 145 | 146 | if args.s: 147 | pho_interface.save_force_constants_to_file(renormalized_force_constants, filename=args.s[0]) 148 | 149 | if args.p: 150 | plot_renormalized_phonon_bands(structure, renormalized_force_constants) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | try: 2 | from setuptools import setup, Extension 3 | use_setuptools = True 4 | print('setuptools is used') 5 | except ImportError: 6 | from distutils.core import setup, Extension 7 | use_setuptools = False 8 | print('distutils is used') 9 | 10 | import numpy 11 | import sys 12 | 13 | include_dirs_numpy = [numpy.get_include()] 14 | 15 | 16 | def check_compiler(): 17 | import subprocess 18 | output = subprocess.Popen(['gcc'], stderr=subprocess.PIPE).communicate()[1] 19 | if b'clang' in output: 20 | return 'clang' 21 | if b'gcc' in output: 22 | return 'gcc' 23 | 24 | 25 | def get_version_number(): 26 | main_ns = {} 27 | for line in open('dynaphopy/__init__.py', 'r').readlines(): 28 | if not(line.find('__version__')): 29 | exec(line, main_ns) 30 | return main_ns['__version__'] 31 | 32 | 33 | if check_compiler() == 'clang': 34 | correlation = Extension('dynaphopy.power_spectrum.correlation', 35 | extra_compile_args=['-std=c99'], 36 | include_dirs=include_dirs_numpy, 37 | sources=['c/correlation.c']) 38 | 39 | mem = Extension('dynaphopy.power_spectrum.mem', 40 | extra_compile_args=['-std=c99'], 41 | include_dirs=include_dirs_numpy, 42 | sources=['c/mem.c']) 43 | 44 | else: 45 | print ('openmp is used') 46 | correlation = Extension('dynaphopy.power_spectrum.correlation', 47 | extra_compile_args=['-std=c99', '-fopenmp'], 48 | extra_link_args=['-lgomp'], 49 | include_dirs=include_dirs_numpy, 50 | sources=['c/correlation.c']) 51 | 52 | mem = Extension('dynaphopy.power_spectrum.mem', 53 | extra_compile_args=['-std=c99', '-fopenmp'], 54 | extra_link_args=['-lgomp'], 55 | include_dirs=include_dirs_numpy, 56 | sources=['c/mem.c']) 57 | 58 | displacements = Extension('dynaphopy.displacements', 59 | extra_compile_args=['-std=c99'], 60 | include_dirs=include_dirs_numpy, 61 | sources=['c/displacements.c']) 62 | 63 | setup(name='dynaphopy', 64 | version=get_version_number(), 65 | description='dynaphopy module', 66 | author='Abel Carreras', 67 | url='https://github.com/abelcarreras/DynaPhoPy', 68 | author_email='abelcarreras83@gmail.com', 69 | packages=['dynaphopy', 70 | 'dynaphopy.power_spectrum', 71 | 'dynaphopy.analysis', 72 | 'dynaphopy.analysis.fitting', 73 | 'dynaphopy.interface', 74 | 'dynaphopy.interface.iofile'], 75 | scripts=['scripts/dynaphopy', 76 | 'scripts/concath5', 77 | 'scripts/fitdata', 78 | 'scripts/qha_extract', 79 | 'scripts/rfc_calc'], 80 | install_requires=['phonopy', 'numpy', 'scipy', 'matplotlib'] + (["windows-curses"] if sys.platform in ["win32", "cygwin"] else []), 81 | license='MIT License', 82 | long_description=open('README.md').read(), 83 | long_description_content_type='text/markdown', 84 | ext_modules=[correlation, mem, displacements]) 85 | -------------------------------------------------------------------------------- /unittest/Ag2Cu2O4_data/POSCAR: -------------------------------------------------------------------------------- 1 | Ag2Cu2O4 2 | 1.00000000000000 3 | 6.0615768472847344 0.0000000000000 -0.0089799621832398 4 | 0.000000000000000 2.814083005924144 0.0000000000000000 5 | -1.94175993509 0.000000000000000 5.39757575753155 6 | Ag Cu O 7 | 2 2 4 8 | Direct 9 | 0.0000000000000000 0.0000000000000000 0.0000000000000000 10 | 0.5000000000000000 0.5000000000000000 0.0000000000000000 11 | 0.0000000000000000 0.5000000000000000 0.5000000000000000 12 | 0.5000000000000000 0.0000000000000000 0.5000000000000000 13 | 0.3516123588593323 0.5000000000000000 0.2900275174711524 14 | 0.6483876411406685 0.5000000000000000 0.7099724825288461 15 | 0.8516123588593315 0.0000000000000000 0.2900275174711524 16 | 0.1483876411406668 0.0000000000000000 0.7099724825288461 17 | -------------------------------------------------------------------------------- /unittest/Ag2Cu2O4_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import unittest 4 | import numpy as np 5 | import dynaphopy 6 | import dynaphopy.interface.iofile as io 7 | from dynaphopy.interface.phonopy_link import get_force_sets_from_file 8 | from dynaphopy.atoms import Structure 9 | 10 | 11 | class TestDynaphopy(unittest.TestCase): 12 | 13 | def setUp(self): 14 | #structure = io.read_from_file_structure_poscar('Ag2Cu2O4_data/POSCAR') 15 | 16 | scaled_positions = [[0.0000000000000000, 0.0000000000000000, 0.0000000000000000], 17 | [0.5000000000000000, 0.5000000000000000, 0.0000000000000000], 18 | [0.0000000000000000, 0.5000000000000000, 0.5000000000000000], 19 | [0.5000000000000000, 0.0000000000000000, 0.5000000000000000], 20 | [0.3516123588593323, 0.5000000000000000, 0.2900275174711524], 21 | [0.6483876411406685, 0.5000000000000000, 0.7099724825288461], 22 | [0.8516123588593315, 0.0000000000000000, 0.2900275174711524], 23 | [0.1483876411406668, 0.0000000000000000, 0.7099724825288461]] 24 | 25 | unit_cell = [[6.061576847284, 0.0000000000000, -0.00897996218323], 26 | [0.000000000000, 2.8140830059241, 0.00000000000000], 27 | [-1.94175993509, 0.0000000000000, 5.39757575753155]] 28 | 29 | atomic_symbols = ['Ag', 'Ag', 'Cu', 'Cu', 'O', 'O', 'O', 'O'] 30 | 31 | self.structure = Structure(cell=unit_cell, 32 | scaled_positions=scaled_positions, 33 | atomic_elements=atomic_symbols) 34 | 35 | self.structure.set_primitive_matrix([[0.5, -0.5, 0.0], 36 | [0.5, 0.5, 0.0], 37 | [0.0, 0.0, 1.0]]) 38 | 39 | force_sets = get_force_sets_from_file(file_name='Ag2Cu2O4_data/FORCE_SETS', 40 | fs_supercell=[[2, 0, 0], 41 | [0, 2, 0], 42 | [0, 0, 2]]) 43 | 44 | self.structure.set_force_set(force_sets) 45 | 46 | def test_force_constants_self_consistency(self): 47 | 48 | trajectory = io.generate_test_trajectory(self.structure, 49 | supercell=[2, 2, 2], 50 | total_time=3, 51 | time_step=0.001, 52 | temperature=300, 53 | silent=False) 54 | 55 | self.calculation = dynaphopy.Quasiparticle(trajectory) 56 | self.calculation.select_power_spectra_algorithm(2) 57 | 58 | renormalized_force_constants = self.calculation.get_renormalized_force_constants().get_array() 59 | harmonic_force_constants = self.calculation.dynamic.structure.get_force_constants().get_array() 60 | 61 | self.assertEqual(np.allclose(renormalized_force_constants, harmonic_force_constants, rtol=1, atol=5.e-2), True) 62 | 63 | def _test_average(self): 64 | 65 | trajectory = io.generate_test_trajectory(self.structure, 66 | supercell=[1, 2, 3], 67 | total_time=5, 68 | silent=False, 69 | temperature=10) 70 | self.calculation = dynaphopy.Quasiparticle(trajectory) 71 | 72 | positions_average = self.calculation.dynamic.average_positions(to_unit_cell=True).real 73 | print(positions_average) 74 | reference = [[-1.94173041e+00, 2.81396066e+00, 5.39755913e+00], 75 | [ 1.08905801e+00, 1.40691916e+00, 5.39306914e+00], 76 | [ 5.09064600e+00, 1.40718064e+00, 2.68983555e+00], 77 | [ 2.05985758e+00, 1.39139630e-04, 2.69432553e+00], 78 | [ 1.56812170e+00, 1.40719153e+00, 1.56230533e+00], 79 | [ 2.55169805e+00, 1.40716376e+00, 3.82629282e+00], 80 | [ 4.59891013e+00, 1.50025412e-04, 1.55781535e+00], 81 | [-4.79090372e-01, 1.22256709e-04, 3.83078280e+00]] 82 | 83 | np.testing.assert_array_almost_equal(positions_average, reference, decimal=1) 84 | 85 | 86 | if __name__ == '__main__': 87 | unittest.main() 88 | -------------------------------------------------------------------------------- /unittest/GaN_data/POSCAR: -------------------------------------------------------------------------------- 1 | Ga N 2 | 1.0 3 | 3.1900000572 0.0000000000 0.0000000000 4 | -1.5950000286 2.7626210876 0.0000000000 5 | 0.0000000000 0.0000000000 5.1890001297 6 | Ga N 7 | 2 2 8 | Direct 9 | 0.666666687 0.333333343 0.000000000 10 | 0.333333313 0.666666627 0.500000000 11 | 0.666666687 0.333333343 0.375000000 12 | 0.333333313 0.666666627 0.875000000 13 | -------------------------------------------------------------------------------- /unittest/GaN_data/atomic_displacements.dat: -------------------------------------------------------------------------------- 1 | -0.2838 0.0000000000e+00 0.0000000000e+00 3.4470497284e-03 0.0000000000e+00 2 | -0.2659 1.3788198913e-03 0.0000000000e+00 2.0682298370e-03 0.0000000000e+00 3 | -0.2480 8.9623292937e-03 2.2750528207e-02 1.3788198913e-02 2.0682298370e-03 4 | -0.2301 1.7235248642e-02 4.0675186795e-02 2.0682298370e-02 1.7235248642e-02 5 | -0.2122 7.3077454241e-02 9.8585622231e-02 4.8258696197e-02 7.5835094024e-02 6 | -0.1943 1.4339726870e-01 2.1716413289e-01 1.6545838696e-01 1.5994310740e-01 7 | -0.1764 3.4332615294e-01 3.6331904137e-01 3.4608379273e-01 3.4056851316e-01 8 | -0.1585 6.1564308149e-01 6.4115124948e-01 7.0802401421e-01 6.6321236774e-01 9 | -0.1406 1.0492819373e+00 1.1520040192e+00 1.1361475905e+00 1.1258064413e+00 10 | -0.1227 1.7786776598e+00 1.6449321304e+00 1.8427927848e+00 1.8186634367e+00 11 | -0.1047 2.5790826068e+00 2.4529205867e+00 2.6687058997e+00 2.6804258688e+00 12 | -0.0868 3.6028563761e+00 3.6628350414e+00 3.4153368709e+00 3.5725223385e+00 13 | -0.0689 4.5335598027e+00 4.4142918821e+00 4.3515555771e+00 4.4584141187e+00 14 | -0.0510 5.2402049971e+00 5.2340003075e+00 5.3050095320e+00 5.0878453991e+00 15 | -0.0331 5.8144834818e+00 5.8386128299e+00 5.6435098153e+00 5.7503683569e+00 16 | -0.0152 6.1495367154e+00 5.8958338554e+00 6.0233746953e+00 5.9034173648e+00 17 | 0.0027 5.6883214617e+00 5.7800129845e+00 5.7855282641e+00 5.6255851567e+00 18 | 0.0206 5.0437231625e+00 5.1292099958e+00 5.1712640025e+00 5.1154217969e+00 19 | 0.0385 4.1350808541e+00 4.1440431834e+00 4.0861327480e+00 4.2736522532e+00 20 | 0.0564 3.1250952837e+00 3.3498429260e+00 3.1409517125e+00 3.3257135779e+00 21 | 0.0743 2.3791537225e+00 2.2178317952e+00 2.3302056164e+00 2.3233115169e+00 22 | 0.0922 1.5835746452e+00 1.4918831224e+00 1.5394524087e+00 1.5573770673e+00 23 | 0.1101 9.4104457584e-01 9.5759041454e-01 1.0024020610e+00 9.7758330296e-01 24 | 0.1281 5.0671631007e-01 5.5566441621e-01 5.7014202507e-01 5.1429981947e-01 25 | 0.1460 2.6886987881e-01 2.9162040702e-01 3.1230270539e-01 2.6886987881e-01 26 | 0.1639 1.3719257919e-01 1.2340438028e-01 1.4408667865e-01 1.2409379022e-01 27 | 0.1818 5.3773975762e-02 5.7910435437e-02 4.4122236523e-02 5.9289255328e-02 28 | 0.1997 2.6197577936e-02 3.5849317175e-02 1.3098788968e-02 1.5856428750e-02 29 | 0.2176 2.7576397827e-03 1.9303478479e-02 6.8940994567e-03 4.8258696197e-03 30 | 0.2355 0.0000000000e+00 8.9623292937e-03 1.3788198913e-03 0.0000000000e+00 31 | -------------------------------------------------------------------------------- /unittest/GaN_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import numpy as np 3 | import os 4 | import dynaphopy.interface.iofile as io 5 | import dynaphopy 6 | from dynaphopy.interface.phonopy_link import get_force_constants_from_file 7 | import unittest 8 | 9 | 10 | class TestDynaphopy(unittest.TestCase): 11 | 12 | def setUp(self): 13 | self.structure = io.read_from_file_structure_poscar('GaN_data/POSCAR') 14 | 15 | self.structure.set_primitive_matrix([[1.0, 0.0, 0.0], 16 | [0.0, 1.0, 0.0], 17 | [0.0, 0.0, 1.0]]) 18 | 19 | self.structure.set_force_constants(get_force_constants_from_file(file_name='GaN_data/FORCE_CONSTANTS', 20 | fc_supercell=[[3, 0, 0], 21 | [0, 3, 0], 22 | [0, 0, 3]])) 23 | 24 | if not os.path.exists('test_gan.h5'): 25 | 26 | trajectory = io.generate_test_trajectory(self.structure, supercell=[3, 3, 3], total_time=8, silent=False) 27 | self.calculation = dynaphopy.Quasiparticle(trajectory) 28 | self.calculation.save_velocity_hdf5('test_gan.h5', save_trajectory=True) 29 | 30 | def test_adp(self): 31 | trajectory = io.initialize_from_hdf5_file('test_gan.h5', 32 | self.structure, 33 | read_trajectory=True, 34 | initial_cut=1, 35 | final_cut=4000, 36 | memmap=False) 37 | 38 | self.calculation = dynaphopy.Quasiparticle(trajectory) 39 | self.calculation.get_anisotropic_displacement_parameters() 40 | 41 | positions_average = self.calculation.dynamic.average_positions(to_unit_cell=True).real 42 | positions = self.structure.get_positions() 43 | difference = positions - positions_average 44 | 45 | norm = np.linalg.norm(self.structure.get_cell(), axis=1) 46 | difference = np.mod(difference, norm) 47 | multiples = np.divide(difference, norm) 48 | 49 | self.assertLess(np.max(np.abs(multiples - np.round(multiples))), 1e-4) 50 | 51 | def test_thermal_properties(self): 52 | trajectory = io.initialize_from_hdf5_file('test_gan.h5', 53 | self.structure, 54 | read_trajectory=False, 55 | initial_cut=1000, 56 | final_cut=4000, 57 | memmap=False) 58 | self.calculation = dynaphopy.Quasiparticle(trajectory) 59 | self.calculation.select_power_spectra_algorithm(2) 60 | harmonic = np.array(self.calculation.get_thermal_properties()) 61 | anharmonic = np.array(self.calculation.get_thermal_properties( 62 | force_constants=self.calculation.get_renormalized_force_constants())) 63 | 64 | print(harmonic) 65 | print(anharmonic) 66 | maximum = np.max((harmonic-anharmonic)**2/harmonic) 67 | print('maximum: {}'.format(maximum)) 68 | self.assertLess(maximum, 0.4) 69 | 70 | def test_force_constants_self_consistency(self): 71 | trajectory = io.initialize_from_hdf5_file('test_gan.h5', 72 | self.structure, 73 | read_trajectory=False, 74 | initial_cut=1, 75 | final_cut=3000, 76 | memmap=True) 77 | self.calculation = dynaphopy.Quasiparticle(trajectory) 78 | 79 | self.calculation.select_power_spectra_algorithm(2) 80 | renormalized_force_constants = self.calculation.get_renormalized_force_constants().get_array() 81 | harmonic_force_constants = self.calculation.dynamic.structure.get_force_constants().get_array() 82 | self.assertEqual(np.allclose(renormalized_force_constants, harmonic_force_constants, rtol=1, atol=1.e-2), True) 83 | 84 | def test_q_points_data(self): 85 | 86 | import yaml 87 | 88 | trajectory = io.initialize_from_hdf5_file('test_gan.h5', 89 | self.structure, 90 | read_trajectory=True, 91 | initial_cut=1, 92 | final_cut=3000, 93 | memmap=True) 94 | self.calculation = dynaphopy.Quasiparticle(trajectory) 95 | 96 | self.calculation.select_power_spectra_algorithm(2) 97 | self.calculation.write_atomic_displacements([0, 0, 1], 'atomic_displacements.dat') 98 | self.calculation.write_quasiparticles_data(filename='quasiparticles_data.yaml') 99 | self.calculation.write_renormalized_phonon_dispersion_bands(filename='bands_data.yaml') 100 | 101 | reference = np.loadtxt('GaN_data/atomic_displacements.dat') 102 | data = np.loadtxt('atomic_displacements.dat') 103 | test_range = np.arange(-5, 5, 0.1) 104 | 105 | for i in range(1, data.shape[1]): 106 | diff_square = np.square(np.interp(test_range, data[:,0], data[:,i], right=0, left=0) - 107 | np.interp(test_range, reference[:,0], reference[:,i], right=0, left=0)) 108 | rms = np.sqrt(np.average(diff_square)) 109 | self.assertLess(rms, 0.05) 110 | 111 | def assertDictAlmostEqual(dict, reference, decimal=6): 112 | for key, value in dict.items(): 113 | np.testing.assert_array_almost_equal(np.array(value), 114 | np.array(reference[key]), 115 | decimal=decimal) 116 | 117 | files = ['quasiparticles_data.yaml'] 118 | for file in files: 119 | print ('file: {}'.format(file)) 120 | with open(file) as stream: 121 | data = yaml.safe_load(stream) 122 | 123 | with open('GaN_data/' + file) as stream: 124 | reference = yaml.safe_load(stream) 125 | 126 | for dict_data, dict_reference in zip(data, reference): 127 | assertDictAlmostEqual(dict_data, dict_reference, decimal=1) 128 | 129 | if __name__ == '__main__': 130 | 131 | unittest.main() 132 | 133 | os.remove('test_gan.h5') 134 | os.remove('atomic_displacements.dat') 135 | os.remove('quasiparticles_data.yaml') 136 | os.remove('bands_data.yaml') -------------------------------------------------------------------------------- /unittest/MgO_data/POSCAR: -------------------------------------------------------------------------------- 1 | MgO 2 | 1.0 3 | 4.2119998932 0.0000000000 0.0000000000 4 | 0.0000000000 4.2119998932 0.0000000000 5 | 0.0000000000 0.0000000000 4.2119998932 6 | Mg O 7 | 4 4 8 | Direct 9 | 0.000000000 0.000000000 0.000000000 10 | 0.000000000 0.500000000 0.500000000 11 | 0.500000000 0.000000000 0.500000000 12 | 0.500000000 0.500000000 0.000000000 13 | 0.500000000 0.500000000 0.500000000 14 | 0.500000000 0.000000000 0.000000000 15 | 0.000000000 0.500000000 0.000000000 16 | 0.000000000 0.000000000 0.500000000 17 | -------------------------------------------------------------------------------- /unittest/MgO_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import numpy as np 3 | import dynaphopy.interface.iofile as io 4 | import dynaphopy 5 | from dynaphopy.interface.phonopy_link import get_force_constants_from_file 6 | 7 | import unittest 8 | 9 | 10 | class TestDynaphopy(unittest.TestCase): 11 | 12 | def setUp(self): 13 | structure = io.read_from_file_structure_poscar('MgO_data/POSCAR') 14 | 15 | structure.set_primitive_matrix([[0.0, 0.5, 0.5], 16 | [0.5, 0.0, 0.5], 17 | [0.5, 0.5, 0.0]]) 18 | 19 | structure.set_force_constants(get_force_constants_from_file(file_name='MgO_data/FORCE_CONSTANTS', 20 | fc_supercell=[[2, 0, 0], 21 | [0, 2, 0], 22 | [0, 0, 2]])) 23 | 24 | trajectory = io.generate_test_trajectory(structure, supercell=[2, 2, 2], total_time=5, silent=False) 25 | self.calculation = dynaphopy.Quasiparticle(trajectory) 26 | 27 | def test_force_constants_self_consistency(self): 28 | self.calculation.select_power_spectra_algorithm(2) 29 | renormalized_force_constants = self.calculation.get_renormalized_force_constants().get_array() 30 | harmonic_force_constants = self.calculation.dynamic.structure.get_force_constants().get_array() 31 | self.assertEqual(np.allclose(renormalized_force_constants, harmonic_force_constants, rtol=1, atol=1.e-2), True) 32 | 33 | 34 | if __name__ == '__main__': 35 | unittest.main() 36 | -------------------------------------------------------------------------------- /unittest/Si_data/POSCAR: -------------------------------------------------------------------------------- 1 | Si 2 | 1.0 3 | 5.4661639157319968 0.0000000000000000 0.0000000000000000 4 | 0.0000000000000000 5.4661639157319968 0.0000000000000000 5 | 0.0000000000000000 0.0000000000000000 5.4661639157319968 6 | 8 7 | Direct 8 | 0.8750000000000000 0.8750000000000000 0.8750000000000000 9 | 0.8750000000000000 0.3750000000000000 0.3750000000000000 10 | 0.3750000000000000 0.8750000000000000 0.3750000000000000 11 | 0.3750000000000000 0.3750000000000000 0.8750000000000000 12 | 0.1250000000000000 0.1250000000000000 0.1250000000000000 13 | 0.1250000000000000 0.6250000000000000 0.6250000000000000 14 | 0.6250000000000000 0.1250000000000000 0.6250000000000000 15 | 0.6250000000000000 0.6250000000000000 0.1250000000000000 16 | -------------------------------------------------------------------------------- /unittest/Si_data/atomic_displacements.dat: -------------------------------------------------------------------------------- 1 | -0.3592 6.0617720690e-03 1.0102953448e-02 2 | -0.3345 5.1525062586e-02 4.5463290517e-02 3 | -0.3097 7.7792741552e-02 1.1618396466e-01 4 | -0.2850 1.4548252965e-01 2.0963628405e-01 5 | -0.2603 2.5863560828e-01 2.7732607215e-01 6 | -0.2355 4.9959104802e-01 4.9504471896e-01 7 | -0.2108 7.8146344922e-01 7.7994800621e-01 8 | -0.1860 1.2133647091e+00 1.1274896048e+00 9 | -0.1613 1.6599152515e+00 1.6583998085e+00 10 | -0.1365 2.0978782835e+00 2.2362887458e+00 11 | -0.1118 2.7924563331e+00 2.7990232528e+00 12 | -0.0870 3.1864715176e+00 3.2036465384e+00 13 | -0.0623 3.6380735367e+00 3.4920858594e+00 14 | -0.0376 3.7522369107e+00 3.7047530295e+00 15 | -0.0128 3.6875780086e+00 3.7264743794e+00 16 | 0.0119 3.5814969974e+00 3.4759211339e+00 17 | 0.0367 3.2915422334e+00 3.2314296604e+00 18 | 0.0614 2.7141584439e+00 2.7555805530e+00 19 | 0.0862 2.2297218260e+00 2.2423505178e+00 20 | 0.1109 1.7740786255e+00 1.6922447026e+00 21 | 0.1357 1.1648705326e+00 1.1648705326e+00 22 | 0.1604 7.6883475741e-01 7.9106125500e-01 23 | 0.1852 4.7382851672e-01 5.2838446534e-01 24 | 0.2099 2.7379003845e-01 2.8641873026e-01 25 | 0.2346 1.7124506095e-01 1.8033771905e-01 26 | 0.2594 7.6277298534e-02 1.0658615888e-01 27 | 0.2841 2.6267678965e-02 4.0411813793e-02 28 | 0.3089 1.7175020862e-02 2.4247088276e-02 29 | 0.3336 0.0000000000e+00 4.5463290517e-03 30 | 0.3584 0.0000000000e+00 5.5566243965e-03 31 | -------------------------------------------------------------------------------- /unittest/Si_data/atomic_displacements_mem.dat: -------------------------------------------------------------------------------- 1 | -0.3887 5.8799922425e-03 3.9199948283e-03 2 | -0.3632 9.7999870708e-03 1.2249983838e-02 3 | -0.3376 2.4989967031e-02 2.1559971556e-02 4 | -0.3121 6.7619910788e-02 1.0730985843e-01 5 | -0.2866 1.3474982222e-01 1.8521975564e-01 6 | -0.2611 2.6655964833e-01 2.9203961471e-01 7 | -0.2356 5.0567933285e-01 4.5373940138e-01 8 | -0.2101 8.4769888162e-01 7.8301896696e-01 9 | -0.1846 1.1921684272e+00 1.1906984291e+00 10 | -0.1591 1.7247977245e+00 1.7007877561e+00 11 | -0.1336 2.2740869998e+00 2.1525671601e+00 12 | -0.1080 2.7199864115e+00 2.7983863081e+00 13 | -0.0825 3.2374257288e+00 3.3834455362e+00 14 | -0.0570 3.7945549938e+00 3.7078251082e+00 15 | -0.0315 3.8812848794e+00 3.8920648652e+00 16 | -0.0060 3.7254650850e+00 3.7970049906e+00 17 | 0.0195 3.4476354515e+00 3.3922655246e+00 18 | 0.0450 3.0972859137e+00 3.0223160126e+00 19 | 0.0705 2.5680866119e+00 2.5705366087e+00 20 | 0.0960 1.9531374232e+00 1.9575474174e+00 21 | 0.1215 1.4200181266e+00 1.4430480962e+00 22 | 0.1471 9.4667875104e-01 9.5157874457e-01 23 | 0.1726 6.2229917900e-01 5.9142921972e-01 24 | 0.1981 3.4005955136e-01 3.6553951774e-01 25 | 0.2236 1.7884976404e-01 2.1657971426e-01 26 | 0.2491 1.0681985907e-01 1.3278982481e-01 27 | 0.2746 6.3699915960e-02 5.2429930829e-02 28 | 0.3001 3.0379959919e-02 1.3719981899e-02 29 | 0.3256 8.8199883637e-03 5.8799922425e-03 30 | 0.3511 3.4299954748e-03 2.4499967677e-03 31 | -------------------------------------------------------------------------------- /unittest/Si_mem_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import unittest 3 | import os 4 | import numpy as np 5 | import dynaphopy.interface.iofile as io 6 | import dynaphopy 7 | from dynaphopy.interface.phonopy_link import get_force_constants_from_file 8 | 9 | 10 | class TestDynaphopy(unittest.TestCase): 11 | 12 | def setUp(self): 13 | import phonopy 14 | print ('Using phonopy {}'.format(phonopy.__version__)) 15 | 16 | # structure = io.read_from_file_structure_poscar('Si_data/POSCAR') 17 | self.structure = io.read_from_file_structure_outcar('Si_data/OUTCAR') 18 | 19 | self.structure.set_primitive_matrix([[0.0, 0.5, 0.5], 20 | [0.5, 0.0, 0.5], 21 | [0.5, 0.5, 0.0]]) 22 | 23 | self.structure.set_force_constants(get_force_constants_from_file(file_name='Si_data/FORCE_CONSTANTS', 24 | fc_supercell=[[2, 0, 0], 25 | [0, 2, 0], 26 | [0, 0, 2]])) 27 | 28 | def test_force_constants_self_consistency(self): 29 | trajectory = io.generate_test_trajectory(self.structure, supercell=[2, 2, 2], total_time=10, silent=False) 30 | calculation = dynaphopy.Quasiparticle(trajectory) 31 | calculation.select_power_spectra_algorithm(2) 32 | renormalized_force_constants = calculation.get_renormalized_force_constants().get_array() 33 | harmonic_force_constants = calculation.dynamic.structure.get_force_constants().get_array() 34 | calculation.get_thermal_properties() 35 | 36 | self.assertEqual(np.allclose(renormalized_force_constants, harmonic_force_constants, rtol=1, atol=1.e-2), True) 37 | 38 | def _test_q_points_data(self): 39 | 40 | import yaml 41 | trajectory = io.generate_test_trajectory(self.structure, supercell=[2, 2, 2], total_time=5, silent=False) 42 | calculation = dynaphopy.Quasiparticle(trajectory) 43 | calculation.select_power_spectra_algorithm(1) 44 | calculation.write_atomic_displacements([0, 0, 1], 'atomic_displacements_mem.dat') 45 | calculation.write_quasiparticles_data(filename='quasiparticles_data_mem.yaml') 46 | calculation.write_renormalized_phonon_dispersion_bands(filename='bands_data_mem.yaml') 47 | 48 | reference = np.loadtxt('Si_data/atomic_displacements_mem.dat') 49 | data = np.loadtxt('atomic_displacements_mem.dat') 50 | test_range = np.arange(-5, 5, 0.1) 51 | 52 | for i in range(1, data.shape[1]): 53 | diff_square = np.square(np.interp(test_range, data[:,0], data[:,i], right=0, left=0) - 54 | np.interp(test_range, reference[:,0], reference[:,i], right=0, left=0)) 55 | rms = np.sqrt(np.average(diff_square)) 56 | self.assertLess(rms, 0.05) 57 | 58 | def assertDictAlmostEqual(dict, reference, decimal=6): 59 | for key, value in dict.items(): 60 | np.testing.assert_array_almost_equal(np.array(value), 61 | np.array(reference[key]), 62 | decimal=decimal) 63 | 64 | files = ['quasiparticles_data_mem.yaml'] 65 | for file in files: 66 | print('file: {}'.format(file)) 67 | with open(file) as stream: 68 | data = yaml.safe_load(stream) 69 | 70 | with open('Si_data/' + file) as stream: 71 | reference = yaml.safe_load(stream) 72 | 73 | for dict_data, dict_reference in zip(data, reference): 74 | assertDictAlmostEqual(dict_data, dict_reference, decimal=1) 75 | 76 | 77 | if __name__ == '__main__': 78 | 79 | unittest.main() 80 | 81 | os.remove('atomic_displacements_mem.dat') 82 | os.remove('quasiparticles_data_mem.yaml') 83 | os.remove('bands_data_mem.yaml') -------------------------------------------------------------------------------- /unittest/Si_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import unittest 3 | import os 4 | import numpy as np 5 | import dynaphopy.interface.iofile as io 6 | import dynaphopy 7 | from dynaphopy.interface.phonopy_link import get_force_constants_from_file 8 | 9 | 10 | class TestDynaphopy(unittest.TestCase): 11 | 12 | def setUp(self): 13 | import phonopy 14 | print ('Using phonopy {}'.format(phonopy.__version__)) 15 | 16 | # structure = io.read_from_file_structure_poscar('Si_data/POSCAR') 17 | self.structure = io.read_from_file_structure_outcar('Si_data/OUTCAR') 18 | 19 | self.structure.set_primitive_matrix([[0.0, 0.5, 0.5], 20 | [0.5, 0.0, 0.5], 21 | [0.5, 0.5, 0.0]]) 22 | 23 | self.structure.set_force_constants(get_force_constants_from_file(file_name='Si_data/FORCE_CONSTANTS', 24 | fc_supercell=[[2, 0, 0], 25 | [0, 2, 0], 26 | [0, 0, 2]])) 27 | 28 | def test_force_constants_self_consistency(self): 29 | trajectory = io.generate_test_trajectory(self.structure, supercell=[2, 2, 2], total_time=10, silent=False) 30 | calculation = dynaphopy.Quasiparticle(trajectory) 31 | calculation.select_power_spectra_algorithm(2) 32 | renormalized_force_constants = calculation.get_renormalized_force_constants().get_array() 33 | harmonic_force_constants = calculation.dynamic.structure.get_force_constants().get_array() 34 | calculation.get_thermal_properties() 35 | 36 | self.assertEqual(np.allclose(renormalized_force_constants, harmonic_force_constants, rtol=1, atol=1.e-2), True) 37 | 38 | def test_q_points_data(self): 39 | 40 | import yaml 41 | trajectory = io.generate_test_trajectory(self.structure, supercell=[2, 2, 2], total_time=5, silent=False) 42 | calculation = dynaphopy.Quasiparticle(trajectory) 43 | calculation.select_power_spectra_algorithm(2) 44 | calculation.write_atomic_displacements([0, 0, 1], 'atomic_displacements.dat') 45 | calculation.write_quasiparticles_data(filename='quasiparticles_data.yaml') 46 | calculation.write_renormalized_phonon_dispersion_bands(filename='bands_data.yaml') 47 | 48 | reference = np.loadtxt('Si_data/atomic_displacements.dat') 49 | data = np.loadtxt('atomic_displacements.dat') 50 | test_range = np.arange(-5, 5, 0.1) 51 | 52 | for i in range(1, data.shape[1]): 53 | diff_square = np.square(np.interp(test_range, data[:,0], data[:,i], right=0, left=0) - 54 | np.interp(test_range, reference[:,0], reference[:,i], right=0, left=0)) 55 | rms = np.sqrt(np.average(diff_square)) 56 | self.assertLess(rms, 0.05) 57 | 58 | def assertDictAlmostEqual(dict, reference, decimal=6): 59 | for key, value in dict.items(): 60 | np.testing.assert_array_almost_equal(np.array(value), 61 | np.array(reference[key]), 62 | decimal=decimal) 63 | 64 | files = ['quasiparticles_data.yaml'] 65 | for file in files: 66 | print('file: {}'.format(file)) 67 | with open(file) as stream: 68 | data = yaml.safe_load(stream) 69 | 70 | with open('Si_data/' + file) as stream: 71 | reference = yaml.safe_load(stream) 72 | 73 | for dict_data, dict_reference in zip(data, reference): 74 | assertDictAlmostEqual(dict_data, dict_reference, decimal=1) 75 | 76 | 77 | if __name__ == '__main__': 78 | 79 | unittest.main() 80 | 81 | os.remove('atomic_displacements.dat') 82 | os.remove('quasiparticles_data.yaml') 83 | os.remove('bands_data.yaml') -------------------------------------------------------------------------------- /unittest/reading_test.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import numpy as np 3 | import dynaphopy.interface.iofile as io 4 | from dynaphopy.interface.phonopy_link import get_force_constants_from_file 5 | 6 | import unittest 7 | 8 | 9 | class TestDynaphopy(unittest.TestCase): 10 | 11 | def setUp(self): 12 | self.structure = io.read_from_file_structure_poscar('Si_data/POSCAR') 13 | 14 | self.structure.set_primitive_matrix([[0.0, 0.5, 0.5], 15 | [0.5, 0.0, 0.5], 16 | [0.5, 0.5, 0.0]]) 17 | 18 | self.structure.set_force_constants(get_force_constants_from_file(file_name='Si_data/FORCE_CONSTANTS', 19 | fc_supercell=[[2, 0, 0], 20 | [0, 2, 0], 21 | [0, 0, 2]])) 22 | 23 | def test_XDATCAR(self): 24 | defined_time_step = 0.0005 25 | parser = io.get_trajectory_parser('Si_data/XDATCAR') 26 | template = io.check_atoms_order('Si_data/XDATCAR', parser, self.structure) 27 | 28 | trajectory = parser('Si_data/XDATCAR', self.structure, 29 | initial_cut=3, end_cut=14, time_step=defined_time_step, template=template) 30 | 31 | rel_traj_ref = [[ 3.83203119e-09, 1.41927075e-09, 1.70312506e-09], 32 | [ 4.25781249e-10, 3.12239576e-09, 5.10937512e-09], 33 | [-1.27734381e-09, -3.69010421e-09, 3.40625005e-09], 34 | [-1.27734384e-09, 4.82552079e-09, -5.10937504e-09], 35 | [-4.68359383e-09, 4.82552082e-09, 5.10937504e-09], 36 | [ 4.25781233e-10, -2.83854171e-10, -6.81249987e-09], 37 | [-2.98046880e-09, -8.79947915e-09, -3.40625001e-09], 38 | [ 2.12890625e-09, -1.98697915e-09, 6.24500451e-17], 39 | [ 2.12890630e-09, -2.83854242e-10, 1.00613962e-16], 40 | [ 3.83203120e-09, 1.41927079e-09, 3.46944695e-17], 41 | [ 2.12890631e-09, 3.12239582e-09, 3.40625004e-09], 42 | [-4.68359377e-09, -3.69010417e-09, -3.40624993e-09]] 43 | 44 | rel_traj = np.array([np.average(trajectory.average_positions().real - traj, axis=0).real 45 | for traj in trajectory.trajectory]) 46 | 47 | # print(rel_traj) 48 | check_traj = np.allclose(rel_traj_ref, rel_traj, rtol=1e-6, atol=1.e-18) 49 | print('trajectory:', check_traj) 50 | 51 | check_time = trajectory.get_time_step_average() == defined_time_step 52 | print('time:', check_time) 53 | 54 | mean_matrix_ref = [[ 0.00065253, 0.00016701, 0.00033313], 55 | [ 0.00016701, 0.00063413, 0.00023646], 56 | [ 0.00033313, 0.00023646, 0.00072747]] 57 | 58 | mean_matrix = np.average(trajectory.get_mean_displacement_matrix(), axis=0) 59 | 60 | check_mean_matrix = np.allclose(mean_matrix, mean_matrix_ref, rtol=1e-3, atol=1.e-6) 61 | print('mean matrix:', check_mean_matrix) 62 | 63 | self.assertEqual(check_traj and check_time and check_mean_matrix, True) 64 | 65 | def test_lammpstraj(self): 66 | defined_time_step = 0.001 67 | parser = io.get_trajectory_parser('Si_data/si.lammpstrj') 68 | 69 | trajectory = parser('Si_data/si.lammpstrj', self.structure, 70 | initial_cut=3, end_cut=14, time_step=defined_time_step) 71 | 72 | rel_traj_ref = [[-3.51562529e-12, -1.82290120e-12, 2.99481620e-12], 73 | [-3.90621563e-13, 4.42701258e-12, -1.30178854e-13], 74 | [ 2.73439431e-12, -3.38547246e-12, 4.55729551e-12], 75 | [-3.90609420e-13, -2.60453117e-13, -4.81767751e-12], 76 | [ 4.29688403e-12, 2.86455235e-12, -1.30132016e-13], 77 | [-1.95310261e-12, -9.63547298e-12, 2.99480753e-12], 78 | [ 1.17189591e-12, 2.86454020e-12, -3.25514442e-12], 79 | [-3.90574725e-13, -2.60357708e-13, 1.43223974e-12], 80 | [ 2.73435614e-12, -2.60437505e-13, -4.81760118e-12], 81 | [ 5.85947263e-12, -1.82294110e-12, -1.69266164e-12], 82 | [-5.07803868e-12, 4.42703513e-12, 1.43230393e-12], 83 | [-5.07806297e-12, 2.86455755e-12, 1.43231781e-12]] 84 | 85 | rel_traj = np.array([np.average(trajectory.average_positions().real - traj, axis=0).real 86 | for traj in trajectory.trajectory]) 87 | 88 | check_traj = np.allclose(rel_traj_ref, rel_traj, rtol=1e-6, atol=1.e-18) 89 | print('trajectory:', check_traj) 90 | 91 | check_time = float(trajectory.get_time_step_average()) == float(defined_time_step) 92 | print('time:', check_time) 93 | 94 | mean_matrix_ref = [[ 0.00263396, 0.00053198, 0.00040298], 95 | [ 0.00053198, 0.00383308, 0.00034559], 96 | [ 0.00040298, 0.00034559, 0.00381229]] 97 | 98 | mean_matrix = np.average(trajectory.get_mean_displacement_matrix(), axis=0) 99 | check_mean_matrix = np.allclose(mean_matrix, mean_matrix_ref, rtol=1e-3, atol=1.e-6) 100 | print('mean matrix:', check_mean_matrix) 101 | 102 | self.assertEqual(check_traj and check_time and check_mean_matrix, True) 103 | 104 | 105 | if __name__ == '__main__': 106 | unittest.main() 107 | --------------------------------------------------------------------------------