mirror of https://github.com/phonopy/phonopy.git
Merge branch 'rc'
This commit is contained in:
commit
64ea303dd2
12
.travis.yml
12
.travis.yml
|
@ -8,14 +8,20 @@ python:
|
|||
- '3.6'
|
||||
|
||||
before_install:
|
||||
- TRAVIS_PYTHON_VERSION=`python --version |& awk '{print $2}'|awk -F'.' '{print $1"."$2}'`
|
||||
- wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
|
||||
#- TRAVIS_PYTHON_VERSION=`python --version |& awk '{print $2}'|awk -F'.' '{print $1"."$2}'`
|
||||
# - wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
|
||||
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
|
||||
wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
else
|
||||
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
fi
|
||||
- echo $TRAVIS_PYTHON_VERSION
|
||||
- bash miniconda.sh -b -p $HOME/miniconda
|
||||
- export PATH="$HOME/miniconda/bin:$PATH"
|
||||
- conda update --yes conda
|
||||
|
||||
install:
|
||||
- conda install --yes python=$TRAVIS_PYTHON_VERSION pip numpy h5py pyyaml matplotlib
|
||||
- conda install --yes python=$TRAVIS_PYTHON_VERSION pip numpy h5py pyyaml matplotlib setuptools setuptools_scm
|
||||
- pwd
|
||||
- ./get_nanoversion.sh
|
||||
- cat __nanoversion__.txt
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
0
|
323
c/_phonopy.c
323
c/_phonopy.c
|
@ -34,6 +34,7 @@
|
|||
|
||||
#include <Python.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <numpy/arrayobject.h>
|
||||
#include <dynmat.h>
|
||||
#include <derivative_dynmat.h>
|
||||
|
@ -50,16 +51,17 @@ static PyObject * py_get_dipole_dipole(PyObject *self, PyObject *args);
|
|||
static PyObject * py_get_derivative_dynmat(PyObject *self, PyObject *args);
|
||||
static PyObject * py_get_thermal_properties(PyObject *self, PyObject *args);
|
||||
static PyObject * py_distribute_fc2(PyObject *self, PyObject *args);
|
||||
static PyObject * py_distribute_fc2_all(PyObject *self, PyObject *args);
|
||||
|
||||
static int distribute_fc2(double * fc2,
|
||||
const double * lat,
|
||||
const double * pos,
|
||||
static int distribute_fc2(double *fc2,
|
||||
PHPYCONST double lat[3][3],
|
||||
PHPYCONST double (*pos)[3],
|
||||
const int num_pos,
|
||||
const int atom_disp,
|
||||
const int map_atom_disp,
|
||||
const double * r_cart,
|
||||
const int * r,
|
||||
const double * t,
|
||||
PHPYCONST double r_cart[3][3],
|
||||
PHPYCONST int r[3][3],
|
||||
const double t[3],
|
||||
const double symprec);
|
||||
static PyObject * py_thm_neighboring_grid_points(PyObject *self, PyObject *args);
|
||||
static PyObject *
|
||||
|
@ -80,6 +82,13 @@ static double get_entropy_omega(const double temperature,
|
|||
static double get_heat_capacity_omega(const double temperature,
|
||||
const double omega);
|
||||
/* static double get_energy_omega(double temperature, double omega); */
|
||||
static int check_overlap(PHPYCONST double (*pos)[3],
|
||||
const int num_pos,
|
||||
const double pos_orig[3],
|
||||
PHPYCONST double lat[3][3],
|
||||
PHPYCONST int r[3][3],
|
||||
const double t[3],
|
||||
const double symprec);
|
||||
static int nint(const double a);
|
||||
|
||||
struct module_state {
|
||||
|
@ -108,6 +117,8 @@ static PyMethodDef _phonopy_methods[] = {
|
|||
{"derivative_dynmat", py_get_derivative_dynmat, METH_VARARGS, "Q derivative of dynamical matrix"},
|
||||
{"thermal_properties", py_get_thermal_properties, METH_VARARGS, "Thermal properties"},
|
||||
{"distribute_fc2", py_distribute_fc2, METH_VARARGS, "Distribute force constants"},
|
||||
{"distribute_fc2_all", py_distribute_fc2_all, METH_VARARGS,
|
||||
"Distribute force constants for all atoms in atom_list"},
|
||||
{"neighboring_grid_points", py_thm_neighboring_grid_points,
|
||||
METH_VARARGS, "Neighboring grid points by relative grid addresses"},
|
||||
{"tetrahedra_relative_grid_address", py_thm_relative_grid_address,
|
||||
|
@ -613,43 +624,43 @@ static double get_heat_capacity_omega(const double temperature,
|
|||
|
||||
static PyObject * py_distribute_fc2(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyArrayObject* force_constants;
|
||||
PyArrayObject* lattice;
|
||||
PyArrayObject* positions;
|
||||
PyArrayObject* rotation;
|
||||
PyArrayObject* rotation_cart;
|
||||
PyArrayObject* translation;
|
||||
PyArrayObject* force_constants_py;
|
||||
PyArrayObject* lattice_py;
|
||||
PyArrayObject* positions_py;
|
||||
PyArrayObject* rotation_py;
|
||||
PyArrayObject* rotation_cart_py;
|
||||
PyArrayObject* translation_py;
|
||||
int atom_disp, map_atom_disp;
|
||||
double symprec;
|
||||
|
||||
int* r;
|
||||
double* r_cart;
|
||||
double* fc2;
|
||||
double* t;
|
||||
double* lat;
|
||||
double* pos;
|
||||
int (*r)[3];
|
||||
double (*r_cart)[3];
|
||||
double *fc2;
|
||||
double *t;
|
||||
double (*lat)[3];
|
||||
double (*pos)[3];
|
||||
int num_pos;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OOOiiOOOd",
|
||||
&force_constants,
|
||||
&lattice,
|
||||
&positions,
|
||||
&atom_disp,
|
||||
&map_atom_disp,
|
||||
&rotation_cart,
|
||||
&rotation,
|
||||
&translation,
|
||||
&symprec)) {
|
||||
&force_constants_py,
|
||||
&lattice_py,
|
||||
&positions_py,
|
||||
&atom_disp,
|
||||
&map_atom_disp,
|
||||
&rotation_cart_py,
|
||||
&rotation_py,
|
||||
&translation_py,
|
||||
&symprec)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = (int*)PyArray_DATA(rotation);
|
||||
r_cart = (double*)PyArray_DATA(rotation_cart);
|
||||
fc2 = (double*)PyArray_DATA(force_constants);
|
||||
t = (double*)PyArray_DATA(translation);
|
||||
lat = (double*)PyArray_DATA(lattice);
|
||||
pos = (double*)PyArray_DATA(positions);
|
||||
num_pos = PyArray_DIMS(positions)[0];
|
||||
r = (int(*)[3])PyArray_DATA(rotation_py);
|
||||
r_cart = (double(*)[3])PyArray_DATA(rotation_cart_py);
|
||||
fc2 = (double*)PyArray_DATA(force_constants_py);
|
||||
t = (double*)PyArray_DATA(translation_py);
|
||||
lat = (double(*)[3])PyArray_DATA(lattice_py);
|
||||
pos = (double(*)[3])PyArray_DATA(positions_py);
|
||||
num_pos = PyArray_DIMS(positions_py)[0];
|
||||
|
||||
distribute_fc2(fc2,
|
||||
lat,
|
||||
|
@ -665,79 +676,96 @@ static PyObject * py_distribute_fc2(PyObject *self, PyObject *args)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int distribute_fc2(double * fc2,
|
||||
const double * lat,
|
||||
const double * pos,
|
||||
const int num_pos,
|
||||
const int atom_disp,
|
||||
const int map_atom_disp,
|
||||
const double * r_cart,
|
||||
const int * r,
|
||||
const double * t,
|
||||
const double symprec)
|
||||
static PyObject * py_distribute_fc2_all(PyObject *self, PyObject *args)
|
||||
{
|
||||
int i, j, k, l, m, address_new, address;
|
||||
int is_found, rot_atom;
|
||||
double distance2, symprec2, diff_cart;
|
||||
double rot_pos[3], diff[3];
|
||||
PyArrayObject* force_constants_py;
|
||||
PyArrayObject* lattice_py;
|
||||
PyArrayObject* positions_py;
|
||||
PyArrayObject* atom_list_py;
|
||||
PyArrayObject* atom_list_done_py;
|
||||
PyArrayObject* rotations_py;
|
||||
PyArrayObject* rotations_cart_py;
|
||||
PyArrayObject* translations_py;
|
||||
double symprec;
|
||||
|
||||
symprec2 = symprec * symprec;
|
||||
int (*r)[3][3];
|
||||
int *atom_list;
|
||||
int *atom_list_done;
|
||||
double (*r_cart)[3][3];
|
||||
double *fc2;
|
||||
double (*t)[3];
|
||||
double (*lat)[3];
|
||||
double (*pos)[3];
|
||||
double (*pos_done)[3];
|
||||
int num_pos, num_rot, len_atom_list, len_atom_list_done, map_atom_disp;
|
||||
int i, j;
|
||||
|
||||
is_found = 1;
|
||||
for (i = 0; i < num_pos; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
rot_pos[j] = t[j];
|
||||
for (k = 0; k < 3; k++) {
|
||||
rot_pos[j] += r[j * 3 + k] * pos[i * 3 + k];
|
||||
}
|
||||
}
|
||||
|
||||
rot_atom = -1;
|
||||
for (j = 0; j < num_pos; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
diff[k] = pos[j * 3 + k] - rot_pos[k];
|
||||
diff[k] -= nint(diff[k]);
|
||||
}
|
||||
distance2 = 0;
|
||||
for (k = 0; k < 3; k++) {
|
||||
diff_cart = 0;
|
||||
for (l = 0; l < 3; l++) {
|
||||
diff_cart += lat[k * 3 + l] * diff[l];
|
||||
}
|
||||
distance2 += diff_cart * diff_cart;
|
||||
}
|
||||
|
||||
if (distance2 < symprec2) {
|
||||
rot_atom = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rot_atom < 0) {
|
||||
printf("Encounter some problem in distribute_fc2.\n");
|
||||
is_found = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* R^-1 P R */
|
||||
address = map_atom_disp * num_pos * 9 + rot_atom * 9;
|
||||
address_new = atom_disp * num_pos * 9 + i * 9;
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
for (m = 0; m < 3; m++) {
|
||||
fc2[address_new + j * 3 + k] +=
|
||||
r_cart[l * 3 + j] * r_cart[m * 3 + k] *
|
||||
fc2[address + l * 3 + m];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
;
|
||||
if (!PyArg_ParseTuple(args, "OOOOOOOOd",
|
||||
&force_constants_py,
|
||||
&lattice_py,
|
||||
&positions_py,
|
||||
&atom_list_py,
|
||||
&atom_list_done_py,
|
||||
&rotations_cart_py,
|
||||
&rotations_py,
|
||||
&translations_py,
|
||||
&symprec)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return is_found;
|
||||
atom_list = (int*)PyArray_DATA(atom_list_py);
|
||||
len_atom_list = PyArray_DIMS(atom_list_py)[0];
|
||||
atom_list_done = (int*)PyArray_DATA(atom_list_done_py);
|
||||
len_atom_list_done = PyArray_DIMS(atom_list_done_py)[0];
|
||||
r = (int(*)[3][3])PyArray_DATA(rotations_py);
|
||||
num_rot = PyArray_DIMS(rotations_py)[0];
|
||||
r_cart = (double(*)[3][3])PyArray_DATA(rotations_cart_py);
|
||||
fc2 = (double*)PyArray_DATA(force_constants_py);
|
||||
t = (double(*)[3])PyArray_DATA(translations_py);
|
||||
lat = (double(*)[3])PyArray_DATA(lattice_py);
|
||||
pos = (double(*)[3])PyArray_DATA(positions_py);
|
||||
num_pos = PyArray_DIMS(positions_py)[0];
|
||||
|
||||
pos_done = (double(*)[3])malloc(sizeof(double[3]) * len_atom_list_done);
|
||||
for (i = 0; i < len_atom_list_done; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
pos_done[i][j] = pos[atom_list_done[i]][j];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma omp parallel for private(j)
|
||||
for (i = 0; i < len_atom_list; i++) {
|
||||
for (j = 0; j < num_rot; j++) {
|
||||
map_atom_disp = check_overlap(pos_done,
|
||||
len_atom_list_done,
|
||||
pos[atom_list[i]],
|
||||
lat,
|
||||
r[j],
|
||||
t[j],
|
||||
symprec);
|
||||
if (map_atom_disp > -1) {
|
||||
distribute_fc2(fc2,
|
||||
lat,
|
||||
pos,
|
||||
num_pos,
|
||||
atom_list[i],
|
||||
atom_list_done[map_atom_disp],
|
||||
r_cart[j],
|
||||
r[j],
|
||||
t[j],
|
||||
symprec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == num_rot) {
|
||||
printf("Input forces are not enough to calculate force constants,\n");
|
||||
printf("or something wrong (e.g. crystal structure does not match).\n");
|
||||
printf("%d, %d\n", i, j);
|
||||
}
|
||||
}
|
||||
|
||||
free(pos_done);
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *py_thm_neighboring_grid_points(PyObject *self, PyObject *args)
|
||||
|
@ -1083,6 +1111,97 @@ static PyObject * py_tetrahedron_method_dos(PyObject *self, PyObject *args)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static int distribute_fc2(double *fc2,
|
||||
PHPYCONST double lat[3][3],
|
||||
PHPYCONST double (*pos)[3],
|
||||
const int num_pos,
|
||||
const int atom_disp,
|
||||
const int map_atom_disp,
|
||||
PHPYCONST double r_cart[3][3],
|
||||
PHPYCONST int r[3][3],
|
||||
const double t[3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j, k, l, m, address_new, address;
|
||||
int is_found, rot_atom;
|
||||
|
||||
is_found = 1;
|
||||
for (i = 0; i < num_pos; i++) {
|
||||
rot_atom = check_overlap(pos,
|
||||
num_pos,
|
||||
pos[i],
|
||||
lat,
|
||||
r,
|
||||
t,
|
||||
symprec);
|
||||
|
||||
if (rot_atom < 0) {
|
||||
printf("Encounter some problem in distribute_fc2.\n");
|
||||
is_found = 0;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* R^-1 P R */
|
||||
address = map_atom_disp * num_pos * 9 + rot_atom * 9;
|
||||
address_new = atom_disp * num_pos * 9 + i * 9;
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
for (m = 0; m < 3; m++) {
|
||||
fc2[address_new + j * 3 + k] +=
|
||||
r_cart[l][j] * r_cart[m][k] *
|
||||
fc2[address + l * 3 + m];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
return is_found;
|
||||
}
|
||||
|
||||
static int check_overlap(PHPYCONST double (*pos)[3],
|
||||
const int num_pos,
|
||||
const double pos_orig[3],
|
||||
PHPYCONST double lat[3][3],
|
||||
PHPYCONST int r[3][3],
|
||||
const double t[3],
|
||||
const double symprec)
|
||||
{
|
||||
int i, j, k;
|
||||
double diff[3], rot_pos[3];
|
||||
double diff_cart, distance2;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
rot_pos[i] = t[i];
|
||||
for (j = 0; j < 3; j++) {
|
||||
rot_pos[i] += r[i][j] * pos_orig[j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_pos; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
diff[j] = pos[i][j] - rot_pos[j];
|
||||
diff[j] -= nint(diff[j]);
|
||||
}
|
||||
distance2 = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
diff_cart = 0;
|
||||
for (k = 0; k < 3; k++) {
|
||||
diff_cart += lat[j][k] * diff[k];
|
||||
}
|
||||
distance2 += diff_cart * diff_cart;
|
||||
}
|
||||
|
||||
if (sqrt(distance2) < symprec) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int nint(const double a)
|
||||
{
|
||||
if (a < 0.0)
|
||||
|
|
|
@ -31,6 +31,8 @@ requirements:
|
|||
- matplotlib
|
||||
- pyyaml
|
||||
- h5py
|
||||
- setuptools
|
||||
- setuptools_scm
|
||||
|
||||
run:
|
||||
- python
|
||||
|
|
|
@ -7,33 +7,28 @@ Installation using MacPorts
|
|||
----------------------------
|
||||
|
||||
This is one way to install phonopy on Mac OS X. This procedure was
|
||||
tested on Yosemite with MacPorts version 2.4.1. In the following case,
|
||||
gcc-6 and python-2.7 are used as the default C-compiler and python
|
||||
and using these numpy and scipy are made.
|
||||
tested on Sierra with MacPorts version 2.4.1. In the following case,
|
||||
gcc-7 is used as the default C-compiler.
|
||||
|
||||
1) Install MacPorts. Download MacPorts from http://www.macports.org/
|
||||
and follow the installation instruction.
|
||||
|
||||
2) Install the following packages
|
||||
2) Install ``gcc`` by
|
||||
|
||||
::
|
||||
|
||||
% sudo port install gcc6
|
||||
% sudo port select --set gcc mp-gcc6
|
||||
% sudo port install OpenBLAS +gcc6
|
||||
% sudo port install python27
|
||||
% sudo port select --set python python27
|
||||
% sudo port install py27-numpy +gcc6 +openblas
|
||||
% sudo port install py27-scipy +gcc6 +openblas
|
||||
% sudo port install py27-matplotlib py27-yaml
|
||||
% sudo port install py27-h5py +gcc6
|
||||
% sudo port install gcc7
|
||||
% sudo port select --set gcc mp-gcc7
|
||||
|
||||
3) Install phonopy following :ref:`install` (step 1 can be omitted.)
|
||||
3) Install necessary python libraries by conda::
|
||||
|
||||
Before running setup.py, gcc can be used as the C-compiler instead
|
||||
of clang for compiling phonopy C-extension as follows,
|
||||
% conda install numpy scipy h5py pyyaml matplotlib
|
||||
|
||||
::
|
||||
4) Install phonopy following :ref:`install_setup_py`.
|
||||
|
||||
Before running setup.py, the environment variable of ``CC=gcc`` is
|
||||
set so that gcc can be used as the C-compiler instead
|
||||
of clang for compiling phonopy C-extension as follows::
|
||||
|
||||
% export CC=gcc
|
||||
% python setup.py install --user
|
||||
|
|
111
doc/install.rst
111
doc/install.rst
|
@ -1,6 +1,6 @@
|
|||
.. _install:
|
||||
|
||||
Download and install
|
||||
Installation
|
||||
=====================
|
||||
|
||||
.. contents::
|
||||
|
@ -58,6 +58,8 @@ follows::
|
|||
|
||||
% conda install numpy scipy h5py pyyaml matplotlib
|
||||
|
||||
.. _install_setup_py:
|
||||
|
||||
Building using setup.py
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -72,27 +74,39 @@ needed.
|
|||
|
||||
and extract it::
|
||||
|
||||
% tar xvfz phonopy-1.11.2.tar.gz
|
||||
% tar xvfz phonopy-1.11.12.31.tar.gz
|
||||
% cd phonopy-1.11.12.31
|
||||
|
||||
The other option is using git to clone the phonopy repository from github::
|
||||
|
||||
% git clone https://github.com/atztogo/phonopy.git
|
||||
% cd phonopy
|
||||
|
||||
2. Set up C-libraries for python C-API and python codes. This can be
|
||||
done as follows:
|
||||
|
||||
Run ``setup.py`` script::
|
||||
|
||||
% python setup.py install --home=<my-directory>
|
||||
|
||||
where :file:`{<my-directory>}` may be your current directory, :file:`.`.
|
||||
Another choice may be to use the user scheme (see the python document)::
|
||||
|
||||
% python setup.py install --user
|
||||
|
||||
The executable command ``phonopy`` is located in the ``bin`` directory.
|
||||
Watching carefully where the phonopy commands and library are
|
||||
installed. Those locations can be ``~/.local/bin`` and
|
||||
``~/.local/lib`` directories, respectively.
|
||||
|
||||
3. Put ``lib/python`` path into :envvar:`$PYTHONPATH`, e.g., in your
|
||||
.bashrc, .zshenv, etc. If it is installed under your current
|
||||
directory, the path to be added to :envvar:`$PYTHONPATH` is such as below::
|
||||
3. Assuming the installation location is those shown in the step 2,
|
||||
set :envvar:`$PATH` and :envvar:`$PYTHONPATH`::
|
||||
|
||||
export PYTHONPATH=~/.local/lib:$PYTHONPATH
|
||||
export PYTH=~/.local/bin:$PATH
|
||||
|
||||
or if ``PYTHONPATH`` is not yet set in your system::
|
||||
|
||||
export PYTHONPATH=~/.local/lib
|
||||
export PYTH=~/.local/bin:$PATH
|
||||
|
||||
in your ``.bashrc`` (or maybe ``.bash_profile``), ``.zshenv``, or
|
||||
other script for the other shells.
|
||||
|
||||
export PYTHONPATH=~/phonopy-1.11.2/lib/python
|
||||
|
||||
Tips on setup.py installation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -103,6 +117,8 @@ Tips on setup.py installation
|
|||
MacOSX
|
||||
virtualmachine
|
||||
|
||||
.. _install_conda:
|
||||
|
||||
conda
|
||||
------
|
||||
|
||||
|
@ -139,4 +155,75 @@ e.g.,::
|
|||
|
||||
sudo apt-get install python-dev
|
||||
|
||||
.. _install_trouble_shooting:
|
||||
|
||||
|
||||
Multithreading support
|
||||
-----------------------
|
||||
|
||||
Two kinds of multithreadings can be used in phonopy.
|
||||
|
||||
1. Multithreaded BLAS linked numpy
|
||||
|
||||
Phonopy uses numpy to run singular value decomposition in the
|
||||
calculation of force constants and diagonalizaion of dynamical
|
||||
matrices. For these, numpy internally calls the LAPACK
|
||||
routines. Therefore if a user installs a numpy that is linked with
|
||||
multithreaded BLAS, these parts are multithreaded. For example, MKL
|
||||
linked numpy is easily installed using conda.
|
||||
|
||||
2. OpenMP support in phonopy and spglib
|
||||
|
||||
OpenMP are applied in the symmetry finding of spglib and the
|
||||
distribution of symmetry reduced force constants elements to full
|
||||
force constants elements in phonopy. When a chosen supercell is
|
||||
very large and there are many cores on a computer, these parts may
|
||||
work well to reduce the computational time. In the default phonopy
|
||||
setting, this is not activated. To enable this, it is necessary to
|
||||
build phonopy using modified ``setup.py`` in which ``with_openmp =
|
||||
False`` must be changed to ``with_openmp = True``. For this,
|
||||
currently only gcc is supported.
|
||||
|
||||
Trouble shooting
|
||||
-----------------
|
||||
|
||||
Remove previous phonopy installations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes previous installations of phonopy prevent from loading newly
|
||||
installed phonopy. In this case, it is recommended to uninstall all
|
||||
the older phonopy packages by
|
||||
|
||||
1. Running ``pip uninstall phonopy`` as many times as no phonopy
|
||||
packages will be found. Error message may be shown, but don't mind
|
||||
it. Similarly do ``conda uninstall phonopy``.
|
||||
|
||||
2. There may still exist litter of phonopy packages. So it is also
|
||||
recommend to remove them if it is found, e.g.::
|
||||
|
||||
% rm -fr ~/.local/lib/python*/site-packages/phonopy*
|
||||
|
||||
Set correct environment variables ``PATH`` and ``PYTHONPATH``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In phonopy, ``PATH`` and ``PYTHONPATH`` play important roles. Of
|
||||
course the information about them can be easily found in internet
|
||||
(e.g. https://en.wikipedia.org/wiki/PATH_(variable)), so you really
|
||||
have to find information by yourself and read them. Even if you can't
|
||||
understand them, first you must ask to your colleagues or people
|
||||
before sending this unnecessary question (as a researcher using
|
||||
computer simulation) to the mailing list.
|
||||
|
||||
The problem appears when phonopy execution and library paths are set
|
||||
multiple times in those environment variable. It is easy to check
|
||||
current environment variables by::
|
||||
|
||||
% echo $PATH
|
||||
|
||||
::
|
||||
|
||||
% echo $PYTHONPATH
|
||||
|
||||
When multiple different phonopy paths are found, remove all except for
|
||||
what you really need. Then logout from the current shell (terminal)
|
||||
and open new shell (terminal) to confirm that the modification is activated.
|
||||
|
|
|
@ -286,13 +286,15 @@ each path are as follows:
|
|||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Labels specified are depicted in band structure plot at the points of
|
||||
band segments. The number of labels has to correspond to the
|
||||
number of band paths specified by ``BAND`` plus one.
|
||||
band segments. The number of labels has to correspond to the number of
|
||||
band paths specified by ``BAND`` plus one. When LaTeX math style
|
||||
expression such as :math:`\Gamma` (``\Gamma``) is expected, it is
|
||||
probably necessary to place it between two $ characters.
|
||||
|
||||
::
|
||||
|
||||
BAND = 1/2 0 1/2 0 0 0 1/2 1/2 1/2
|
||||
BAND_LABELS = X \Gamma L
|
||||
BAND_LABELS = X $\Gamma$ L
|
||||
|
||||
.. |bandlabels| image:: band-labels.png
|
||||
:scale: 50
|
||||
|
|
|
@ -1,57 +1,98 @@
|
|||
from gpaw import GPAW, PW
|
||||
from ase import *
|
||||
from ase import Atoms
|
||||
from phonopy import Phonopy
|
||||
from phonopy.structure.atoms import Atoms as PhonopyAtoms
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
import numpy as np
|
||||
|
||||
# GPAW setting
|
||||
a = 5.404
|
||||
bulk = PhonopyAtoms(symbols=(['Si'] * 8),
|
||||
cell=np.diag((a, a, a)),
|
||||
scaled_positions=[(0, 0, 0),
|
||||
(0, 0.5, 0.5),
|
||||
(0.5, 0, 0.5),
|
||||
(0.5, 0.5, 0),
|
||||
(0.25, 0.25, 0.25),
|
||||
(0.25, 0.75, 0.75),
|
||||
(0.75, 0.25, 0.75),
|
||||
(0.75, 0.75, 0.25)])
|
||||
calc = GPAW(mode=PW(300),
|
||||
kpts={'size': (4, 4, 4)})
|
||||
def get_gpaw(kpts_size=None):
|
||||
if kpts_size is None:
|
||||
calc = GPAW(mode=PW(300),
|
||||
kpts={'size': (2, 2, 2)})
|
||||
else:
|
||||
calc = GPAW(mode=PW(300),
|
||||
kpts={'size': kpts_size})
|
||||
return calc
|
||||
|
||||
phonon = Phonopy(bulk,
|
||||
[[1,0,0], [0,1,0], [0,0,1]],
|
||||
primitive_matrix=[[0, 0.5, 0.5],
|
||||
[0.5, 0, 0.5],
|
||||
[0.5, 0.5, 0]])
|
||||
phonon.generate_displacements(distance=0.01)
|
||||
print("[Phonopy] Atomic displacements:")
|
||||
disps = phonon.get_displacements()
|
||||
for d in disps:
|
||||
print ("[Phonopy] %d %s" % (d[0], d[1:]))
|
||||
supercells = phonon.get_supercells_with_displacements()
|
||||
def get_crystal():
|
||||
a = 5.404
|
||||
cell = PhonopyAtoms(symbols=(['Si'] * 8),
|
||||
cell=np.diag((a, a, a)),
|
||||
scaled_positions=[(0, 0, 0),
|
||||
(0, 0.5, 0.5),
|
||||
(0.5, 0, 0.5),
|
||||
(0.5, 0.5, 0),
|
||||
(0.25, 0.25, 0.25),
|
||||
(0.25, 0.75, 0.75),
|
||||
(0.75, 0.25, 0.75),
|
||||
(0.75, 0.75, 0.25)])
|
||||
return cell
|
||||
|
||||
# Force calculations by calculator
|
||||
set_of_forces = []
|
||||
for scell in supercells:
|
||||
cell = Atoms(symbols=scell.get_chemical_symbols(),
|
||||
scaled_positions=scell.get_scaled_positions(),
|
||||
cell=scell.get_cell(),
|
||||
pbc=True)
|
||||
cell.set_calculator(calc)
|
||||
forces = cell.get_forces()
|
||||
drift_force = forces.sum(axis=0)
|
||||
print "[Phonopy] Drift force:", "%11.5f"*3 % tuple(drift_force)
|
||||
# Simple translational invariance
|
||||
for force in forces:
|
||||
force -= drift_force / forces.shape[0]
|
||||
set_of_forces.append(forces)
|
||||
def phonopy_pre_process(cell, supercell_matrix=None):
|
||||
|
||||
# Phonopy post-process
|
||||
phonon.produce_force_constants(forces=set_of_forces)
|
||||
print('')
|
||||
print("[Phonopy] Phonon frequencies at Gamma:")
|
||||
for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))):
|
||||
print("[Phonopy] %3d: %10.5f THz" % (i + 1, freq)) # THz
|
||||
if supercell_matrix is None:
|
||||
smat = [[2,0,0], [0,2,0], [0,0,2]],
|
||||
else:
|
||||
smat = supercell_matrix
|
||||
phonon = Phonopy(cell,
|
||||
smat,
|
||||
primitive_matrix=[[0, 0.5, 0.5],
|
||||
[0.5, 0, 0.5],
|
||||
[0.5, 0.5, 0]])
|
||||
phonon.generate_displacements(distance=0.03)
|
||||
print("[Phonopy] Atomic displacements:")
|
||||
disps = phonon.get_displacements()
|
||||
for d in disps:
|
||||
print("[Phonopy] %d %s" % (d[0], d[1:]))
|
||||
return phonon
|
||||
|
||||
def run_gpaw(calc, phonon):
|
||||
supercells = phonon.get_supercells_with_displacements()
|
||||
# Force calculations by calculator
|
||||
set_of_forces = []
|
||||
for scell in supercells:
|
||||
cell = Atoms(symbols=scell.get_chemical_symbols(),
|
||||
scaled_positions=scell.get_scaled_positions(),
|
||||
cell=scell.get_cell(),
|
||||
pbc=True)
|
||||
cell.set_calculator(calc)
|
||||
forces = cell.get_forces()
|
||||
drift_force = forces.sum(axis=0)
|
||||
print(("[Phonopy] Drift force:" + "%11.5f" * 3) % tuple(drift_force))
|
||||
# Simple translational invariance
|
||||
for force in forces:
|
||||
force -= drift_force / forces.shape[0]
|
||||
set_of_forces.append(forces)
|
||||
return set_of_forces
|
||||
|
||||
def phonopy_post_process(phonon, set_of_forces):
|
||||
phonon.produce_force_constants(forces=set_of_forces)
|
||||
print('')
|
||||
print("[Phonopy] Phonon frequencies at Gamma:")
|
||||
for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))):
|
||||
print("[Phonopy] %3d: %10.5f THz" % (i + 1, freq)) # THz
|
||||
|
||||
# DOS
|
||||
phonon.set_mesh([21, 21, 21])
|
||||
phonon.set_total_DOS(tetrahedron_method=True)
|
||||
print('')
|
||||
print("[Phonopy] Phonon DOS:")
|
||||
for omega, dos in np.array(phonon.get_total_DOS()).T:
|
||||
print("%15.7f%15.7f" % (omega, dos))
|
||||
|
||||
def main():
|
||||
cell = get_crystal()
|
||||
|
||||
# 1x1x1 supercell of conventional unit cell
|
||||
calc = get_gpaw(kpts_size=(4, 4, 4))
|
||||
phonon = phonopy_pre_process(cell, supercell_matrix=np.eye(3, dtype='intc'))
|
||||
|
||||
# # 2x2x2 supercell of conventional unit cell
|
||||
# calc = get_gpaw(kpts_size=(2, 2, 2))
|
||||
# phonon = phonopy_pre_process(cell,
|
||||
# supercell_matrix=(np.eye(3, dtype='intc') * 2))
|
||||
|
||||
set_of_forces = run_gpaw(calc, phonon)
|
||||
phonopy_post_process(phonon, set_of_forces)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -149,27 +149,47 @@ def distribute_force_constants(force_constants,
|
|||
rotations,
|
||||
trans,
|
||||
symprec):
|
||||
for atom_disp in atom_list:
|
||||
if atom_disp in atom_list_done:
|
||||
continue
|
||||
if True:
|
||||
rots_cartesian = np.array([similarity_transformation(lattice, r)
|
||||
for r in rotations],
|
||||
dtype='double', order='C')
|
||||
atom_list_copied = []
|
||||
for i in atom_list:
|
||||
if i not in atom_list_done:
|
||||
atom_list_copied.append(i)
|
||||
|
||||
map_atom_disp, map_sym = _get_atom_mapping_by_symmetry(
|
||||
atom_list_done,
|
||||
atom_disp,
|
||||
rotations,
|
||||
trans,
|
||||
lattice,
|
||||
positions,
|
||||
symprec=symprec)
|
||||
import phonopy._phonopy as phonoc
|
||||
phonoc.distribute_fc2_all(force_constants,
|
||||
lattice,
|
||||
positions,
|
||||
np.array(atom_list_copied, dtype='intc'),
|
||||
np.array(atom_list_done, dtype='intc'),
|
||||
rots_cartesian,
|
||||
rotations,
|
||||
trans,
|
||||
symprec)
|
||||
else:
|
||||
for atom_disp in atom_list:
|
||||
if atom_disp in atom_list_done:
|
||||
continue
|
||||
|
||||
_distribute_fc2_part(force_constants,
|
||||
positions,
|
||||
atom_disp,
|
||||
map_atom_disp,
|
||||
lattice,
|
||||
rotations[map_sym],
|
||||
trans[map_sym],
|
||||
symprec)
|
||||
map_atom_disp, map_sym = _get_atom_mapping_by_symmetry(
|
||||
atom_list_done,
|
||||
atom_disp,
|
||||
rotations,
|
||||
trans,
|
||||
lattice,
|
||||
positions,
|
||||
symprec=symprec)
|
||||
|
||||
_distribute_fc2_part(force_constants,
|
||||
positions,
|
||||
atom_disp,
|
||||
map_atom_disp,
|
||||
lattice,
|
||||
rotations[map_sym],
|
||||
trans[map_sym],
|
||||
symprec)
|
||||
|
||||
|
||||
def solve_force_constants(force_constants,
|
||||
|
|
|
@ -654,6 +654,17 @@ class Vasprun(object):
|
|||
|
||||
class VasprunxmlExpat(object):
|
||||
def __init__(self, fileptr):
|
||||
"""Parsing vasprun.xml by Expat
|
||||
|
||||
Args:
|
||||
fileptr: binary stream. Considering compatibility between python2.7
|
||||
and 3.x, it is prepared as follows:
|
||||
|
||||
import io
|
||||
io.open(filename, "rb")
|
||||
|
||||
"""
|
||||
|
||||
import xml.parsers.expat
|
||||
|
||||
self._fileptr = fileptr
|
||||
|
|
|
@ -61,7 +61,12 @@ def print_phononpy():
|
|||
|_| |_| |___/""")
|
||||
|
||||
def print_version(version):
|
||||
print(('%s' % version).rjust(44))
|
||||
try:
|
||||
import pkg_resources
|
||||
rev = pkg_resources.require("phonopy")[0].version.split('.')[3]
|
||||
print(('%s-r%s' % (version, rev)).rjust(44))
|
||||
except ImportError:
|
||||
print(('%s' % version).rjust(44))
|
||||
print('')
|
||||
|
||||
def print_end():
|
||||
|
|
44
setup.py
44
setup.py
|
@ -1,5 +1,8 @@
|
|||
import numpy
|
||||
import os
|
||||
import sys
|
||||
import numpy
|
||||
|
||||
with_openmp = False
|
||||
|
||||
try:
|
||||
from setuptools import setup, Extension
|
||||
|
@ -10,6 +13,18 @@ except ImportError:
|
|||
use_setuptools = False
|
||||
print("distutils is used.")
|
||||
|
||||
try:
|
||||
from setuptools_scm import get_version
|
||||
except ImportError:
|
||||
git_num = None
|
||||
|
||||
if 'setuptools_scm' in sys.modules.keys():
|
||||
try:
|
||||
git_ver = get_version()
|
||||
git_num = int(git_ver.split('.')[3].split('+')[0].replace("dev", ""))
|
||||
except:
|
||||
git_num = None
|
||||
|
||||
include_dirs_numpy = [numpy.get_include()]
|
||||
cc = None
|
||||
if 'CC' in os.environ:
|
||||
|
@ -35,10 +50,7 @@ sources_phonopy = ['c/_phonopy.c',
|
|||
'c/kspclib/kgrid.c',
|
||||
'c/kspclib/tetrahedron_method.c']
|
||||
|
||||
if __name__ == '__main__':
|
||||
extra_compile_args_phonopy = []
|
||||
extra_link_args_phonopy = []
|
||||
else:
|
||||
if with_openmp:
|
||||
extra_compile_args_phonopy = ['-fopenmp',]
|
||||
if cc == 'gcc':
|
||||
extra_link_args_phonopy = ['-lgomp',]
|
||||
|
@ -46,6 +58,9 @@ else:
|
|||
extra_link_args_phonopy = []
|
||||
else:
|
||||
extra_link_args_phonopy = ['-lgomp',]
|
||||
else:
|
||||
extra_compile_args_phonopy = []
|
||||
extra_link_args_phonopy = []
|
||||
|
||||
extension_phonopy = Extension(
|
||||
'phonopy._phonopy',
|
||||
|
@ -58,10 +73,7 @@ extension_phonopy = Extension(
|
|||
#####################
|
||||
# _spglib extension #
|
||||
#####################
|
||||
if __name__ == '__main__':
|
||||
extra_compile_args_spglib=[]
|
||||
extra_link_args_spglib=[]
|
||||
else:
|
||||
if with_openmp:
|
||||
extra_compile_args_spglib=['-fopenmp',]
|
||||
if cc == 'gcc':
|
||||
extra_link_args_spglib=['-lgomp',]
|
||||
|
@ -69,6 +81,9 @@ else:
|
|||
extra_link_args_spglib=[]
|
||||
else:
|
||||
extra_link_args_spglib=['-lgomp',]
|
||||
else:
|
||||
extra_compile_args_spglib=[]
|
||||
extra_link_args_spglib=[]
|
||||
|
||||
extension_spglib = Extension(
|
||||
'phonopy._spglib',
|
||||
|
@ -118,14 +133,16 @@ scripts_phonopy = ['scripts/phonopy',
|
|||
'scripts/pdosplot']
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
version_nums = [None, None, None]
|
||||
with open("phonopy/version.py") as w:
|
||||
for line in w:
|
||||
with open("phonopy/version.py") as f:
|
||||
for line in f:
|
||||
if "__version__" in line:
|
||||
for i, num in enumerate(line.split()[2].strip('\"').split('.')):
|
||||
version_nums[i] = int(num)
|
||||
break
|
||||
|
||||
# To deploy to pypi/conda by travis-CI
|
||||
# # To deploy to pypi/conda by travis-CI
|
||||
if os.path.isfile("__nanoversion__.txt"):
|
||||
with open('__nanoversion__.txt') as nv:
|
||||
try :
|
||||
|
@ -136,12 +153,15 @@ if __name__ == '__main__':
|
|||
nanoversion = 0
|
||||
if nanoversion:
|
||||
version_nums.append(nanoversion)
|
||||
elif git_num:
|
||||
version_nums.append(git_num)
|
||||
|
||||
if None in version_nums:
|
||||
print("Failed to get version number in setup.py.")
|
||||
raise
|
||||
|
||||
version_number = ".".join(["%d" % n for n in version_nums])
|
||||
|
||||
if use_setuptools:
|
||||
setup(name='phonopy',
|
||||
version=version_number,
|
||||
|
|
Loading…
Reference in New Issue