Merge branch 'rc'

This commit is contained in:
Atsushi Togo 2017-08-07 12:39:29 +09:00
commit 64ea303dd2
12 changed files with 529 additions and 222 deletions

View File

@ -8,14 +8,20 @@ python:
- '3.6' - '3.6'
before_install: before_install:
- TRAVIS_PYTHON_VERSION=`python --version |& awk '{print $2}'|awk -F'.' '{print $1"."$2}'` #- 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 # - 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 - bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH" - export PATH="$HOME/miniconda/bin:$PATH"
- conda update --yes conda - conda update --yes conda
install: 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 - pwd
- ./get_nanoversion.sh - ./get_nanoversion.sh
- cat __nanoversion__.txt - cat __nanoversion__.txt

View File

@ -1 +0,0 @@
0

View File

@ -34,6 +34,7 @@
#include <Python.h> #include <Python.h>
#include <stdio.h> #include <stdio.h>
#include <math.h>
#include <numpy/arrayobject.h> #include <numpy/arrayobject.h>
#include <dynmat.h> #include <dynmat.h>
#include <derivative_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_derivative_dynmat(PyObject *self, PyObject *args);
static PyObject * py_get_thermal_properties(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(PyObject *self, PyObject *args);
static PyObject * py_distribute_fc2_all(PyObject *self, PyObject *args);
static int distribute_fc2(double * fc2, static int distribute_fc2(double *fc2,
const double * lat, PHPYCONST double lat[3][3],
const double * pos, PHPYCONST double (*pos)[3],
const int num_pos, const int num_pos,
const int atom_disp, const int atom_disp,
const int map_atom_disp, const int map_atom_disp,
const double * r_cart, PHPYCONST double r_cart[3][3],
const int * r, PHPYCONST int r[3][3],
const double * t, const double t[3],
const double symprec); const double symprec);
static PyObject * py_thm_neighboring_grid_points(PyObject *self, PyObject *args); static PyObject * py_thm_neighboring_grid_points(PyObject *self, PyObject *args);
static PyObject * static PyObject *
@ -80,6 +82,13 @@ static double get_entropy_omega(const double temperature,
static double get_heat_capacity_omega(const double temperature, static double get_heat_capacity_omega(const double temperature,
const double omega); const double omega);
/* static double get_energy_omega(double temperature, 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); static int nint(const double a);
struct module_state { struct module_state {
@ -108,6 +117,8 @@ static PyMethodDef _phonopy_methods[] = {
{"derivative_dynmat", py_get_derivative_dynmat, METH_VARARGS, "Q derivative of dynamical matrix"}, {"derivative_dynmat", py_get_derivative_dynmat, METH_VARARGS, "Q derivative of dynamical matrix"},
{"thermal_properties", py_get_thermal_properties, METH_VARARGS, "Thermal properties"}, {"thermal_properties", py_get_thermal_properties, METH_VARARGS, "Thermal properties"},
{"distribute_fc2", py_distribute_fc2, METH_VARARGS, "Distribute force constants"}, {"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, {"neighboring_grid_points", py_thm_neighboring_grid_points,
METH_VARARGS, "Neighboring grid points by relative grid addresses"}, METH_VARARGS, "Neighboring grid points by relative grid addresses"},
{"tetrahedra_relative_grid_address", py_thm_relative_grid_address, {"tetrahedra_relative_grid_address", py_thm_relative_grid_address,
@ -548,7 +559,7 @@ static PyObject * py_get_thermal_properties(PyObject *self, PyObject *args)
} }
} }
} }
for (i = 0; i < num_temp * 3; i++) { for (i = 0; i < num_temp * 3; i++) {
for (j = 0; j < num_qpoints; j++) { for (j = 0; j < num_qpoints; j++) {
thermal_props[i] += tp[j * num_temp * 3 + i]; thermal_props[i] += tp[j * num_temp * 3 + i];
@ -613,43 +624,43 @@ static double get_heat_capacity_omega(const double temperature,
static PyObject * py_distribute_fc2(PyObject *self, PyObject *args) static PyObject * py_distribute_fc2(PyObject *self, PyObject *args)
{ {
PyArrayObject* force_constants; PyArrayObject* force_constants_py;
PyArrayObject* lattice; PyArrayObject* lattice_py;
PyArrayObject* positions; PyArrayObject* positions_py;
PyArrayObject* rotation; PyArrayObject* rotation_py;
PyArrayObject* rotation_cart; PyArrayObject* rotation_cart_py;
PyArrayObject* translation; PyArrayObject* translation_py;
int atom_disp, map_atom_disp; int atom_disp, map_atom_disp;
double symprec; double symprec;
int* r; int (*r)[3];
double* r_cart; double (*r_cart)[3];
double* fc2; double *fc2;
double* t; double *t;
double* lat; double (*lat)[3];
double* pos; double (*pos)[3];
int num_pos; int num_pos;
if (!PyArg_ParseTuple(args, "OOOiiOOOd", if (!PyArg_ParseTuple(args, "OOOiiOOOd",
&force_constants, &force_constants_py,
&lattice, &lattice_py,
&positions, &positions_py,
&atom_disp, &atom_disp,
&map_atom_disp, &map_atom_disp,
&rotation_cart, &rotation_cart_py,
&rotation, &rotation_py,
&translation, &translation_py,
&symprec)) { &symprec)) {
return NULL; return NULL;
} }
r = (int*)PyArray_DATA(rotation); r = (int(*)[3])PyArray_DATA(rotation_py);
r_cart = (double*)PyArray_DATA(rotation_cart); r_cart = (double(*)[3])PyArray_DATA(rotation_cart_py);
fc2 = (double*)PyArray_DATA(force_constants); fc2 = (double*)PyArray_DATA(force_constants_py);
t = (double*)PyArray_DATA(translation); t = (double*)PyArray_DATA(translation_py);
lat = (double*)PyArray_DATA(lattice); lat = (double(*)[3])PyArray_DATA(lattice_py);
pos = (double*)PyArray_DATA(positions); pos = (double(*)[3])PyArray_DATA(positions_py);
num_pos = PyArray_DIMS(positions)[0]; num_pos = PyArray_DIMS(positions_py)[0];
distribute_fc2(fc2, distribute_fc2(fc2,
lat, lat,
@ -665,79 +676,96 @@ static PyObject * py_distribute_fc2(PyObject *self, PyObject *args)
Py_RETURN_NONE; Py_RETURN_NONE;
} }
static int distribute_fc2(double * fc2, static PyObject * py_distribute_fc2_all(PyObject *self, PyObject *args)
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)
{ {
int i, j, k, l, m, address_new, address; PyArrayObject* force_constants_py;
int is_found, rot_atom; PyArrayObject* lattice_py;
double distance2, symprec2, diff_cart; PyArrayObject* positions_py;
double rot_pos[3], diff[3]; 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; if (!PyArg_ParseTuple(args, "OOOOOOOOd",
for (i = 0; i < num_pos; i++) { &force_constants_py,
for (j = 0; j < 3; j++) { &lattice_py,
rot_pos[j] = t[j]; &positions_py,
for (k = 0; k < 3; k++) { &atom_list_py,
rot_pos[j] += r[j * 3 + k] * pos[i * 3 + k]; &atom_list_done_py,
} &rotations_cart_py,
} &rotations_py,
&translations_py,
rot_atom = -1; &symprec)) {
for (j = 0; j < num_pos; j++) { return NULL;
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:
;
} }
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) 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; 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) static int nint(const double a)
{ {
if (a < 0.0) if (a < 0.0)

View File

@ -31,6 +31,8 @@ requirements:
- matplotlib - matplotlib
- pyyaml - pyyaml
- h5py - h5py
- setuptools
- setuptools_scm
run: run:
- python - python

View File

@ -7,33 +7,28 @@ Installation using MacPorts
---------------------------- ----------------------------
This is one way to install phonopy on Mac OS X. This procedure was 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, tested on Sierra 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 gcc-7 is used as the default C-compiler.
and using these numpy and scipy are made.
1) Install MacPorts. Download MacPorts from http://www.macports.org/ 1) Install MacPorts. Download MacPorts from http://www.macports.org/
and follow the installation instruction. and follow the installation instruction.
2) Install the following packages 2) Install ``gcc`` by
:: ::
% sudo port install gcc6 % sudo port install gcc7
% sudo port select --set gcc mp-gcc6 % sudo port select --set gcc mp-gcc7
% 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
3) Install phonopy following :ref:`install` (step 1 can be omitted.)
Before running setup.py, gcc can be used as the C-compiler instead 3) Install necessary python libraries by conda::
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 % export CC=gcc
% python setup.py install --user % python setup.py install --user

View File

@ -1,6 +1,6 @@
.. _install: .. _install:
Download and install Installation
===================== =====================
.. contents:: .. contents::
@ -58,6 +58,8 @@ follows::
% conda install numpy scipy h5py pyyaml matplotlib % conda install numpy scipy h5py pyyaml matplotlib
.. _install_setup_py:
Building using setup.py Building using setup.py
~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
@ -72,27 +74,39 @@ needed.
and extract it:: 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 2. Set up C-libraries for python C-API and python codes. This can be
done as follows: done as follows:
Run ``setup.py`` script:: 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 % 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 3. Assuming the installation location is those shown in the step 2,
.bashrc, .zshenv, etc. If it is installed under your current set :envvar:`$PATH` and :envvar:`$PYTHONPATH`::
directory, the path to be added to :envvar:`$PYTHONPATH` is such as below::
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 Tips on setup.py installation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -103,6 +117,8 @@ Tips on setup.py installation
MacOSX MacOSX
virtualmachine virtualmachine
.. _install_conda:
conda conda
------ ------
@ -139,4 +155,75 @@ e.g.,::
sudo apt-get install python-dev 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.

View File

@ -286,13 +286,15 @@ each path are as follows:
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
Labels specified are depicted in band structure plot at the points of Labels specified are depicted in band structure plot at the points of
band segments. The number of labels has to correspond to the band segments. The number of labels has to correspond to the number of
number of band paths specified by ``BAND`` plus one. 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 = 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 .. |bandlabels| image:: band-labels.png
:scale: 50 :scale: 50

View File

@ -1,57 +1,98 @@
from gpaw import GPAW, PW from gpaw import GPAW, PW
from ase import * from ase import Atoms
from phonopy import Phonopy from phonopy import Phonopy
from phonopy.structure.atoms import Atoms as PhonopyAtoms from phonopy.structure.atoms import PhonopyAtoms
import numpy as np import numpy as np
# GPAW setting def get_gpaw(kpts_size=None):
a = 5.404 if kpts_size is None:
bulk = PhonopyAtoms(symbols=(['Si'] * 8), calc = GPAW(mode=PW(300),
cell=np.diag((a, a, a)), kpts={'size': (2, 2, 2)})
scaled_positions=[(0, 0, 0), else:
(0, 0.5, 0.5), calc = GPAW(mode=PW(300),
(0.5, 0, 0.5), kpts={'size': kpts_size})
(0.5, 0.5, 0), return calc
(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)})
phonon = Phonopy(bulk, def get_crystal():
[[1,0,0], [0,1,0], [0,0,1]], a = 5.404
primitive_matrix=[[0, 0.5, 0.5], cell = PhonopyAtoms(symbols=(['Si'] * 8),
[0.5, 0, 0.5], cell=np.diag((a, a, a)),
[0.5, 0.5, 0]]) scaled_positions=[(0, 0, 0),
phonon.generate_displacements(distance=0.01) (0, 0.5, 0.5),
print("[Phonopy] Atomic displacements:") (0.5, 0, 0.5),
disps = phonon.get_displacements() (0.5, 0.5, 0),
for d in disps: (0.25, 0.25, 0.25),
print ("[Phonopy] %d %s" % (d[0], d[1:])) (0.25, 0.75, 0.75),
supercells = phonon.get_supercells_with_displacements() (0.75, 0.25, 0.75),
(0.75, 0.75, 0.25)])
return cell
# Force calculations by calculator def phonopy_pre_process(cell, supercell_matrix=None):
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)
# Phonopy post-process if supercell_matrix is None:
phonon.produce_force_constants(forces=set_of_forces) smat = [[2,0,0], [0,2,0], [0,0,2]],
print('') else:
print("[Phonopy] Phonon frequencies at Gamma:") smat = supercell_matrix
for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))): phonon = Phonopy(cell,
print("[Phonopy] %3d: %10.5f THz" % (i + 1, freq)) # THz 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()

View File

@ -149,27 +149,47 @@ def distribute_force_constants(force_constants,
rotations, rotations,
trans, trans,
symprec): symprec):
for atom_disp in atom_list: if True:
if atom_disp in atom_list_done: rots_cartesian = np.array([similarity_transformation(lattice, r)
continue 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( import phonopy._phonopy as phonoc
atom_list_done, phonoc.distribute_fc2_all(force_constants,
atom_disp, lattice,
rotations, positions,
trans, np.array(atom_list_copied, dtype='intc'),
lattice, np.array(atom_list_done, dtype='intc'),
positions, rots_cartesian,
symprec=symprec) rotations,
trans,
_distribute_fc2_part(force_constants, symprec)
positions, else:
atom_disp, for atom_disp in atom_list:
map_atom_disp, if atom_disp in atom_list_done:
lattice, continue
rotations[map_sym],
trans[map_sym], map_atom_disp, map_sym = _get_atom_mapping_by_symmetry(
symprec) 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, def solve_force_constants(force_constants,

View File

@ -654,6 +654,17 @@ class Vasprun(object):
class VasprunxmlExpat(object): class VasprunxmlExpat(object):
def __init__(self, fileptr): 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 import xml.parsers.expat
self._fileptr = fileptr self._fileptr = fileptr

View File

@ -61,7 +61,12 @@ def print_phononpy():
|_| |_| |___/""") |_| |_| |___/""")
def print_version(version): 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('') print('')
def print_end(): def print_end():

View File

@ -1,5 +1,8 @@
import numpy
import os import os
import sys
import numpy
with_openmp = False
try: try:
from setuptools import setup, Extension from setuptools import setup, Extension
@ -10,6 +13,18 @@ except ImportError:
use_setuptools = False use_setuptools = False
print("distutils is used.") 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()] include_dirs_numpy = [numpy.get_include()]
cc = None cc = None
if 'CC' in os.environ: if 'CC' in os.environ:
@ -35,10 +50,7 @@ sources_phonopy = ['c/_phonopy.c',
'c/kspclib/kgrid.c', 'c/kspclib/kgrid.c',
'c/kspclib/tetrahedron_method.c'] 'c/kspclib/tetrahedron_method.c']
if __name__ == '__main__': if with_openmp:
extra_compile_args_phonopy = []
extra_link_args_phonopy = []
else:
extra_compile_args_phonopy = ['-fopenmp',] extra_compile_args_phonopy = ['-fopenmp',]
if cc == 'gcc': if cc == 'gcc':
extra_link_args_phonopy = ['-lgomp',] extra_link_args_phonopy = ['-lgomp',]
@ -46,6 +58,9 @@ else:
extra_link_args_phonopy = [] extra_link_args_phonopy = []
else: else:
extra_link_args_phonopy = ['-lgomp',] extra_link_args_phonopy = ['-lgomp',]
else:
extra_compile_args_phonopy = []
extra_link_args_phonopy = []
extension_phonopy = Extension( extension_phonopy = Extension(
'phonopy._phonopy', 'phonopy._phonopy',
@ -58,10 +73,7 @@ extension_phonopy = Extension(
##################### #####################
# _spglib extension # # _spglib extension #
##################### #####################
if __name__ == '__main__': if with_openmp:
extra_compile_args_spglib=[]
extra_link_args_spglib=[]
else:
extra_compile_args_spglib=['-fopenmp',] extra_compile_args_spglib=['-fopenmp',]
if cc == 'gcc': if cc == 'gcc':
extra_link_args_spglib=['-lgomp',] extra_link_args_spglib=['-lgomp',]
@ -69,6 +81,9 @@ else:
extra_link_args_spglib=[] extra_link_args_spglib=[]
else: else:
extra_link_args_spglib=['-lgomp',] extra_link_args_spglib=['-lgomp',]
else:
extra_compile_args_spglib=[]
extra_link_args_spglib=[]
extension_spglib = Extension( extension_spglib = Extension(
'phonopy._spglib', 'phonopy._spglib',
@ -118,14 +133,16 @@ scripts_phonopy = ['scripts/phonopy',
'scripts/pdosplot'] 'scripts/pdosplot']
if __name__ == '__main__': if __name__ == '__main__':
version_nums = [None, None, None] version_nums = [None, None, None]
with open("phonopy/version.py") as w: with open("phonopy/version.py") as f:
for line in w: for line in f:
if "__version__" in line: if "__version__" in line:
for i, num in enumerate(line.split()[2].strip('\"').split('.')): for i, num in enumerate(line.split()[2].strip('\"').split('.')):
version_nums[i] = int(num) 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"): if os.path.isfile("__nanoversion__.txt"):
with open('__nanoversion__.txt') as nv: with open('__nanoversion__.txt') as nv:
try : try :
@ -136,12 +153,15 @@ if __name__ == '__main__':
nanoversion = 0 nanoversion = 0
if nanoversion: if nanoversion:
version_nums.append(nanoversion) version_nums.append(nanoversion)
elif git_num:
version_nums.append(git_num)
if None in version_nums: if None in version_nums:
print("Failed to get version number in setup.py.") print("Failed to get version number in setup.py.")
raise raise
version_number = ".".join(["%d" % n for n in version_nums]) version_number = ".".join(["%d" % n for n in version_nums])
if use_setuptools: if use_setuptools:
setup(name='phonopy', setup(name='phonopy',
version=version_number, version=version_number,