mirror of https://github.com/phonopy/phono3py.git
Merge pull request #51 from phonopy/refactoring
Refactoring and bug fix of direct solition
This commit is contained in:
commit
febccc9fe8
174
c/_lapackepy.c
174
c/_lapackepy.c
|
@ -33,17 +33,17 @@
|
|||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <Python.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <numpy/arrayobject.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
static PyObject *py_phonopy_pinv(PyObject *self, PyObject *args);
|
||||
static PyObject *py_phonopy_zheev(PyObject *self, PyObject *args);
|
||||
|
||||
struct module_state
|
||||
{
|
||||
PyObject *error;
|
||||
struct module_state {
|
||||
PyObject *error;
|
||||
};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
@ -53,50 +53,39 @@ struct module_state
|
|||
static struct module_state _state;
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
error_out(PyObject *m)
|
||||
{
|
||||
struct module_state *st = GETSTATE(m);
|
||||
PyErr_SetString(st->error, "something bad happened");
|
||||
return NULL;
|
||||
static PyObject *error_out(PyObject *m) {
|
||||
struct module_state *st = GETSTATE(m);
|
||||
PyErr_SetString(st->error, "something bad happened");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyMethodDef _lapackepy_methods[] = {
|
||||
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
|
||||
{"pinv", py_phonopy_pinv, METH_VARARGS, "Pseudo-inverse using Lapack dgesvd"},
|
||||
{"pinv", py_phonopy_pinv, METH_VARARGS,
|
||||
"Pseudo-inverse using Lapack dgesvd"},
|
||||
{"zheev", py_phonopy_zheev, METH_VARARGS, "Lapack zheev wrapper"},
|
||||
{NULL, NULL, 0, NULL}};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
||||
static int _lapackepy_traverse(PyObject *m, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
static int _lapackepy_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _lapackepy_clear(PyObject *m)
|
||||
{
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
static int _lapackepy_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_lapackepy",
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
_lapackepy_methods,
|
||||
NULL,
|
||||
_lapackepy_traverse,
|
||||
_lapackepy_clear,
|
||||
NULL};
|
||||
PyModuleDef_HEAD_INIT, "_lapackepy", NULL,
|
||||
sizeof(struct module_state), _lapackepy_methods, NULL,
|
||||
_lapackepy_traverse, _lapackepy_clear, NULL};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyObject *
|
||||
PyInit__lapackepy(void)
|
||||
|
||||
PyObject *PyInit__lapackepy(void)
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
|
@ -104,96 +93,83 @@ void init_lapackepy(void)
|
|||
#endif
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule("_lapackepy", _lapackepy_methods);
|
||||
PyObject *module = Py_InitModule("_lapackepy", _lapackepy_methods);
|
||||
#endif
|
||||
struct module_state *st;
|
||||
struct module_state *st;
|
||||
|
||||
if (module == NULL)
|
||||
INITERROR;
|
||||
st = GETSTATE(module);
|
||||
if (module == NULL) INITERROR;
|
||||
st = GETSTATE(module);
|
||||
|
||||
st->error = PyErr_NewException("_lapackepy.Error", NULL, NULL);
|
||||
if (st->error == NULL)
|
||||
{
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
st->error = PyErr_NewException("_lapackepy.Error", NULL, NULL);
|
||||
if (st->error == NULL) {
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return module;
|
||||
return module;
|
||||
#endif
|
||||
}
|
||||
|
||||
static PyObject *py_phonopy_zheev(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyArrayObject *dynamical_matrix;
|
||||
PyArrayObject *eigenvalues;
|
||||
static PyObject *py_phonopy_zheev(PyObject *self, PyObject *args) {
|
||||
PyArrayObject *dynamical_matrix;
|
||||
PyArrayObject *eigenvalues;
|
||||
|
||||
int dimension;
|
||||
npy_cdouble *dynmat;
|
||||
double *eigvals;
|
||||
lapack_complex_double *a;
|
||||
int i, info;
|
||||
int dimension;
|
||||
npy_cdouble *dynmat;
|
||||
double *eigvals;
|
||||
lapack_complex_double *a;
|
||||
int i, info;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OO",
|
||||
&dynamical_matrix,
|
||||
&eigenvalues))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "OO", &dynamical_matrix, &eigenvalues)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dimension = (int)PyArray_DIMS(dynamical_matrix)[0];
|
||||
dynmat = (npy_cdouble *)PyArray_DATA(dynamical_matrix);
|
||||
eigvals = (double *)PyArray_DATA(eigenvalues);
|
||||
dimension = (int)PyArray_DIMS(dynamical_matrix)[0];
|
||||
dynmat = (npy_cdouble *)PyArray_DATA(dynamical_matrix);
|
||||
eigvals = (double *)PyArray_DATA(eigenvalues);
|
||||
|
||||
a = (lapack_complex_double *)malloc(sizeof(lapack_complex_double) *
|
||||
dimension * dimension);
|
||||
for (i = 0; i < dimension * dimension; i++)
|
||||
{
|
||||
a[i] = lapack_make_complex_double(dynmat[i].real, dynmat[i].imag);
|
||||
}
|
||||
a = (lapack_complex_double *)malloc(sizeof(lapack_complex_double) *
|
||||
dimension * dimension);
|
||||
for (i = 0; i < dimension * dimension; i++) {
|
||||
a[i] = lapack_make_complex_double(dynmat[i].real, dynmat[i].imag);
|
||||
}
|
||||
|
||||
info = phonopy_zheev(eigvals, a, dimension, 'L');
|
||||
info = phonopy_zheev(eigvals, a, dimension, 'L');
|
||||
|
||||
for (i = 0; i < dimension * dimension; i++)
|
||||
{
|
||||
dynmat[i].real = lapack_complex_double_real(a[i]);
|
||||
dynmat[i].imag = lapack_complex_double_imag(a[i]);
|
||||
}
|
||||
for (i = 0; i < dimension * dimension; i++) {
|
||||
dynmat[i].real = lapack_complex_double_real(a[i]);
|
||||
dynmat[i].imag = lapack_complex_double_imag(a[i]);
|
||||
}
|
||||
|
||||
free(a);
|
||||
free(a);
|
||||
|
||||
return PyLong_FromLong((long)info);
|
||||
return PyLong_FromLong((long)info);
|
||||
}
|
||||
|
||||
static PyObject *py_phonopy_pinv(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyArrayObject *data_in_py;
|
||||
PyArrayObject *data_out_py;
|
||||
double cutoff;
|
||||
static PyObject *py_phonopy_pinv(PyObject *self, PyObject *args) {
|
||||
PyArrayObject *data_in_py;
|
||||
PyArrayObject *data_out_py;
|
||||
double cutoff;
|
||||
|
||||
int m;
|
||||
int n;
|
||||
double *data_in;
|
||||
double *data_out;
|
||||
int info;
|
||||
int m;
|
||||
int n;
|
||||
double *data_in;
|
||||
double *data_out;
|
||||
int info;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OOd",
|
||||
&data_out_py,
|
||||
&data_in_py,
|
||||
&cutoff))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!PyArg_ParseTuple(args, "OOd", &data_out_py, &data_in_py, &cutoff)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m = (int)PyArray_DIMS(data_in_py)[0];
|
||||
n = (int)PyArray_DIMS(data_in_py)[1];
|
||||
data_in = (double *)PyArray_DATA(data_in_py);
|
||||
data_out = (double *)PyArray_DATA(data_out_py);
|
||||
m = (int)PyArray_DIMS(data_in_py)[0];
|
||||
n = (int)PyArray_DIMS(data_in_py)[1];
|
||||
data_in = (double *)PyArray_DATA(data_in_py);
|
||||
data_out = (double *)PyArray_DATA(data_out_py);
|
||||
|
||||
info = phonopy_pinv(data_out, data_in, m, n, cutoff);
|
||||
info = phonopy_pinv(data_out, data_in, m, n, cutoff);
|
||||
|
||||
return PyLong_FromLong((long)info);
|
||||
return PyLong_FromLong((long)info);
|
||||
}
|
||||
|
|
3859
c/_phono3py.c
3859
c/_phono3py.c
File diff suppressed because it is too large
Load Diff
362
c/_phononmod.c
362
c/_phononmod.c
|
@ -34,14 +34,14 @@
|
|||
|
||||
#include <Python.h>
|
||||
#include <numpy/arrayobject.h>
|
||||
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phononmod.h"
|
||||
|
||||
static PyObject *py_get_phonons_at_gridpoints(PyObject *self, PyObject *args);
|
||||
|
||||
struct module_state
|
||||
{
|
||||
PyObject *error;
|
||||
struct module_state {
|
||||
PyObject *error;
|
||||
};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
@ -51,52 +51,38 @@ struct module_state
|
|||
static struct module_state _state;
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
error_out(PyObject *m)
|
||||
{
|
||||
struct module_state *st = GETSTATE(m);
|
||||
PyErr_SetString(st->error, "something bad happened");
|
||||
return NULL;
|
||||
static PyObject *error_out(PyObject *m) {
|
||||
struct module_state *st = GETSTATE(m);
|
||||
PyErr_SetString(st->error, "something bad happened");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyMethodDef _phononmod_methods[] = {
|
||||
{"error_out", (PyCFunction)error_out, METH_NOARGS, NULL},
|
||||
{"phonons_at_gridpoints",
|
||||
py_get_phonons_at_gridpoints,
|
||||
METH_VARARGS,
|
||||
{"phonons_at_gridpoints", py_get_phonons_at_gridpoints, METH_VARARGS,
|
||||
"Set phonons at grid points"},
|
||||
{NULL, NULL, 0, NULL}};
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
|
||||
static int _phononmod_traverse(PyObject *m, visitproc visit, void *arg)
|
||||
{
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
static int _phononmod_traverse(PyObject *m, visitproc visit, void *arg) {
|
||||
Py_VISIT(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _phononmod_clear(PyObject *m)
|
||||
{
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
static int _phononmod_clear(PyObject *m) {
|
||||
Py_CLEAR(GETSTATE(m)->error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct PyModuleDef moduledef = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_phononmod",
|
||||
NULL,
|
||||
sizeof(struct module_state),
|
||||
_phononmod_methods,
|
||||
NULL,
|
||||
_phononmod_traverse,
|
||||
_phononmod_clear,
|
||||
NULL};
|
||||
PyModuleDef_HEAD_INIT, "_phononmod", NULL,
|
||||
sizeof(struct module_state), _phononmod_methods, NULL,
|
||||
_phononmod_traverse, _phononmod_clear, NULL};
|
||||
|
||||
#define INITERROR return NULL
|
||||
|
||||
PyObject *
|
||||
PyInit__phononmod(void)
|
||||
|
||||
PyObject *PyInit__phononmod(void)
|
||||
#else
|
||||
#define INITERROR return
|
||||
|
||||
|
@ -104,205 +90,143 @@ void init_phononmod(void)
|
|||
#endif
|
||||
{
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
PyObject *module = PyModule_Create(&moduledef);
|
||||
#else
|
||||
PyObject *module = Py_InitModule("_phononmod", _phononmod_methods);
|
||||
PyObject *module = Py_InitModule("_phononmod", _phononmod_methods);
|
||||
#endif
|
||||
struct module_state *st;
|
||||
struct module_state *st;
|
||||
|
||||
if (module == NULL)
|
||||
INITERROR;
|
||||
st = GETSTATE(module);
|
||||
if (module == NULL) INITERROR;
|
||||
st = GETSTATE(module);
|
||||
|
||||
st->error = PyErr_NewException("_phononmod.Error", NULL, NULL);
|
||||
if (st->error == NULL)
|
||||
{
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
st->error = PyErr_NewException("_phononmod.Error", NULL, NULL);
|
||||
if (st->error == NULL) {
|
||||
Py_DECREF(module);
|
||||
INITERROR;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return module;
|
||||
return module;
|
||||
#endif
|
||||
}
|
||||
|
||||
static PyObject *py_get_phonons_at_gridpoints(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyArrayObject *py_frequencies;
|
||||
PyArrayObject *py_eigenvectors;
|
||||
PyArrayObject *py_phonon_done;
|
||||
PyArrayObject *py_grid_points;
|
||||
PyArrayObject *py_grid_address;
|
||||
PyArrayObject *py_QDinv;
|
||||
PyArrayObject *py_shortest_vectors_fc2;
|
||||
PyArrayObject *py_multiplicity_fc2;
|
||||
PyArrayObject *py_positions_fc2;
|
||||
PyArrayObject *py_fc2;
|
||||
PyArrayObject *py_masses_fc2;
|
||||
PyArrayObject *py_p2s_map_fc2;
|
||||
PyArrayObject *py_s2p_map_fc2;
|
||||
PyArrayObject *py_reciprocal_lattice;
|
||||
PyArrayObject *py_born_effective_charge;
|
||||
PyArrayObject *py_q_direction;
|
||||
PyArrayObject *py_dielectric_constant;
|
||||
PyArrayObject *py_dd_q0;
|
||||
PyArrayObject *py_G_list;
|
||||
double nac_factor;
|
||||
double unit_conversion_factor;
|
||||
double lambda;
|
||||
char *uplo;
|
||||
static PyObject *py_get_phonons_at_gridpoints(PyObject *self, PyObject *args) {
|
||||
PyArrayObject *py_frequencies;
|
||||
PyArrayObject *py_eigenvectors;
|
||||
PyArrayObject *py_phonon_done;
|
||||
PyArrayObject *py_grid_points;
|
||||
PyArrayObject *py_grid_address;
|
||||
PyArrayObject *py_QDinv;
|
||||
PyArrayObject *py_shortest_vectors_fc2;
|
||||
PyArrayObject *py_multiplicity_fc2;
|
||||
PyArrayObject *py_positions_fc2;
|
||||
PyArrayObject *py_fc2;
|
||||
PyArrayObject *py_masses_fc2;
|
||||
PyArrayObject *py_p2s_map_fc2;
|
||||
PyArrayObject *py_s2p_map_fc2;
|
||||
PyArrayObject *py_reciprocal_lattice;
|
||||
PyArrayObject *py_born_effective_charge;
|
||||
PyArrayObject *py_q_direction;
|
||||
PyArrayObject *py_dielectric_constant;
|
||||
PyArrayObject *py_dd_q0;
|
||||
PyArrayObject *py_G_list;
|
||||
double nac_factor;
|
||||
double unit_conversion_factor;
|
||||
double lambda;
|
||||
char *uplo;
|
||||
|
||||
double(*born)[3][3];
|
||||
double(*dielectric)[3];
|
||||
double *q_dir;
|
||||
double *freqs;
|
||||
lapack_complex_double *eigvecs;
|
||||
char *phonon_done;
|
||||
long *grid_points;
|
||||
long(*grid_address)[3];
|
||||
double(*QDinv)[3];
|
||||
double *fc2;
|
||||
double(*svecs_fc2)[3];
|
||||
long(*multi_fc2)[2];
|
||||
double(*positions_fc2)[3];
|
||||
double *masses_fc2;
|
||||
long *p2s_fc2;
|
||||
long *s2p_fc2;
|
||||
double(*rec_lat)[3];
|
||||
double *dd_q0;
|
||||
double(*G_list)[3];
|
||||
long num_patom, num_satom, num_phonons, num_grid_points, num_G_points;
|
||||
double(*born)[3][3];
|
||||
double(*dielectric)[3];
|
||||
double *q_dir;
|
||||
double *freqs;
|
||||
lapack_complex_double *eigvecs;
|
||||
char *phonon_done;
|
||||
long *grid_points;
|
||||
long(*grid_address)[3];
|
||||
double(*QDinv)[3];
|
||||
double *fc2;
|
||||
double(*svecs_fc2)[3];
|
||||
long(*multi_fc2)[2];
|
||||
double(*positions_fc2)[3];
|
||||
double *masses_fc2;
|
||||
long *p2s_fc2;
|
||||
long *s2p_fc2;
|
||||
double(*rec_lat)[3];
|
||||
double *dd_q0;
|
||||
double(*G_list)[3];
|
||||
long num_patom, num_satom, num_phonons, num_grid_points, num_G_points;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOOdOOOOdOOds",
|
||||
&py_frequencies,
|
||||
&py_eigenvectors,
|
||||
&py_phonon_done,
|
||||
&py_grid_points,
|
||||
&py_grid_address,
|
||||
&py_QDinv,
|
||||
&py_fc2,
|
||||
&py_shortest_vectors_fc2,
|
||||
&py_multiplicity_fc2,
|
||||
&py_positions_fc2,
|
||||
&py_masses_fc2,
|
||||
&py_p2s_map_fc2,
|
||||
&py_s2p_map_fc2,
|
||||
&unit_conversion_factor,
|
||||
&py_born_effective_charge,
|
||||
&py_dielectric_constant,
|
||||
&py_reciprocal_lattice,
|
||||
&py_q_direction,
|
||||
&nac_factor,
|
||||
&py_dd_q0,
|
||||
&py_G_list,
|
||||
&lambda,
|
||||
&uplo))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
freqs = (double *)PyArray_DATA(py_frequencies);
|
||||
eigvecs = (lapack_complex_double *)PyArray_DATA(py_eigenvectors);
|
||||
phonon_done = (char *)PyArray_DATA(py_phonon_done);
|
||||
grid_points = (long *)PyArray_DATA(py_grid_points);
|
||||
grid_address = (long(*)[3])PyArray_DATA(py_grid_address);
|
||||
QDinv = (double(*)[3])PyArray_DATA(py_QDinv);
|
||||
fc2 = (double *)PyArray_DATA(py_fc2);
|
||||
svecs_fc2 = (double(*)[3])PyArray_DATA(py_shortest_vectors_fc2);
|
||||
multi_fc2 = (long(*)[2])PyArray_DATA(py_multiplicity_fc2);
|
||||
masses_fc2 = (double *)PyArray_DATA(py_masses_fc2);
|
||||
p2s_fc2 = (long *)PyArray_DATA(py_p2s_map_fc2);
|
||||
s2p_fc2 = (long *)PyArray_DATA(py_s2p_map_fc2);
|
||||
rec_lat = (double(*)[3])PyArray_DATA(py_reciprocal_lattice);
|
||||
num_patom = (long)PyArray_DIMS(py_multiplicity_fc2)[1];
|
||||
num_satom = (long)PyArray_DIMS(py_multiplicity_fc2)[0];
|
||||
num_phonons = (long)PyArray_DIMS(py_frequencies)[0];
|
||||
num_grid_points = (long)PyArray_DIMS(py_grid_points)[0];
|
||||
if ((PyObject *)py_born_effective_charge == Py_None)
|
||||
{
|
||||
born = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
born = (double(*)[3][3])PyArray_DATA(py_born_effective_charge);
|
||||
}
|
||||
if ((PyObject *)py_dielectric_constant == Py_None)
|
||||
{
|
||||
dielectric = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
dielectric = (double(*)[3])PyArray_DATA(py_dielectric_constant);
|
||||
}
|
||||
if ((PyObject *)py_q_direction == Py_None)
|
||||
{
|
||||
q_dir = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
q_dir = (double *)PyArray_DATA(py_q_direction);
|
||||
if (fabs(q_dir[0]) < 1e-10 &&
|
||||
fabs(q_dir[1]) < 1e-10 &&
|
||||
fabs(q_dir[2]) < 1e-10)
|
||||
{
|
||||
q_dir = NULL;
|
||||
if (!PyArg_ParseTuple(
|
||||
args, "OOOOOOOOOOOOOdOOOOdOOds", &py_frequencies, &py_eigenvectors,
|
||||
&py_phonon_done, &py_grid_points, &py_grid_address, &py_QDinv,
|
||||
&py_fc2, &py_shortest_vectors_fc2, &py_multiplicity_fc2,
|
||||
&py_positions_fc2, &py_masses_fc2, &py_p2s_map_fc2, &py_s2p_map_fc2,
|
||||
&unit_conversion_factor, &py_born_effective_charge,
|
||||
&py_dielectric_constant, &py_reciprocal_lattice, &py_q_direction,
|
||||
&nac_factor, &py_dd_q0, &py_G_list, &lambda, &uplo)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ((PyObject *)py_dd_q0 == Py_None)
|
||||
{
|
||||
dd_q0 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
dd_q0 = (double *)PyArray_DATA(py_dd_q0);
|
||||
}
|
||||
if ((PyObject *)py_G_list == Py_None)
|
||||
{
|
||||
G_list = NULL;
|
||||
num_G_points = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
G_list = (double(*)[3])PyArray_DATA(py_G_list);
|
||||
num_G_points = (long)PyArray_DIMS(py_G_list)[0];
|
||||
}
|
||||
if ((PyObject *)py_positions_fc2 == Py_None)
|
||||
{
|
||||
positions_fc2 = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
positions_fc2 = (double(*)[3])PyArray_DATA(py_positions_fc2);
|
||||
}
|
||||
|
||||
phmod_get_phonons_at_gridpoints(freqs,
|
||||
eigvecs,
|
||||
phonon_done,
|
||||
num_phonons,
|
||||
grid_points,
|
||||
num_grid_points,
|
||||
grid_address,
|
||||
QDinv,
|
||||
fc2,
|
||||
svecs_fc2,
|
||||
multi_fc2,
|
||||
positions_fc2,
|
||||
num_patom,
|
||||
num_satom,
|
||||
masses_fc2,
|
||||
p2s_fc2,
|
||||
s2p_fc2,
|
||||
unit_conversion_factor,
|
||||
born,
|
||||
dielectric,
|
||||
rec_lat,
|
||||
q_dir,
|
||||
nac_factor,
|
||||
dd_q0,
|
||||
G_list,
|
||||
num_G_points,
|
||||
lambda,
|
||||
uplo[0]);
|
||||
freqs = (double *)PyArray_DATA(py_frequencies);
|
||||
eigvecs = (lapack_complex_double *)PyArray_DATA(py_eigenvectors);
|
||||
phonon_done = (char *)PyArray_DATA(py_phonon_done);
|
||||
grid_points = (long *)PyArray_DATA(py_grid_points);
|
||||
grid_address = (long(*)[3])PyArray_DATA(py_grid_address);
|
||||
QDinv = (double(*)[3])PyArray_DATA(py_QDinv);
|
||||
fc2 = (double *)PyArray_DATA(py_fc2);
|
||||
svecs_fc2 = (double(*)[3])PyArray_DATA(py_shortest_vectors_fc2);
|
||||
multi_fc2 = (long(*)[2])PyArray_DATA(py_multiplicity_fc2);
|
||||
masses_fc2 = (double *)PyArray_DATA(py_masses_fc2);
|
||||
p2s_fc2 = (long *)PyArray_DATA(py_p2s_map_fc2);
|
||||
s2p_fc2 = (long *)PyArray_DATA(py_s2p_map_fc2);
|
||||
rec_lat = (double(*)[3])PyArray_DATA(py_reciprocal_lattice);
|
||||
num_patom = (long)PyArray_DIMS(py_multiplicity_fc2)[1];
|
||||
num_satom = (long)PyArray_DIMS(py_multiplicity_fc2)[0];
|
||||
num_phonons = (long)PyArray_DIMS(py_frequencies)[0];
|
||||
num_grid_points = (long)PyArray_DIMS(py_grid_points)[0];
|
||||
if ((PyObject *)py_born_effective_charge == Py_None) {
|
||||
born = NULL;
|
||||
} else {
|
||||
born = (double(*)[3][3])PyArray_DATA(py_born_effective_charge);
|
||||
}
|
||||
if ((PyObject *)py_dielectric_constant == Py_None) {
|
||||
dielectric = NULL;
|
||||
} else {
|
||||
dielectric = (double(*)[3])PyArray_DATA(py_dielectric_constant);
|
||||
}
|
||||
if ((PyObject *)py_q_direction == Py_None) {
|
||||
q_dir = NULL;
|
||||
} else {
|
||||
q_dir = (double *)PyArray_DATA(py_q_direction);
|
||||
if (fabs(q_dir[0]) < 1e-10 && fabs(q_dir[1]) < 1e-10 &&
|
||||
fabs(q_dir[2]) < 1e-10) {
|
||||
q_dir = NULL;
|
||||
}
|
||||
}
|
||||
if ((PyObject *)py_dd_q0 == Py_None) {
|
||||
dd_q0 = NULL;
|
||||
} else {
|
||||
dd_q0 = (double *)PyArray_DATA(py_dd_q0);
|
||||
}
|
||||
if ((PyObject *)py_G_list == Py_None) {
|
||||
G_list = NULL;
|
||||
num_G_points = 0;
|
||||
} else {
|
||||
G_list = (double(*)[3])PyArray_DATA(py_G_list);
|
||||
num_G_points = (long)PyArray_DIMS(py_G_list)[0];
|
||||
}
|
||||
if ((PyObject *)py_positions_fc2 == Py_None) {
|
||||
positions_fc2 = NULL;
|
||||
} else {
|
||||
positions_fc2 = (double(*)[3])PyArray_DATA(py_positions_fc2);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
phmod_get_phonons_at_gridpoints(
|
||||
freqs, eigvecs, phonon_done, num_phonons, grid_points, num_grid_points,
|
||||
grid_address, QDinv, fc2, svecs_fc2, multi_fc2, positions_fc2,
|
||||
num_patom, num_satom, masses_fc2, p2s_fc2, s2p_fc2,
|
||||
unit_conversion_factor, born, dielectric, rec_lat, q_dir, nac_factor,
|
||||
dd_q0, G_list, num_G_points, lambda, uplo[0]);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
|
824
c/bzgrid.c
824
c/bzgrid.c
|
@ -32,555 +32,373 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "bzgrid.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include "bzgrid.h"
|
||||
|
||||
#include "grgrid.h"
|
||||
#include "lagrid.h"
|
||||
|
||||
#define BZG_NUM_BZ_SEARCH_SPACE 125
|
||||
#define GRID_TOLERANCE_FACTOR 0.01
|
||||
static long bz_search_space[BZG_NUM_BZ_SEARCH_SPACE][3] = {
|
||||
{0, 0, 0},
|
||||
{0, 0, 1},
|
||||
{0, 0, 2},
|
||||
{0, 0, -2},
|
||||
{0, 0, -1},
|
||||
{0, 1, 0},
|
||||
{0, 1, 1},
|
||||
{0, 1, 2},
|
||||
{0, 1, -2},
|
||||
{0, 1, -1},
|
||||
{0, 2, 0},
|
||||
{0, 2, 1},
|
||||
{0, 2, 2},
|
||||
{0, 2, -2},
|
||||
{0, 2, -1},
|
||||
{0, -2, 0},
|
||||
{0, -2, 1},
|
||||
{0, -2, 2},
|
||||
{0, -2, -2},
|
||||
{0, -2, -1},
|
||||
{0, -1, 0},
|
||||
{0, -1, 1},
|
||||
{0, -1, 2},
|
||||
{0, -1, -2},
|
||||
{0, -1, -1},
|
||||
{1, 0, 0},
|
||||
{1, 0, 1},
|
||||
{1, 0, 2},
|
||||
{1, 0, -2},
|
||||
{1, 0, -1},
|
||||
{1, 1, 0},
|
||||
{1, 1, 1},
|
||||
{1, 1, 2},
|
||||
{1, 1, -2},
|
||||
{1, 1, -1},
|
||||
{1, 2, 0},
|
||||
{1, 2, 1},
|
||||
{1, 2, 2},
|
||||
{1, 2, -2},
|
||||
{1, 2, -1},
|
||||
{1, -2, 0},
|
||||
{1, -2, 1},
|
||||
{1, -2, 2},
|
||||
{1, -2, -2},
|
||||
{1, -2, -1},
|
||||
{1, -1, 0},
|
||||
{1, -1, 1},
|
||||
{1, -1, 2},
|
||||
{1, -1, -2},
|
||||
{1, -1, -1},
|
||||
{2, 0, 0},
|
||||
{2, 0, 1},
|
||||
{2, 0, 2},
|
||||
{2, 0, -2},
|
||||
{2, 0, -1},
|
||||
{2, 1, 0},
|
||||
{2, 1, 1},
|
||||
{2, 1, 2},
|
||||
{2, 1, -2},
|
||||
{2, 1, -1},
|
||||
{2, 2, 0},
|
||||
{2, 2, 1},
|
||||
{2, 2, 2},
|
||||
{2, 2, -2},
|
||||
{2, 2, -1},
|
||||
{2, -2, 0},
|
||||
{2, -2, 1},
|
||||
{2, -2, 2},
|
||||
{2, -2, -2},
|
||||
{2, -2, -1},
|
||||
{2, -1, 0},
|
||||
{2, -1, 1},
|
||||
{2, -1, 2},
|
||||
{2, -1, -2},
|
||||
{2, -1, -1},
|
||||
{-2, 0, 0},
|
||||
{-2, 0, 1},
|
||||
{-2, 0, 2},
|
||||
{-2, 0, -2},
|
||||
{-2, 0, -1},
|
||||
{-2, 1, 0},
|
||||
{-2, 1, 1},
|
||||
{-2, 1, 2},
|
||||
{-2, 1, -2},
|
||||
{-2, 1, -1},
|
||||
{-2, 2, 0},
|
||||
{-2, 2, 1},
|
||||
{-2, 2, 2},
|
||||
{-2, 2, -2},
|
||||
{-2, 2, -1},
|
||||
{-2, -2, 0},
|
||||
{-2, -2, 1},
|
||||
{-2, -2, 2},
|
||||
{-2, -2, -2},
|
||||
{-2, -2, -1},
|
||||
{-2, -1, 0},
|
||||
{-2, -1, 1},
|
||||
{-2, -1, 2},
|
||||
{-2, -1, -2},
|
||||
{-2, -1, -1},
|
||||
{-1, 0, 0},
|
||||
{-1, 0, 1},
|
||||
{-1, 0, 2},
|
||||
{-1, 0, -2},
|
||||
{-1, 0, -1},
|
||||
{-1, 1, 0},
|
||||
{-1, 1, 1},
|
||||
{-1, 1, 2},
|
||||
{-1, 1, -2},
|
||||
{-1, 1, -1},
|
||||
{-1, 2, 0},
|
||||
{-1, 2, 1},
|
||||
{-1, 2, 2},
|
||||
{-1, 2, -2},
|
||||
{-1, 2, -1},
|
||||
{-1, -2, 0},
|
||||
{-1, -2, 1},
|
||||
{-1, -2, 2},
|
||||
{-1, -2, -2},
|
||||
{-1, -2, -1},
|
||||
{-1, -1, 0},
|
||||
{-1, -1, 1},
|
||||
{-1, -1, 2},
|
||||
{-1, -1, -2},
|
||||
{-1, -1, -1}};
|
||||
{0, 0, 0}, {0, 0, 1}, {0, 0, 2}, {0, 0, -2}, {0, 0, -1},
|
||||
{0, 1, 0}, {0, 1, 1}, {0, 1, 2}, {0, 1, -2}, {0, 1, -1},
|
||||
{0, 2, 0}, {0, 2, 1}, {0, 2, 2}, {0, 2, -2}, {0, 2, -1},
|
||||
{0, -2, 0}, {0, -2, 1}, {0, -2, 2}, {0, -2, -2}, {0, -2, -1},
|
||||
{0, -1, 0}, {0, -1, 1}, {0, -1, 2}, {0, -1, -2}, {0, -1, -1},
|
||||
{1, 0, 0}, {1, 0, 1}, {1, 0, 2}, {1, 0, -2}, {1, 0, -1},
|
||||
{1, 1, 0}, {1, 1, 1}, {1, 1, 2}, {1, 1, -2}, {1, 1, -1},
|
||||
{1, 2, 0}, {1, 2, 1}, {1, 2, 2}, {1, 2, -2}, {1, 2, -1},
|
||||
{1, -2, 0}, {1, -2, 1}, {1, -2, 2}, {1, -2, -2}, {1, -2, -1},
|
||||
{1, -1, 0}, {1, -1, 1}, {1, -1, 2}, {1, -1, -2}, {1, -1, -1},
|
||||
{2, 0, 0}, {2, 0, 1}, {2, 0, 2}, {2, 0, -2}, {2, 0, -1},
|
||||
{2, 1, 0}, {2, 1, 1}, {2, 1, 2}, {2, 1, -2}, {2, 1, -1},
|
||||
{2, 2, 0}, {2, 2, 1}, {2, 2, 2}, {2, 2, -2}, {2, 2, -1},
|
||||
{2, -2, 0}, {2, -2, 1}, {2, -2, 2}, {2, -2, -2}, {2, -2, -1},
|
||||
{2, -1, 0}, {2, -1, 1}, {2, -1, 2}, {2, -1, -2}, {2, -1, -1},
|
||||
{-2, 0, 0}, {-2, 0, 1}, {-2, 0, 2}, {-2, 0, -2}, {-2, 0, -1},
|
||||
{-2, 1, 0}, {-2, 1, 1}, {-2, 1, 2}, {-2, 1, -2}, {-2, 1, -1},
|
||||
{-2, 2, 0}, {-2, 2, 1}, {-2, 2, 2}, {-2, 2, -2}, {-2, 2, -1},
|
||||
{-2, -2, 0}, {-2, -2, 1}, {-2, -2, 2}, {-2, -2, -2}, {-2, -2, -1},
|
||||
{-2, -1, 0}, {-2, -1, 1}, {-2, -1, 2}, {-2, -1, -2}, {-2, -1, -1},
|
||||
{-1, 0, 0}, {-1, 0, 1}, {-1, 0, 2}, {-1, 0, -2}, {-1, 0, -1},
|
||||
{-1, 1, 0}, {-1, 1, 1}, {-1, 1, 2}, {-1, 1, -2}, {-1, 1, -1},
|
||||
{-1, 2, 0}, {-1, 2, 1}, {-1, 2, 2}, {-1, 2, -2}, {-1, 2, -1},
|
||||
{-1, -2, 0}, {-1, -2, 1}, {-1, -2, 2}, {-1, -2, -2}, {-1, -2, -1},
|
||||
{-1, -1, 0}, {-1, -1, 1}, {-1, -1, 2}, {-1, -1, -2}, {-1, -1, -1}};
|
||||
|
||||
static void get_bz_grid_addresses_type1(BZGrid *bzgrid,
|
||||
const long Qinv[3][3]);
|
||||
static void get_bz_grid_addresses_type2(BZGrid *bzgrid,
|
||||
const long Qinv[3][3]);
|
||||
static void set_bz_address(long address[3],
|
||||
const long bz_index,
|
||||
const long grid_address[3],
|
||||
const long D_diag[3],
|
||||
const long nint[3],
|
||||
const long Qinv[3][3]);
|
||||
static double get_bz_distances(long nint[3],
|
||||
double distances[],
|
||||
const BZGrid *bzgrid,
|
||||
const long grid_address[3],
|
||||
static void get_bz_grid_addresses_type1(BZGrid *bzgrid, const long Qinv[3][3]);
|
||||
static void get_bz_grid_addresses_type2(BZGrid *bzgrid, const long Qinv[3][3]);
|
||||
static void set_bz_address(long address[3], const long bz_index,
|
||||
const long grid_address[3], const long D_diag[3],
|
||||
const long nint[3], const long Qinv[3][3]);
|
||||
static double get_bz_distances(long nint[3], double distances[],
|
||||
const BZGrid *bzgrid, const long grid_address[3],
|
||||
const double tolerance);
|
||||
static void multiply_matrix_vector_d3(double v[3],
|
||||
const double a[3][3],
|
||||
static void multiply_matrix_vector_d3(double v[3], const double a[3][3],
|
||||
const double b[3]);
|
||||
static long get_inverse_unimodular_matrix_l3(long m[3][3],
|
||||
const long a[3][3]);
|
||||
static long get_inverse_unimodular_matrix_l3(long m[3][3], const long a[3][3]);
|
||||
static double norm_squared_d3(const double a[3]);
|
||||
|
||||
long bzg_rotate_grid_index(const long bz_grid_index,
|
||||
const long rotation[3][3],
|
||||
const ConstBZGrid *bzgrid)
|
||||
{
|
||||
long i, gp, num_bzgp, num_grgp;
|
||||
long dadrs[3], dadrs_rot[3], adrs_rot[3];
|
||||
long bzg_rotate_grid_index(const long bz_grid_index, const long rotation[3][3],
|
||||
const ConstBZGrid *bzgrid) {
|
||||
long i, gp, num_bzgp, num_grgp;
|
||||
long dadrs[3], dadrs_rot[3], adrs_rot[3];
|
||||
|
||||
grg_get_double_grid_address(dadrs, bzgrid->addresses[bz_grid_index], bzgrid->PS);
|
||||
lagmat_multiply_matrix_vector_l3(dadrs_rot, rotation, dadrs);
|
||||
grg_get_grid_address(adrs_rot, dadrs_rot, bzgrid->PS);
|
||||
gp = grg_get_grid_index(adrs_rot, bzgrid->D_diag);
|
||||
grg_get_double_grid_address(dadrs, bzgrid->addresses[bz_grid_index],
|
||||
bzgrid->PS);
|
||||
lagmat_multiply_matrix_vector_l3(dadrs_rot, rotation, dadrs);
|
||||
grg_get_grid_address(adrs_rot, dadrs_rot, bzgrid->PS);
|
||||
gp = grg_get_grid_index(adrs_rot, bzgrid->D_diag);
|
||||
|
||||
if (bzgrid->type == 1)
|
||||
{
|
||||
if (bzgrid->addresses[gp][0] == adrs_rot[0] &&
|
||||
bzgrid->addresses[gp][1] == adrs_rot[1] &&
|
||||
bzgrid->addresses[gp][2] == adrs_rot[2])
|
||||
{
|
||||
return gp;
|
||||
if (bzgrid->type == 1) {
|
||||
if (bzgrid->addresses[gp][0] == adrs_rot[0] &&
|
||||
bzgrid->addresses[gp][1] == adrs_rot[1] &&
|
||||
bzgrid->addresses[gp][2] == adrs_rot[2]) {
|
||||
return gp;
|
||||
}
|
||||
num_grgp = bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
num_bzgp = num_grgp * 8;
|
||||
for (i = bzgrid->gp_map[num_bzgp + gp] + num_grgp;
|
||||
i < bzgrid->gp_map[num_bzgp + gp + 1] + num_grgp; i++) {
|
||||
if (bzgrid->addresses[i][0] == adrs_rot[0] &&
|
||||
bzgrid->addresses[i][1] == adrs_rot[1] &&
|
||||
bzgrid->addresses[i][2] == adrs_rot[2]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = bzgrid->gp_map[gp]; i < bzgrid->gp_map[gp + 1]; i++) {
|
||||
if (bzgrid->addresses[i][0] == adrs_rot[0] &&
|
||||
bzgrid->addresses[i][1] == adrs_rot[1] &&
|
||||
bzgrid->addresses[i][2] == adrs_rot[2]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
num_grgp = bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
num_bzgp = num_grgp * 8;
|
||||
for (i = bzgrid->gp_map[num_bzgp + gp] + num_grgp;
|
||||
i < bzgrid->gp_map[num_bzgp + gp + 1] + num_grgp; i++)
|
||||
{
|
||||
if (bzgrid->addresses[i][0] == adrs_rot[0] &&
|
||||
bzgrid->addresses[i][1] == adrs_rot[1] &&
|
||||
bzgrid->addresses[i][2] == adrs_rot[2])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = bzgrid->gp_map[gp]; i < bzgrid->gp_map[gp + 1]; i++)
|
||||
{
|
||||
if (bzgrid->addresses[i][0] == adrs_rot[0] &&
|
||||
bzgrid->addresses[i][1] == adrs_rot[1] &&
|
||||
bzgrid->addresses[i][2] == adrs_rot[2])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This should not happen, but possible when bzgrid is ill-defined. */
|
||||
return bzgrid->gp_map[gp];
|
||||
/* This should not happen, but possible when bzgrid is ill-defined. */
|
||||
return bzgrid->gp_map[gp];
|
||||
}
|
||||
|
||||
long bzg_get_bz_grid_addresses(BZGrid *bzgrid)
|
||||
{
|
||||
long det;
|
||||
long Qinv[3][3];
|
||||
long bzg_get_bz_grid_addresses(BZGrid *bzgrid) {
|
||||
long det;
|
||||
long Qinv[3][3];
|
||||
|
||||
det = get_inverse_unimodular_matrix_l3(Qinv, bzgrid->Q);
|
||||
if (det == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
det = get_inverse_unimodular_matrix_l3(Qinv, bzgrid->Q);
|
||||
if (det == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bzgrid->type == 1)
|
||||
{
|
||||
get_bz_grid_addresses_type1(bzgrid, Qinv);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_bz_grid_addresses_type2(bzgrid, Qinv);
|
||||
}
|
||||
if (bzgrid->type == 1) {
|
||||
get_bz_grid_addresses_type1(bzgrid, Qinv);
|
||||
} else {
|
||||
get_bz_grid_addresses_type2(bzgrid, Qinv);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Note: Tolerance in squared distance. */
|
||||
double bzg_get_tolerance_for_BZ_reduction(const BZGrid *bzgrid)
|
||||
{
|
||||
long i, j;
|
||||
double tolerance;
|
||||
double length[3];
|
||||
double reclatQ[3][3];
|
||||
double bzg_get_tolerance_for_BZ_reduction(const BZGrid *bzgrid) {
|
||||
long i, j;
|
||||
double tolerance;
|
||||
double length[3];
|
||||
double reclatQ[3][3];
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
reclatQ[i][j] =
|
||||
bzgrid->reclat[i][0] * bzgrid->Q[0][j] + bzgrid->reclat[i][1] * bzgrid->Q[1][j] + bzgrid->reclat[i][2] * bzgrid->Q[2][j];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
length[i] = 0;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
length[i] += reclatQ[j][i] * reclatQ[j][i];
|
||||
}
|
||||
length[i] /= bzgrid->D_diag[i] * bzgrid->D_diag[i];
|
||||
}
|
||||
tolerance = length[0];
|
||||
for (i = 1; i < 3; i++)
|
||||
{
|
||||
if (tolerance < length[i])
|
||||
{
|
||||
tolerance = length[i];
|
||||
}
|
||||
}
|
||||
tolerance *= GRID_TOLERANCE_FACTOR;
|
||||
|
||||
return tolerance;
|
||||
}
|
||||
|
||||
RotMats *bzg_alloc_RotMats(const long size)
|
||||
{
|
||||
RotMats *rotmats;
|
||||
|
||||
rotmats = NULL;
|
||||
|
||||
if ((rotmats = (RotMats *)malloc(sizeof(RotMats))) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rotmats->size = size;
|
||||
if (size > 0)
|
||||
{
|
||||
if ((rotmats->mat = (long(*)[3][3])malloc(sizeof(long[3][3]) * size)) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated ");
|
||||
warning_print("(RotMats, line %d, %s).\n", __LINE__, __FILE__);
|
||||
free(rotmats);
|
||||
rotmats = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return rotmats;
|
||||
}
|
||||
|
||||
void bzg_free_RotMats(RotMats *rotmats)
|
||||
{
|
||||
if (rotmats->size > 0)
|
||||
{
|
||||
free(rotmats->mat);
|
||||
rotmats->mat = NULL;
|
||||
}
|
||||
free(rotmats);
|
||||
}
|
||||
|
||||
void bzg_multiply_matrix_vector_ld3(double v[3],
|
||||
const long a[3][3],
|
||||
const double b[3])
|
||||
{
|
||||
long i;
|
||||
double c[3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
v[i] = c[i];
|
||||
}
|
||||
}
|
||||
|
||||
static void get_bz_grid_addresses_type1(BZGrid *bzgrid,
|
||||
const long Qinv[3][3])
|
||||
{
|
||||
double tolerance, min_distance;
|
||||
double distances[BZG_NUM_BZ_SEARCH_SPACE];
|
||||
long bzmesh[3], bz_address_double[3], nint[3], gr_adrs[3];
|
||||
long i, j, k, boundary_num_gp, total_num_gp, bzgp, gp, num_bzmesh;
|
||||
long count, id_shift;
|
||||
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction(bzgrid);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bzmesh[j] = bzgrid->D_diag[j] * 2;
|
||||
}
|
||||
|
||||
num_bzmesh = bzmesh[0] * bzmesh[1] * bzmesh[2];
|
||||
for (i = 0; i < num_bzmesh; i++)
|
||||
{
|
||||
bzgrid->gp_map[i] = num_bzmesh;
|
||||
}
|
||||
|
||||
boundary_num_gp = 0;
|
||||
total_num_gp = bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
|
||||
/* Multithreading doesn't work for this loop since gp calculated */
|
||||
/* with boundary_num_gp is unstable to store bz_grid_address. */
|
||||
bzgrid->gp_map[num_bzmesh] = 0;
|
||||
id_shift = 0;
|
||||
for (i = 0; i < total_num_gp; i++)
|
||||
{
|
||||
grg_get_grid_address_from_index(gr_adrs, i, bzgrid->D_diag);
|
||||
min_distance = get_bz_distances(nint, distances, bzgrid,
|
||||
gr_adrs, tolerance);
|
||||
count = 0;
|
||||
for (j = 0; j < BZG_NUM_BZ_SEARCH_SPACE; j++)
|
||||
{
|
||||
if (distances[j] < min_distance + tolerance)
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
gp = i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
reclatQ[i][j] = bzgrid->reclat[i][0] * bzgrid->Q[0][j] +
|
||||
bzgrid->reclat[i][1] * bzgrid->Q[1][j] +
|
||||
bzgrid->reclat[i][2] * bzgrid->Q[2][j];
|
||||
}
|
||||
else
|
||||
{
|
||||
gp = boundary_num_gp + total_num_gp;
|
||||
boundary_num_gp++;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
length[i] = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
length[i] += reclatQ[j][i] * reclatQ[j][i];
|
||||
}
|
||||
count++;
|
||||
set_bz_address(bzgrid->addresses[gp],
|
||||
j,
|
||||
gr_adrs,
|
||||
bzgrid->D_diag,
|
||||
nint,
|
||||
Qinv);
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
bz_address_double[k] = bzgrid->addresses[gp][k] * 2 + bzgrid->PS[k];
|
||||
length[i] /= bzgrid->D_diag[i] * bzgrid->D_diag[i];
|
||||
}
|
||||
tolerance = length[0];
|
||||
for (i = 1; i < 3; i++) {
|
||||
if (tolerance < length[i]) {
|
||||
tolerance = length[i];
|
||||
}
|
||||
bzgp = grg_get_double_grid_index(
|
||||
bz_address_double, bzmesh, bzgrid->PS);
|
||||
bzgrid->gp_map[bzgp] = gp;
|
||||
bzgrid->bzg2grg[gp] = i;
|
||||
}
|
||||
}
|
||||
/* This is used in get_BZ_triplets_at_q_type1. */
|
||||
/* The first one among those found is treated specially, so */
|
||||
/* excluded from the gp_map address shift by -1. */
|
||||
id_shift += count - 1;
|
||||
bzgrid->gp_map[num_bzmesh + i + 1] = id_shift;
|
||||
}
|
||||
bzgrid->size = boundary_num_gp + total_num_gp;
|
||||
tolerance *= GRID_TOLERANCE_FACTOR;
|
||||
|
||||
return tolerance;
|
||||
}
|
||||
|
||||
static void get_bz_grid_addresses_type2(BZGrid *bzgrid,
|
||||
const long Qinv[3][3])
|
||||
{
|
||||
double tolerance, min_distance;
|
||||
double distances[BZG_NUM_BZ_SEARCH_SPACE];
|
||||
long nint[3], gr_adrs[3];
|
||||
long i, j, num_gp;
|
||||
RotMats *bzg_alloc_RotMats(const long size) {
|
||||
RotMats *rotmats;
|
||||
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction(bzgrid);
|
||||
num_gp = 0;
|
||||
/* The first element of gp_map is always 0. */
|
||||
bzgrid->gp_map[0] = 0;
|
||||
rotmats = NULL;
|
||||
|
||||
for (i = 0;
|
||||
i < bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2]; i++)
|
||||
{
|
||||
grg_get_grid_address_from_index(gr_adrs, i, bzgrid->D_diag);
|
||||
min_distance = get_bz_distances(nint, distances, bzgrid,
|
||||
gr_adrs, tolerance);
|
||||
for (j = 0; j < BZG_NUM_BZ_SEARCH_SPACE; j++)
|
||||
{
|
||||
if (distances[j] < min_distance + tolerance)
|
||||
{
|
||||
set_bz_address(bzgrid->addresses[num_gp],
|
||||
j,
|
||||
gr_adrs,
|
||||
bzgrid->D_diag,
|
||||
nint,
|
||||
Qinv);
|
||||
bzgrid->bzg2grg[num_gp] = i;
|
||||
num_gp++;
|
||||
}
|
||||
if ((rotmats = (RotMats *)malloc(sizeof(RotMats))) == NULL) {
|
||||
warning_print("Memory could not be allocated.");
|
||||
return NULL;
|
||||
}
|
||||
bzgrid->gp_map[i + 1] = num_gp;
|
||||
}
|
||||
|
||||
bzgrid->size = num_gp;
|
||||
}
|
||||
|
||||
static void set_bz_address(long address[3],
|
||||
const long bz_index,
|
||||
const long grid_address[3],
|
||||
const long D_diag[3],
|
||||
const long nint[3],
|
||||
const long Qinv[3][3])
|
||||
{
|
||||
long i;
|
||||
long deltaG[3];
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
deltaG[i] = bz_search_space[bz_index][i] - nint[i];
|
||||
}
|
||||
lagmat_multiply_matrix_vector_l3(deltaG, Qinv, deltaG);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
address[i] = grid_address[i] + deltaG[i] * D_diag[i];
|
||||
}
|
||||
}
|
||||
|
||||
static double get_bz_distances(long nint[3],
|
||||
double distances[],
|
||||
const BZGrid *bzgrid,
|
||||
const long grid_address[3],
|
||||
const double tolerance)
|
||||
{
|
||||
long i, j;
|
||||
long dadrs[3];
|
||||
double min_distance;
|
||||
double q_vec[3], q_red[3];
|
||||
|
||||
grg_get_double_grid_address(dadrs, grid_address, bzgrid->PS);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
q_red[i] = dadrs[i] / (2.0 * bzgrid->D_diag[i]);
|
||||
}
|
||||
bzg_multiply_matrix_vector_ld3(q_red, bzgrid->Q, q_red);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
nint[i] = lagmat_Nint(q_red[i]);
|
||||
q_red[i] -= nint[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < BZG_NUM_BZ_SEARCH_SPACE; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
q_vec[j] = q_red[j] + bz_search_space[i][j];
|
||||
rotmats->size = size;
|
||||
if (size > 0) {
|
||||
if ((rotmats->mat = (long(*)[3][3])malloc(sizeof(long[3][3]) * size)) ==
|
||||
NULL) {
|
||||
warning_print("Memory could not be allocated ");
|
||||
warning_print("(RotMats, line %d, %s).\n", __LINE__, __FILE__);
|
||||
free(rotmats);
|
||||
rotmats = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
multiply_matrix_vector_d3(q_vec, bzgrid->reclat, q_vec);
|
||||
distances[i] = norm_squared_d3(q_vec);
|
||||
}
|
||||
return rotmats;
|
||||
}
|
||||
|
||||
/* Use of tolerance is important to select first one among similar
|
||||
* distances. Otherwise the choice of bz grid address among
|
||||
* those translationally equivalent can change by very tiny numerical
|
||||
* fluctuation. */
|
||||
min_distance = distances[0];
|
||||
for (i = 1; i < BZG_NUM_BZ_SEARCH_SPACE; i++)
|
||||
{
|
||||
if (distances[i] < min_distance - tolerance)
|
||||
{
|
||||
min_distance = distances[i];
|
||||
void bzg_free_RotMats(RotMats *rotmats) {
|
||||
if (rotmats->size > 0) {
|
||||
free(rotmats->mat);
|
||||
rotmats->mat = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return min_distance;
|
||||
free(rotmats);
|
||||
}
|
||||
|
||||
static void multiply_matrix_vector_d3(double v[3],
|
||||
const double a[3][3],
|
||||
const double b[3])
|
||||
{
|
||||
long i;
|
||||
double c[3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
v[i] = c[i];
|
||||
}
|
||||
void bzg_multiply_matrix_vector_ld3(double v[3], const long a[3][3],
|
||||
const double b[3]) {
|
||||
long i;
|
||||
double c[3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
v[i] = c[i];
|
||||
}
|
||||
}
|
||||
|
||||
static long get_inverse_unimodular_matrix_l3(long m[3][3],
|
||||
const long a[3][3])
|
||||
{
|
||||
long det;
|
||||
long c[3][3];
|
||||
static void get_bz_grid_addresses_type1(BZGrid *bzgrid, const long Qinv[3][3]) {
|
||||
double tolerance, min_distance;
|
||||
double distances[BZG_NUM_BZ_SEARCH_SPACE];
|
||||
long bzmesh[3], bz_address_double[3], nint[3], gr_adrs[3];
|
||||
long i, j, k, boundary_num_gp, total_num_gp, bzgp, gp, num_bzmesh;
|
||||
long count, id_shift;
|
||||
|
||||
det = lagmat_get_determinant_l3(a);
|
||||
if (labs(det) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction(bzgrid);
|
||||
for (j = 0; j < 3; j++) {
|
||||
bzmesh[j] = bzgrid->D_diag[j] * 2;
|
||||
}
|
||||
|
||||
c[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det;
|
||||
c[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det;
|
||||
c[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det;
|
||||
c[0][1] = (a[2][1] * a[0][2] - a[2][2] * a[0][1]) / det;
|
||||
c[1][1] = (a[2][2] * a[0][0] - a[2][0] * a[0][2]) / det;
|
||||
c[2][1] = (a[2][0] * a[0][1] - a[2][1] * a[0][0]) / det;
|
||||
c[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det;
|
||||
c[1][2] = (a[0][2] * a[1][0] - a[0][0] * a[1][2]) / det;
|
||||
c[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det;
|
||||
lagmat_copy_matrix_l3(m, c);
|
||||
num_bzmesh = bzmesh[0] * bzmesh[1] * bzmesh[2];
|
||||
for (i = 0; i < num_bzmesh; i++) {
|
||||
bzgrid->gp_map[i] = num_bzmesh;
|
||||
}
|
||||
|
||||
return det;
|
||||
boundary_num_gp = 0;
|
||||
total_num_gp = bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
|
||||
/* Multithreading doesn't work for this loop since gp calculated */
|
||||
/* with boundary_num_gp is unstable to store bz_grid_address. */
|
||||
bzgrid->gp_map[num_bzmesh] = 0;
|
||||
id_shift = 0;
|
||||
for (i = 0; i < total_num_gp; i++) {
|
||||
grg_get_grid_address_from_index(gr_adrs, i, bzgrid->D_diag);
|
||||
min_distance =
|
||||
get_bz_distances(nint, distances, bzgrid, gr_adrs, tolerance);
|
||||
count = 0;
|
||||
for (j = 0; j < BZG_NUM_BZ_SEARCH_SPACE; j++) {
|
||||
if (distances[j] < min_distance + tolerance) {
|
||||
if (count == 0) {
|
||||
gp = i;
|
||||
} else {
|
||||
gp = boundary_num_gp + total_num_gp;
|
||||
boundary_num_gp++;
|
||||
}
|
||||
count++;
|
||||
set_bz_address(bzgrid->addresses[gp], j, gr_adrs,
|
||||
bzgrid->D_diag, nint, Qinv);
|
||||
for (k = 0; k < 3; k++) {
|
||||
bz_address_double[k] =
|
||||
bzgrid->addresses[gp][k] * 2 + bzgrid->PS[k];
|
||||
}
|
||||
bzgp = grg_get_double_grid_index(bz_address_double, bzmesh,
|
||||
bzgrid->PS);
|
||||
bzgrid->gp_map[bzgp] = gp;
|
||||
bzgrid->bzg2grg[gp] = i;
|
||||
}
|
||||
}
|
||||
/* This is used in get_BZ_triplets_at_q_type1. */
|
||||
/* The first one among those found is treated specially, so */
|
||||
/* excluded from the gp_map address shift by -1. */
|
||||
id_shift += count - 1;
|
||||
bzgrid->gp_map[num_bzmesh + i + 1] = id_shift;
|
||||
}
|
||||
bzgrid->size = boundary_num_gp + total_num_gp;
|
||||
}
|
||||
|
||||
static double norm_squared_d3(const double a[3])
|
||||
{
|
||||
return a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
|
||||
static void get_bz_grid_addresses_type2(BZGrid *bzgrid, const long Qinv[3][3]) {
|
||||
double tolerance, min_distance;
|
||||
double distances[BZG_NUM_BZ_SEARCH_SPACE];
|
||||
long nint[3], gr_adrs[3];
|
||||
long i, j, num_gp;
|
||||
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction(bzgrid);
|
||||
num_gp = 0;
|
||||
/* The first element of gp_map is always 0. */
|
||||
bzgrid->gp_map[0] = 0;
|
||||
|
||||
for (i = 0; i < bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
i++) {
|
||||
grg_get_grid_address_from_index(gr_adrs, i, bzgrid->D_diag);
|
||||
min_distance =
|
||||
get_bz_distances(nint, distances, bzgrid, gr_adrs, tolerance);
|
||||
for (j = 0; j < BZG_NUM_BZ_SEARCH_SPACE; j++) {
|
||||
if (distances[j] < min_distance + tolerance) {
|
||||
set_bz_address(bzgrid->addresses[num_gp], j, gr_adrs,
|
||||
bzgrid->D_diag, nint, Qinv);
|
||||
bzgrid->bzg2grg[num_gp] = i;
|
||||
num_gp++;
|
||||
}
|
||||
}
|
||||
bzgrid->gp_map[i + 1] = num_gp;
|
||||
}
|
||||
|
||||
bzgrid->size = num_gp;
|
||||
}
|
||||
|
||||
static void set_bz_address(long address[3], const long bz_index,
|
||||
const long grid_address[3], const long D_diag[3],
|
||||
const long nint[3], const long Qinv[3][3]) {
|
||||
long i;
|
||||
long deltaG[3];
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
deltaG[i] = bz_search_space[bz_index][i] - nint[i];
|
||||
}
|
||||
lagmat_multiply_matrix_vector_l3(deltaG, Qinv, deltaG);
|
||||
for (i = 0; i < 3; i++) {
|
||||
address[i] = grid_address[i] + deltaG[i] * D_diag[i];
|
||||
}
|
||||
}
|
||||
|
||||
static double get_bz_distances(long nint[3], double distances[],
|
||||
const BZGrid *bzgrid, const long grid_address[3],
|
||||
const double tolerance) {
|
||||
long i, j;
|
||||
long dadrs[3];
|
||||
double min_distance;
|
||||
double q_vec[3], q_red[3];
|
||||
|
||||
grg_get_double_grid_address(dadrs, grid_address, bzgrid->PS);
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
q_red[i] = dadrs[i] / (2.0 * bzgrid->D_diag[i]);
|
||||
}
|
||||
bzg_multiply_matrix_vector_ld3(q_red, bzgrid->Q, q_red);
|
||||
for (i = 0; i < 3; i++) {
|
||||
nint[i] = lagmat_Nint(q_red[i]);
|
||||
q_red[i] -= nint[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < BZG_NUM_BZ_SEARCH_SPACE; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
q_vec[j] = q_red[j] + bz_search_space[i][j];
|
||||
}
|
||||
multiply_matrix_vector_d3(q_vec, bzgrid->reclat, q_vec);
|
||||
distances[i] = norm_squared_d3(q_vec);
|
||||
}
|
||||
|
||||
/* Use of tolerance is important to select first one among similar
|
||||
* distances. Otherwise the choice of bz grid address among
|
||||
* those translationally equivalent can change by very tiny numerical
|
||||
* fluctuation. */
|
||||
min_distance = distances[0];
|
||||
for (i = 1; i < BZG_NUM_BZ_SEARCH_SPACE; i++) {
|
||||
if (distances[i] < min_distance - tolerance) {
|
||||
min_distance = distances[i];
|
||||
}
|
||||
}
|
||||
|
||||
return min_distance;
|
||||
}
|
||||
|
||||
static void multiply_matrix_vector_d3(double v[3], const double a[3][3],
|
||||
const double b[3]) {
|
||||
long i;
|
||||
double c[3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
v[i] = c[i];
|
||||
}
|
||||
}
|
||||
|
||||
static long get_inverse_unimodular_matrix_l3(long m[3][3], const long a[3][3]) {
|
||||
long det;
|
||||
long c[3][3];
|
||||
|
||||
det = lagmat_get_determinant_l3(a);
|
||||
if (labs(det) != 1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
c[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det;
|
||||
c[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det;
|
||||
c[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det;
|
||||
c[0][1] = (a[2][1] * a[0][2] - a[2][2] * a[0][1]) / det;
|
||||
c[1][1] = (a[2][2] * a[0][0] - a[2][0] * a[0][2]) / det;
|
||||
c[2][1] = (a[2][0] * a[0][1] - a[2][1] * a[0][0]) / det;
|
||||
c[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det;
|
||||
c[1][2] = (a[0][2] * a[1][0] - a[0][0] * a[1][2]) / det;
|
||||
c[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det;
|
||||
lagmat_copy_matrix_l3(m, c);
|
||||
|
||||
return det;
|
||||
}
|
||||
|
||||
static double norm_squared_d3(const double a[3]) {
|
||||
return a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
|
||||
}
|
||||
|
|
55
c/bzgrid.h
55
c/bzgrid.h
|
@ -35,10 +35,9 @@
|
|||
#ifndef __bzgrid_H__
|
||||
#define __bzgrid_H__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long size;
|
||||
long (*mat)[3][3];
|
||||
typedef struct {
|
||||
long size;
|
||||
long (*mat)[3][3];
|
||||
} RotMats;
|
||||
|
||||
/* Data structure of Brillouin zone grid
|
||||
|
@ -68,41 +67,37 @@ typedef struct
|
|||
* shape=(3, 3)
|
||||
* type : long
|
||||
* 1 or 2. */
|
||||
typedef struct
|
||||
{
|
||||
long size;
|
||||
long D_diag[3];
|
||||
long Q[3][3];
|
||||
long PS[3];
|
||||
long *gp_map;
|
||||
long *bzg2grg;
|
||||
long (*addresses)[3];
|
||||
double reclat[3][3];
|
||||
long type;
|
||||
typedef struct {
|
||||
long size;
|
||||
long D_diag[3];
|
||||
long Q[3][3];
|
||||
long PS[3];
|
||||
long *gp_map;
|
||||
long *bzg2grg;
|
||||
long (*addresses)[3];
|
||||
double reclat[3][3];
|
||||
long type;
|
||||
} BZGrid;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
long size;
|
||||
long D_diag[3];
|
||||
long Q[3][3];
|
||||
long PS[3];
|
||||
const long *gp_map;
|
||||
const long *bzg2grg;
|
||||
const long (*addresses)[3];
|
||||
double reclat[3][3];
|
||||
long type;
|
||||
typedef struct {
|
||||
long size;
|
||||
long D_diag[3];
|
||||
long Q[3][3];
|
||||
long PS[3];
|
||||
const long *gp_map;
|
||||
const long *bzg2grg;
|
||||
const long (*addresses)[3];
|
||||
double reclat[3][3];
|
||||
long type;
|
||||
} ConstBZGrid;
|
||||
|
||||
long bzg_rotate_grid_index(const long grid_index,
|
||||
const long rotation[3][3],
|
||||
long bzg_rotate_grid_index(const long grid_index, const long rotation[3][3],
|
||||
const ConstBZGrid *bzgrid);
|
||||
long bzg_get_bz_grid_addresses(BZGrid *bzgrid);
|
||||
double bzg_get_tolerance_for_BZ_reduction(const BZGrid *bzgrid);
|
||||
RotMats *bzg_alloc_RotMats(const long size);
|
||||
void bzg_free_RotMats(RotMats *rotmats);
|
||||
void bzg_multiply_matrix_vector_ld3(double v[3],
|
||||
const long a[3][3],
|
||||
void bzg_multiply_matrix_vector_ld3(double v[3], const long a[3][3],
|
||||
const double b[3]);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,343 +32,255 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "phonoc_array.h"
|
||||
#include "phonoc_utils.h"
|
||||
#include "collision_matrix.h"
|
||||
|
||||
static void get_collision_matrix(double *collision_matrix,
|
||||
const double *fc3_normal_squared,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long num_gp,
|
||||
const long *map_q,
|
||||
const long *rot_grid_points,
|
||||
const long num_ir_gp,
|
||||
const long num_rot,
|
||||
const double *rotations_cartesian,
|
||||
const double *g,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
static void
|
||||
get_reducible_collision_matrix(double *collision_matrix,
|
||||
const double *fc3_normal_squared,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long num_gp,
|
||||
const long *map_q,
|
||||
const double *g,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
static void get_inv_sinh(double *inv_sinh,
|
||||
const long gp,
|
||||
const double temperature,
|
||||
const double *frequencies,
|
||||
const long triplet[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const long num_band,
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "phonoc_array.h"
|
||||
#include "phonoc_utils.h"
|
||||
|
||||
static void get_collision_matrix(
|
||||
double *collision_matrix, const double *fc3_normal_squared,
|
||||
const long num_band0, const long num_band, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplets_map, const long num_gp,
|
||||
const long *map_q, const long *rot_grid_points, const long num_ir_gp,
|
||||
const long num_rot, const double *rotations_cartesian, const double *g,
|
||||
const double temperature, const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
static void get_reducible_collision_matrix(
|
||||
double *collision_matrix, const double *fc3_normal_squared,
|
||||
const long num_band0, const long num_band, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplets_map, const long num_gp,
|
||||
const long *map_q, const double *g, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
static long get_inv_sinh(double *inv_sinh, const long gp,
|
||||
const double temperature, const double *frequencies,
|
||||
const long triplet[3], const long *triplets_map,
|
||||
const long *map_q, const long num_band,
|
||||
const double cutoff_frequency);
|
||||
static long *create_gp2tp_map(const long *triplets_map,
|
||||
const long num_gp);
|
||||
static long *create_gp2tp_map(const long *triplets_map, const long num_gp);
|
||||
|
||||
void col_get_collision_matrix(double *collision_matrix,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const long *rot_grid_points,
|
||||
const double *rotations_cartesian,
|
||||
const double *g,
|
||||
const long num_ir_gp,
|
||||
const long num_gp,
|
||||
const long num_rot,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long num_triplets, num_band0, num_band;
|
||||
void col_get_collision_matrix(
|
||||
double *collision_matrix, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplets_map, const long *map_q, const long *rot_grid_points,
|
||||
const double *rotations_cartesian, const double *g, const long num_ir_gp,
|
||||
const long num_gp, const long num_rot, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency) {
|
||||
long num_triplets, num_band0, num_band;
|
||||
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
|
||||
get_collision_matrix(
|
||||
collision_matrix,
|
||||
fc3_normal_squared->data,
|
||||
num_band0,
|
||||
num_band,
|
||||
frequencies,
|
||||
triplets,
|
||||
triplets_map,
|
||||
num_gp,
|
||||
map_q,
|
||||
rot_grid_points,
|
||||
num_ir_gp,
|
||||
num_rot,
|
||||
rotations_cartesian,
|
||||
g + 2 * num_triplets * num_band0 * num_band * num_band,
|
||||
temperature,
|
||||
unit_conversion_factor,
|
||||
cutoff_frequency);
|
||||
get_collision_matrix(collision_matrix, fc3_normal_squared->data, num_band0,
|
||||
num_band, frequencies, triplets, triplets_map, num_gp,
|
||||
map_q, rot_grid_points, num_ir_gp, num_rot,
|
||||
rotations_cartesian,
|
||||
g + 2 * num_triplets * num_band0 * num_band * num_band,
|
||||
temperature, unit_conversion_factor, cutoff_frequency);
|
||||
}
|
||||
|
||||
void col_get_reducible_collision_matrix(double *collision_matrix,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const double *g,
|
||||
const long num_gp,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long num_triplets, num_band, num_band0;
|
||||
void col_get_reducible_collision_matrix(
|
||||
double *collision_matrix, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplets_map, const long *map_q, const double *g,
|
||||
const long num_gp, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency) {
|
||||
long num_triplets, num_band, num_band0;
|
||||
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
|
||||
get_reducible_collision_matrix(
|
||||
collision_matrix,
|
||||
fc3_normal_squared->data,
|
||||
num_band0,
|
||||
num_band,
|
||||
frequencies,
|
||||
triplets,
|
||||
triplets_map,
|
||||
num_gp,
|
||||
map_q,
|
||||
g + 2 * num_triplets * num_band0 * num_band * num_band,
|
||||
temperature,
|
||||
unit_conversion_factor,
|
||||
cutoff_frequency);
|
||||
get_reducible_collision_matrix(
|
||||
collision_matrix, fc3_normal_squared->data, num_band0, num_band,
|
||||
frequencies, triplets, triplets_map, num_gp, map_q,
|
||||
g + 2 * num_triplets * num_band0 * num_band * num_band, temperature,
|
||||
unit_conversion_factor, cutoff_frequency);
|
||||
}
|
||||
|
||||
static void get_collision_matrix(double *collision_matrix,
|
||||
const double *fc3_normal_squared,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long num_gp,
|
||||
const long *map_q,
|
||||
const long *rot_grid_points,
|
||||
const long num_ir_gp,
|
||||
const long num_rot,
|
||||
const double *rotations_cartesian,
|
||||
const double *g,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j, k, l, m, n, ti, r_gp;
|
||||
long *gp2tp_map;
|
||||
double collision;
|
||||
double *inv_sinh;
|
||||
static void get_collision_matrix(
|
||||
double *collision_matrix, const double *fc3_normal_squared,
|
||||
const long num_band0, const long num_band, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplets_map, const long num_gp,
|
||||
const long *map_q, const long *rot_grid_points, const long num_ir_gp,
|
||||
const long num_rot, const double *rotations_cartesian, const double *g,
|
||||
const double temperature, const double unit_conversion_factor,
|
||||
const double cutoff_frequency) {
|
||||
long i, j, k, l, m, n, ti, r_gp, swapped;
|
||||
long *gp2tp_map;
|
||||
double collision;
|
||||
double *inv_sinh;
|
||||
|
||||
gp2tp_map = create_gp2tp_map(triplets_map, num_gp);
|
||||
gp2tp_map = create_gp2tp_map(triplets_map, num_gp);
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, k, l, m, n, ti, r_gp, collision, inv_sinh)
|
||||
#endif
|
||||
for (i = 0; i < num_ir_gp; i++)
|
||||
{
|
||||
inv_sinh = (double *)malloc(sizeof(double) * num_band);
|
||||
for (j = 0; j < num_rot; j++)
|
||||
{
|
||||
r_gp = rot_grid_points[i * num_rot + j];
|
||||
ti = gp2tp_map[triplets_map[r_gp]];
|
||||
get_inv_sinh(inv_sinh,
|
||||
r_gp,
|
||||
temperature,
|
||||
frequencies,
|
||||
triplets[ti],
|
||||
triplets_map,
|
||||
map_q,
|
||||
num_band,
|
||||
cutoff_frequency);
|
||||
for (i = 0; i < num_ir_gp; i++) {
|
||||
inv_sinh = (double *)malloc(sizeof(double) * num_band);
|
||||
for (j = 0; j < num_rot; j++) {
|
||||
r_gp = rot_grid_points[i * num_rot + j];
|
||||
ti = gp2tp_map[triplets_map[r_gp]];
|
||||
swapped = get_inv_sinh(inv_sinh, r_gp, temperature, frequencies,
|
||||
triplets[ti], triplets_map, map_q, num_band,
|
||||
cutoff_frequency);
|
||||
|
||||
for (k = 0; k < num_band0; k++)
|
||||
{
|
||||
for (l = 0; l < num_band; l++)
|
||||
{
|
||||
collision = 0;
|
||||
for (m = 0; m < num_band; m++)
|
||||
{
|
||||
collision +=
|
||||
fc3_normal_squared[ti * num_band0 * num_band * num_band +
|
||||
k * num_band * num_band +
|
||||
l * num_band + m] *
|
||||
g[ti * num_band0 * num_band * num_band +
|
||||
k * num_band * num_band +
|
||||
l * num_band + m] *
|
||||
inv_sinh[m] * unit_conversion_factor;
|
||||
}
|
||||
for (m = 0; m < 3; m++)
|
||||
{
|
||||
for (n = 0; n < 3; n++)
|
||||
{
|
||||
collision_matrix[k * 3 * num_ir_gp * num_band * 3 +
|
||||
m * num_ir_gp * num_band * 3 +
|
||||
i * num_band * 3 + l * 3 + n] +=
|
||||
collision * rotations_cartesian[j * 9 + m * 3 + n];
|
||||
for (k = 0; k < num_band0; k++) {
|
||||
for (l = 0; l < num_band; l++) {
|
||||
collision = 0;
|
||||
for (m = 0; m < num_band; m++) {
|
||||
if (swapped) {
|
||||
collision +=
|
||||
fc3_normal_squared[ti * num_band0 * num_band *
|
||||
num_band +
|
||||
k * num_band * num_band +
|
||||
m * num_band + l] *
|
||||
g[ti * num_band0 * num_band * num_band +
|
||||
k * num_band * num_band + m * num_band + l] *
|
||||
inv_sinh[m] * unit_conversion_factor;
|
||||
} else {
|
||||
collision +=
|
||||
fc3_normal_squared[ti * num_band0 * num_band *
|
||||
num_band +
|
||||
k * num_band * num_band +
|
||||
l * num_band + m] *
|
||||
g[ti * num_band0 * num_band * num_band +
|
||||
k * num_band * num_band + l * num_band + m] *
|
||||
inv_sinh[m] * unit_conversion_factor;
|
||||
}
|
||||
}
|
||||
for (m = 0; m < 3; m++) {
|
||||
for (n = 0; n < 3; n++) {
|
||||
collision_matrix[k * 3 * num_ir_gp * num_band * 3 +
|
||||
m * num_ir_gp * num_band * 3 +
|
||||
i * num_band * 3 + l * 3 + n] +=
|
||||
collision *
|
||||
rotations_cartesian[j * 9 + m * 3 + n];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
free(inv_sinh);
|
||||
inv_sinh = NULL;
|
||||
}
|
||||
free(inv_sinh);
|
||||
inv_sinh = NULL;
|
||||
}
|
||||
|
||||
free(gp2tp_map);
|
||||
gp2tp_map = NULL;
|
||||
free(gp2tp_map);
|
||||
gp2tp_map = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
get_reducible_collision_matrix(double *collision_matrix,
|
||||
const double *fc3_normal_squared,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long num_gp,
|
||||
const long *map_q,
|
||||
const double *g,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j, k, l, ti;
|
||||
long *gp2tp_map;
|
||||
double collision;
|
||||
double *inv_sinh;
|
||||
static void get_reducible_collision_matrix(
|
||||
double *collision_matrix, const double *fc3_normal_squared,
|
||||
const long num_band0, const long num_band, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplets_map, const long num_gp,
|
||||
const long *map_q, const double *g, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency) {
|
||||
long i, j, k, l, ti, swapped;
|
||||
long *gp2tp_map;
|
||||
double collision;
|
||||
double *inv_sinh;
|
||||
|
||||
gp2tp_map = create_gp2tp_map(triplets_map, num_gp);
|
||||
gp2tp_map = create_gp2tp_map(triplets_map, num_gp);
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, k, l, ti, collision, inv_sinh)
|
||||
#endif
|
||||
for (i = 0; i < num_gp; i++)
|
||||
{
|
||||
inv_sinh = (double *)malloc(sizeof(double) * num_band);
|
||||
ti = gp2tp_map[triplets_map[i]];
|
||||
get_inv_sinh(inv_sinh,
|
||||
i,
|
||||
temperature,
|
||||
frequencies,
|
||||
triplets[ti],
|
||||
triplets_map,
|
||||
map_q,
|
||||
num_band,
|
||||
cutoff_frequency);
|
||||
for (i = 0; i < num_gp; i++) {
|
||||
inv_sinh = (double *)malloc(sizeof(double) * num_band);
|
||||
ti = gp2tp_map[triplets_map[i]];
|
||||
swapped =
|
||||
get_inv_sinh(inv_sinh, i, temperature, frequencies, triplets[ti],
|
||||
triplets_map, map_q, num_band, cutoff_frequency);
|
||||
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
for (k = 0; k < num_band; k++)
|
||||
{
|
||||
collision = 0;
|
||||
for (l = 0; l < num_band; l++)
|
||||
{
|
||||
collision +=
|
||||
fc3_normal_squared[ti * num_band0 * num_band * num_band +
|
||||
j * num_band * num_band +
|
||||
k * num_band + l] *
|
||||
g[ti * num_band0 * num_band * num_band +
|
||||
j * num_band * num_band +
|
||||
k * num_band + l] *
|
||||
inv_sinh[l] * unit_conversion_factor;
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
for (k = 0; k < num_band; k++) {
|
||||
collision = 0;
|
||||
for (l = 0; l < num_band; l++) {
|
||||
if (swapped) {
|
||||
collision +=
|
||||
fc3_normal_squared[ti * num_band0 * num_band *
|
||||
num_band +
|
||||
j * num_band * num_band +
|
||||
l * num_band + k] *
|
||||
g[ti * num_band0 * num_band * num_band +
|
||||
j * num_band * num_band + l * num_band + k] *
|
||||
inv_sinh[l] * unit_conversion_factor;
|
||||
} else {
|
||||
collision +=
|
||||
fc3_normal_squared[ti * num_band0 * num_band *
|
||||
num_band +
|
||||
j * num_band * num_band +
|
||||
k * num_band + l] *
|
||||
g[ti * num_band0 * num_band * num_band +
|
||||
j * num_band * num_band + k * num_band + l] *
|
||||
inv_sinh[l] * unit_conversion_factor;
|
||||
}
|
||||
}
|
||||
collision_matrix[j * num_gp * num_band + i * num_band + k] +=
|
||||
collision;
|
||||
}
|
||||
}
|
||||
collision_matrix[j * num_gp * num_band + i * num_band + k] += collision;
|
||||
}
|
||||
|
||||
free(inv_sinh);
|
||||
inv_sinh = NULL;
|
||||
}
|
||||
|
||||
free(inv_sinh);
|
||||
inv_sinh = NULL;
|
||||
}
|
||||
|
||||
free(gp2tp_map);
|
||||
gp2tp_map = NULL;
|
||||
free(gp2tp_map);
|
||||
gp2tp_map = NULL;
|
||||
}
|
||||
|
||||
static void get_inv_sinh(double *inv_sinh,
|
||||
const long gp,
|
||||
const double temperature,
|
||||
const double *frequencies,
|
||||
const long triplet[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const long num_band,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, gp2;
|
||||
double f;
|
||||
static long get_inv_sinh(double *inv_sinh, const long gp,
|
||||
const double temperature, const double *frequencies,
|
||||
const long triplet[3], const long *triplets_map,
|
||||
const long *map_q, const long num_band,
|
||||
const double cutoff_frequency) {
|
||||
long i, gp2, swapped;
|
||||
double f;
|
||||
|
||||
/* This assumes the algorithm of get_ir_triplets_at_q_perm_q1q2, */
|
||||
/* where defined triplets_map[gp] == triplets_map[map_q[gp]]. */
|
||||
/* If triplets_map[map_q[gp]] != map_q[gp], q1 and q2 are permuted. */
|
||||
if (triplets_map[gp] == map_q[gp])
|
||||
{
|
||||
gp2 = triplet[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
gp2 = triplet[1];
|
||||
}
|
||||
/* This assumes the algorithm of get_ir_triplets_at_q_perm_q1q2, */
|
||||
/* where defined triplets_map[gp] == triplets_map[map_q[gp]]. */
|
||||
/* If triplets_map[map_q[gp]] != map_q[gp], q1 and q2 are permuted. */
|
||||
if (triplets_map[gp] == map_q[gp]) {
|
||||
gp2 = triplet[2];
|
||||
swapped = 0;
|
||||
} else {
|
||||
gp2 = triplet[1];
|
||||
swapped = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band; i++)
|
||||
{
|
||||
f = frequencies[gp2 * num_band + i];
|
||||
if (f > cutoff_frequency)
|
||||
{
|
||||
inv_sinh[i] = phonoc_inv_sinh_occupation(f, temperature);
|
||||
for (i = 0; i < num_band; i++) {
|
||||
f = frequencies[gp2 * num_band + i];
|
||||
if (f > cutoff_frequency) {
|
||||
inv_sinh[i] = phonoc_inv_sinh_occupation(f, temperature);
|
||||
} else {
|
||||
inv_sinh[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
inv_sinh[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return swapped;
|
||||
}
|
||||
|
||||
/* Symmetrically independent triplets are indexed. */
|
||||
/* Inverse definition of ir_grid_points in get_BZ_triplets_at_q */
|
||||
/* in triplet_grid.c. */
|
||||
static long *create_gp2tp_map(const long *triplets_map,
|
||||
const long num_gp)
|
||||
{
|
||||
long i, num_ir;
|
||||
long *gp2tp_map;
|
||||
static long *create_gp2tp_map(const long *triplets_map, const long num_gp) {
|
||||
long i, num_ir;
|
||||
long *gp2tp_map;
|
||||
|
||||
gp2tp_map = (long *)malloc(sizeof(long) * num_gp);
|
||||
num_ir = 0;
|
||||
for (i = 0; i < num_gp; i++)
|
||||
{
|
||||
if (triplets_map[i] == i)
|
||||
{
|
||||
gp2tp_map[i] = num_ir;
|
||||
num_ir++;
|
||||
gp2tp_map = (long *)malloc(sizeof(long) * num_gp);
|
||||
num_ir = 0;
|
||||
for (i = 0; i < num_gp; i++) {
|
||||
if (triplets_map[i] == i) {
|
||||
gp2tp_map[i] = num_ir;
|
||||
num_ir++;
|
||||
} else { /* This should not be used. */
|
||||
gp2tp_map[i] = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* This should not be used. */
|
||||
gp2tp_map[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
return gp2tp_map;
|
||||
return gp2tp_map;
|
||||
}
|
||||
|
|
|
@ -37,31 +37,18 @@
|
|||
|
||||
#include "phonoc_array.h"
|
||||
|
||||
void col_get_collision_matrix(double *collision_matrix,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const long *rot_grid_points,
|
||||
const double *rotations_cartesian,
|
||||
const double *g,
|
||||
const long num_ir_gp,
|
||||
const long num_gp,
|
||||
const long num_rot,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
void col_get_reducible_collision_matrix(double *collision_matrix,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const double *g,
|
||||
const long num_gp,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
void col_get_collision_matrix(
|
||||
double *collision_matrix, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplets_map, const long *map_q, const long *rot_grid_points,
|
||||
const double *rotations_cartesian, const double *g, const long num_ir_gp,
|
||||
const long num_gp, const long num_rot, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
void col_get_reducible_collision_matrix(
|
||||
double *collision_matrix, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplets_map, const long *map_q, const double *g,
|
||||
const long num_gp, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
|
||||
#endif
|
||||
|
|
1022
c/dynmat.c
1022
c/dynmat.c
File diff suppressed because it is too large
Load Diff
68
c/dynmat.h
68
c/dynmat.h
|
@ -36,58 +36,42 @@
|
|||
#define __dynmat_H__
|
||||
|
||||
long dym_get_dynamical_matrix_at_q(double *dynamical_matrix,
|
||||
const long num_patom,
|
||||
const long num_satom,
|
||||
const double *fc,
|
||||
const double q[3],
|
||||
const long num_patom, const long num_satom,
|
||||
const double *fc, const double q[3],
|
||||
const double (*svecs)[3],
|
||||
const long (*multi)[2],
|
||||
const double *mass,
|
||||
const long *s2p_map,
|
||||
const long *p2s_map,
|
||||
const long (*multi)[2], const double *mass,
|
||||
const long *s2p_map, const long *p2s_map,
|
||||
const double (*charge_sum)[3][3],
|
||||
const long with_openmp);
|
||||
void dym_get_recip_dipole_dipole(double *dd, /* [natom, 3, natom, 3, (real,imag)] */
|
||||
const double *dd_q0, /* [natom, 3, 3, (real,imag)] */
|
||||
const double (*G_list)[3], /* [num_G, 3] */
|
||||
const long num_G,
|
||||
const long num_patom,
|
||||
const double q_cart[3],
|
||||
const double *q_direction_cart, /* must be pointer */
|
||||
const double (*born)[3][3],
|
||||
const double dielectric[3][3],
|
||||
const double (*pos)[3], /* [num_patom, 3] */
|
||||
const double factor, /* 4pi/V*unit-conv */
|
||||
const double lambda,
|
||||
const double tolerance);
|
||||
void dym_get_recip_dipole_dipole_q0(double *dd_q0, /* [natom, 3, 3, (real,imag)] */
|
||||
const double (*G_list)[3], /* [num_G, 3] */
|
||||
const long num_G,
|
||||
const long num_patom,
|
||||
const double (*born)[3][3],
|
||||
const double dielectric[3][3],
|
||||
const double (*pos)[3], /* [natom, 3] */
|
||||
const double lambda,
|
||||
const double tolerance);
|
||||
void dym_get_charge_sum(double (*charge_sum)[3][3],
|
||||
const long num_patom,
|
||||
const double factor,
|
||||
const double q_cart[3],
|
||||
void dym_get_recip_dipole_dipole(
|
||||
double *dd, /* [natom, 3, natom, 3, (real,imag)] */
|
||||
const double *dd_q0, /* [natom, 3, 3, (real,imag)] */
|
||||
const double (*G_list)[3], /* [num_G, 3] */
|
||||
const long num_G, const long num_patom, const double q_cart[3],
|
||||
const double *q_direction_cart, /* must be pointer */
|
||||
const double (*born)[3][3], const double dielectric[3][3],
|
||||
const double (*pos)[3], /* [num_patom, 3] */
|
||||
const double factor, /* 4pi/V*unit-conv */
|
||||
const double lambda, const double tolerance);
|
||||
void dym_get_recip_dipole_dipole_q0(
|
||||
double *dd_q0, /* [natom, 3, 3, (real,imag)] */
|
||||
const double (*G_list)[3], /* [num_G, 3] */
|
||||
const long num_G, const long num_patom, const double (*born)[3][3],
|
||||
const double dielectric[3][3], const double (*pos)[3], /* [natom, 3] */
|
||||
const double lambda, const double tolerance);
|
||||
void dym_get_charge_sum(double (*charge_sum)[3][3], const long num_patom,
|
||||
const double factor, const double q_cart[3],
|
||||
const double (*born)[3][3]);
|
||||
/* fc[num_patom, num_satom, 3, 3] */
|
||||
/* dm[num_comm_points, num_patom * 3, num_patom *3] */
|
||||
/* comm_points[num_satom / num_patom, 3] */
|
||||
/* shortest_vectors[:, 3] */
|
||||
/* multiplicities[num_satom, num_patom, 2] */
|
||||
void dym_transform_dynmat_to_fc(double *fc,
|
||||
const double *dm,
|
||||
void dym_transform_dynmat_to_fc(double *fc, const double *dm,
|
||||
const double (*comm_points)[3],
|
||||
const double (*svecs)[3],
|
||||
const long (*multi)[2],
|
||||
const double *masses,
|
||||
const long *s2pp_map,
|
||||
const long *fc_index_map,
|
||||
const long num_patom,
|
||||
const long num_satom);
|
||||
const long (*multi)[2], const double *masses,
|
||||
const long *s2pp_map, const long *fc_index_map,
|
||||
const long num_patom, const long num_satom);
|
||||
|
||||
#endif
|
||||
|
|
36
c/fc3.h
36
c/fc3.h
|
@ -35,35 +35,21 @@
|
|||
#ifndef __fc3_H__
|
||||
#define __fc3_H__
|
||||
|
||||
void fc3_distribute_fc3(double *fc3,
|
||||
const long target,
|
||||
const long source,
|
||||
const long *atom_mapping,
|
||||
const long num_atom,
|
||||
void fc3_distribute_fc3(double *fc3, const long target, const long source,
|
||||
const long *atom_mapping, const long num_atom,
|
||||
const double *rot_cart);
|
||||
void fc3_rotate_delta_fc2(double (*fc3)[3][3][3],
|
||||
const double (*delta_fc2s)[3][3],
|
||||
const double *inv_U,
|
||||
const double (*delta_fc2s)[3][3], const double *inv_U,
|
||||
const double (*site_sym_cart)[3][3],
|
||||
const long *rot_map_syms,
|
||||
const long num_atom,
|
||||
const long num_site_sym,
|
||||
const long num_disp);
|
||||
const long *rot_map_syms, const long num_atom,
|
||||
const long num_site_sym, const long num_disp);
|
||||
void fc3_set_permutation_symmetry_fc3(double *fc3, const long num_atom);
|
||||
void fc3_set_permutation_symmetry_compact_fc3(double *fc3,
|
||||
const long p2s[],
|
||||
const long s2pp[],
|
||||
const long nsym_list[],
|
||||
const long perms[],
|
||||
const long n_satom,
|
||||
const long n_patom);
|
||||
void fc3_transpose_compact_fc3(double *fc3,
|
||||
const long p2s[],
|
||||
const long s2pp[],
|
||||
const long nsym_list[],
|
||||
const long perms[],
|
||||
const long n_satom,
|
||||
const long n_patom,
|
||||
void fc3_set_permutation_symmetry_compact_fc3(
|
||||
double *fc3, const long p2s[], const long s2pp[], const long nsym_list[],
|
||||
const long perms[], const long n_satom, const long n_patom);
|
||||
void fc3_transpose_compact_fc3(double *fc3, const long p2s[], const long s2pp[],
|
||||
const long nsym_list[], const long perms[],
|
||||
const long n_satom, const long n_patom,
|
||||
const long t_type);
|
||||
|
||||
#endif
|
||||
|
|
489
c/grgrid.c
489
c/grgrid.c
|
@ -32,10 +32,12 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
#include "grgrid.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lagrid.h"
|
||||
#include "snf3x3.h"
|
||||
|
||||
|
@ -43,62 +45,47 @@
|
|||
|
||||
static void reduce_grid_address(long address[3], const long D_diag[3]);
|
||||
static long get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
const long D_diag[3], const long PS[3]);
|
||||
static long get_grid_index_from_address(const long address[3],
|
||||
const long D_diag[3]);
|
||||
static void get_all_grid_addresses(long grid_address[][3],
|
||||
const long D_diag[3]);
|
||||
static void get_grid_address_from_index(long address[3],
|
||||
const long grid_index,
|
||||
static void get_grid_address_from_index(long address[3], const long grid_index,
|
||||
const long D_diag[3]);
|
||||
static void get_grid_address(long address[3],
|
||||
const long address_double[3],
|
||||
static void get_grid_address(long address[3], const long address_double[3],
|
||||
const long PS[3]);
|
||||
static void get_double_grid_address(long address_double[3],
|
||||
const long address[3],
|
||||
const long PS[3]);
|
||||
static long rotate_grid_index(const long grid_index,
|
||||
const long rotation[3][3],
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
static void get_ir_grid_map(long *ir_grid_map,
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long address[3], const long PS[3]);
|
||||
static long rotate_grid_index(const long grid_index, const long rotation[3][3],
|
||||
const long D_diag[3], const long PS[3]);
|
||||
static void get_ir_grid_map(long *ir_grid_map, const long (*rotations)[3][3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long PS[3]);
|
||||
|
||||
long grg_get_snf3x3(long D_diag[3],
|
||||
long P[3][3],
|
||||
long Q[3][3],
|
||||
const long A[3][3])
|
||||
{
|
||||
long i, j, succeeded;
|
||||
long D[3][3];
|
||||
long grg_get_snf3x3(long D_diag[3], long P[3][3], long Q[3][3],
|
||||
const long A[3][3]) {
|
||||
long i, j, succeeded;
|
||||
long D[3][3];
|
||||
|
||||
succeeded = 0;
|
||||
succeeded = 0;
|
||||
|
||||
if (lagmat_get_determinant_l3(A) == 0)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
D[i][j] = A[i][j];
|
||||
if (lagmat_get_determinant_l3(A) == 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
succeeded = snf3x3(D, P, Q);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
D_diag[i] = D[i][i];
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
D[i][j] = A[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
succeeded = snf3x3(D, P, Q);
|
||||
for (i = 0; i < 3; i++) {
|
||||
D_diag[i] = D[i][i];
|
||||
}
|
||||
|
||||
err:
|
||||
return succeeded;
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
/*----------------------------------------*/
|
||||
|
@ -110,40 +97,34 @@ err:
|
|||
/* vectors. */
|
||||
/* num_rot : Number of rotations */
|
||||
long grg_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3])
|
||||
{
|
||||
long i, j, k;
|
||||
double r[3][3], Q_double[3][3];
|
||||
const long (*rotations)[3][3], const long num_rot,
|
||||
const long D_diag[3], const long Q[3][3]) {
|
||||
long i, j, k;
|
||||
double r[3][3], Q_double[3][3];
|
||||
|
||||
/* Compute D(Q^-1)RQ(D^-1) by three steps */
|
||||
/* It is assumed that |det(Q)|=1 and Q^-1 has relatively small round-off */
|
||||
/* error, and we want to divide by D carefully. */
|
||||
/* 1. Compute (Q^-1)RQ */
|
||||
/* 2. Compute D(Q^-1)RQ */
|
||||
/* 3. Compute D(Q^-1)RQ(D^-1) */
|
||||
lagmat_cast_matrix_3l_to_3d(Q_double, Q);
|
||||
for (i = 0; i < num_rot; i++)
|
||||
{
|
||||
lagmat_get_similar_matrix_ld3(r, rotations[i], Q_double, 0);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
r[j][k] *= D_diag[j];
|
||||
r[j][k] /= D_diag[k];
|
||||
}
|
||||
/* Compute D(Q^-1)RQ(D^-1) by three steps */
|
||||
/* It is assumed that |det(Q)|=1 and Q^-1 has relatively small round-off */
|
||||
/* error, and we want to divide by D carefully. */
|
||||
/* 1. Compute (Q^-1)RQ */
|
||||
/* 2. Compute D(Q^-1)RQ */
|
||||
/* 3. Compute D(Q^-1)RQ(D^-1) */
|
||||
lagmat_cast_matrix_3l_to_3d(Q_double, Q);
|
||||
for (i = 0; i < num_rot; i++) {
|
||||
lagmat_get_similar_matrix_ld3(r, rotations[i], Q_double, 0);
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
r[j][k] *= D_diag[j];
|
||||
r[j][k] /= D_diag[k];
|
||||
}
|
||||
}
|
||||
lagmat_cast_matrix_3d_to_3l(transformed_rots[i], r);
|
||||
if (!lagmat_check_identity_matrix_ld3(transformed_rots[i], r,
|
||||
IDENTITY_TOL)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
lagmat_cast_matrix_3d_to_3l(transformed_rots[i], r);
|
||||
if (!lagmat_check_identity_matrix_ld3(transformed_rots[i], r, IDENTITY_TOL))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* -------------------------------*/
|
||||
|
@ -151,9 +132,8 @@ long grg_transform_rotations(long (*transformed_rots)[3][3],
|
|||
/* -------------------------------*/
|
||||
/* address : Single grid address. */
|
||||
/* D_diag : Diagnal elements of D. */
|
||||
void grg_get_all_grid_addresses(long (*grid_address)[3], const long D_diag[3])
|
||||
{
|
||||
get_all_grid_addresses(grid_address, D_diag);
|
||||
void grg_get_all_grid_addresses(long (*grid_address)[3], const long D_diag[3]) {
|
||||
get_all_grid_addresses(grid_address, D_diag);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------*/
|
||||
|
@ -164,11 +144,9 @@ void grg_get_all_grid_addresses(long (*grid_address)[3], const long D_diag[3])
|
|||
/* address_double : Double grid address. */
|
||||
/* address : Single grid address. */
|
||||
/* PS : Shifts transformed by P. s_i is 0 or 1. */
|
||||
void grg_get_double_grid_address(long address_double[3],
|
||||
const long address[3],
|
||||
const long PS[3])
|
||||
{
|
||||
get_double_grid_address(address_double, address, PS);
|
||||
void grg_get_double_grid_address(long address_double[3], const long address[3],
|
||||
const long PS[3]) {
|
||||
get_double_grid_address(address_double, address, PS);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------*/
|
||||
|
@ -179,11 +157,9 @@ void grg_get_double_grid_address(long address_double[3],
|
|||
/* address : Single grid address. */
|
||||
/* address_double : Double grid address. */
|
||||
/* PS : Shifts transformed by P. s_i is 0 or 1. */
|
||||
void grg_get_grid_address(long address[3],
|
||||
const long address_double[3],
|
||||
const long PS[3])
|
||||
{
|
||||
get_grid_address(address, address_double, PS);
|
||||
void grg_get_grid_address(long address[3], const long address_double[3],
|
||||
const long PS[3]) {
|
||||
get_grid_address(address, address_double, PS);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------*/
|
||||
|
@ -193,10 +169,8 @@ void grg_get_grid_address(long address[3],
|
|||
/* D_diag : Diagnal elements of D. */
|
||||
/* PS : Shifts transformed by P. s_i is 0 or 1. */
|
||||
long grg_get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
return get_double_grid_index(address_double, D_diag, PS);
|
||||
const long D_diag[3], const long PS[3]) {
|
||||
return get_double_grid_index(address_double, D_diag, PS);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------*/
|
||||
|
@ -204,13 +178,12 @@ long grg_get_double_grid_index(const long address_double[3],
|
|||
/* -------------------------------------------------*/
|
||||
/* address : Single grid address. */
|
||||
/* D_diag : Diagnal elements of D. */
|
||||
long grg_get_grid_index(const long address[3], const long D_diag[3])
|
||||
{
|
||||
long red_adrs[3];
|
||||
long grg_get_grid_index(const long address[3], const long D_diag[3]) {
|
||||
long red_adrs[3];
|
||||
|
||||
lagmat_copy_vector_l3(red_adrs, address);
|
||||
reduce_grid_address(red_adrs, D_diag);
|
||||
return get_grid_index_from_address(red_adrs, D_diag);
|
||||
lagmat_copy_vector_l3(red_adrs, address);
|
||||
reduce_grid_address(red_adrs, D_diag);
|
||||
return get_grid_index_from_address(red_adrs, D_diag);
|
||||
}
|
||||
|
||||
/* ---------------------------------------*/
|
||||
|
@ -218,38 +191,26 @@ long grg_get_grid_index(const long address[3], const long D_diag[3])
|
|||
/* ---------------------------------------*/
|
||||
/* address : Single grid address. */
|
||||
/* D_diag : Diagnal elements of D. */
|
||||
void grg_get_grid_address_from_index(long address[3],
|
||||
const long grid_index,
|
||||
const long D_diag[3])
|
||||
{
|
||||
get_grid_address_from_index(address, grid_index, D_diag);
|
||||
void grg_get_grid_address_from_index(long address[3], const long grid_index,
|
||||
const long D_diag[3]) {
|
||||
get_grid_address_from_index(address, grid_index, D_diag);
|
||||
}
|
||||
|
||||
/* ---------------------------*/
|
||||
/* Rotate grid point by index */
|
||||
/* ---------------------------*/
|
||||
long grg_rotate_grid_index(const long grid_index,
|
||||
const long rotation[3][3],
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
return rotate_grid_index(grid_index, rotation, D_diag, PS);
|
||||
long grg_rotate_grid_index(const long grid_index, const long rotation[3][3],
|
||||
const long D_diag[3], const long PS[3]) {
|
||||
return rotate_grid_index(grid_index, rotation, D_diag, PS);
|
||||
}
|
||||
|
||||
/* -----------------------------*/
|
||||
/* Find irreducible grid points */
|
||||
/* -----------------------------*/
|
||||
void grg_get_ir_grid_map(long *ir_grid_map,
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
get_ir_grid_map(ir_grid_map,
|
||||
rotations,
|
||||
num_rot,
|
||||
D_diag,
|
||||
PS);
|
||||
void grg_get_ir_grid_map(long *ir_grid_map, const long (*rotations)[3][3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long PS[3]) {
|
||||
get_ir_grid_map(ir_grid_map, rotations, num_rot, D_diag, PS);
|
||||
}
|
||||
|
||||
/* Unique reciprocal rotations are collected from input rotations. */
|
||||
|
@ -267,92 +228,74 @@ long grg_get_reciprocal_point_group(long rec_rotations[48][3][3],
|
|||
const long is_transpose)
|
||||
|
||||
{
|
||||
long i, j, num_rot_ret, inv_exist;
|
||||
const long inversion[3][3] = {
|
||||
{-1, 0, 0},
|
||||
{0, -1, 0},
|
||||
{0, 0, -1}};
|
||||
long i, j, num_rot_ret, inv_exist;
|
||||
const long inversion[3][3] = {{-1, 0, 0}, {0, -1, 0}, {0, 0, -1}};
|
||||
|
||||
/* Collect unique rotations */
|
||||
num_rot_ret = 0;
|
||||
for (i = 0; i < num_rot; i++)
|
||||
{
|
||||
for (j = 0; j < num_rot_ret; j++)
|
||||
{
|
||||
if (lagmat_check_identity_matrix_l3(rotations[i], rec_rotations[j]))
|
||||
{
|
||||
goto escape;
|
||||
}
|
||||
}
|
||||
if (num_rot_ret == 48)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
lagmat_copy_matrix_l3(rec_rotations[num_rot_ret], rotations[i]);
|
||||
num_rot_ret++;
|
||||
escape:;
|
||||
}
|
||||
|
||||
if (is_transpose)
|
||||
{
|
||||
for (i = 0; i < num_rot_ret; i++)
|
||||
{
|
||||
lagmat_transpose_matrix_l3(rec_rotations[i], rec_rotations[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_time_reversal)
|
||||
{
|
||||
inv_exist = 0;
|
||||
for (i = 0; i < num_rot_ret; i++)
|
||||
{
|
||||
if (lagmat_check_identity_matrix_l3(inversion, rec_rotations[i]))
|
||||
{
|
||||
inv_exist = 1;
|
||||
break;
|
||||
}
|
||||
/* Collect unique rotations */
|
||||
num_rot_ret = 0;
|
||||
for (i = 0; i < num_rot; i++) {
|
||||
for (j = 0; j < num_rot_ret; j++) {
|
||||
if (lagmat_check_identity_matrix_l3(rotations[i],
|
||||
rec_rotations[j])) {
|
||||
goto escape;
|
||||
}
|
||||
}
|
||||
if (num_rot_ret == 48) {
|
||||
goto err;
|
||||
}
|
||||
lagmat_copy_matrix_l3(rec_rotations[num_rot_ret], rotations[i]);
|
||||
num_rot_ret++;
|
||||
escape:;
|
||||
}
|
||||
|
||||
if (!inv_exist)
|
||||
{
|
||||
if (num_rot_ret > 24)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rot_ret; i++)
|
||||
{
|
||||
lagmat_multiply_matrix_l3(rec_rotations[num_rot_ret + i],
|
||||
inversion, rec_rotations[i]);
|
||||
}
|
||||
num_rot_ret *= 2;
|
||||
if (is_transpose) {
|
||||
for (i = 0; i < num_rot_ret; i++) {
|
||||
lagmat_transpose_matrix_l3(rec_rotations[i], rec_rotations[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_rot_ret;
|
||||
if (is_time_reversal) {
|
||||
inv_exist = 0;
|
||||
for (i = 0; i < num_rot_ret; i++) {
|
||||
if (lagmat_check_identity_matrix_l3(inversion, rec_rotations[i])) {
|
||||
inv_exist = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inv_exist) {
|
||||
if (num_rot_ret > 24) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_rot_ret; i++) {
|
||||
lagmat_multiply_matrix_l3(rec_rotations[num_rot_ret + i],
|
||||
inversion, rec_rotations[i]);
|
||||
}
|
||||
num_rot_ret *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return num_rot_ret;
|
||||
err:
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void reduce_grid_address(long address[3], const long D_diag[3])
|
||||
{
|
||||
long i;
|
||||
static void reduce_grid_address(long address[3], const long D_diag[3]) {
|
||||
long i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
address[i] = lagmat_modulo_l(address[i], D_diag[i]);
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
address[i] = lagmat_modulo_l(address[i], D_diag[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static long get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
long address[3];
|
||||
const long D_diag[3], const long PS[3]) {
|
||||
long address[3];
|
||||
|
||||
get_grid_address(address, address_double, PS);
|
||||
reduce_grid_address(address, D_diag);
|
||||
return get_grid_index_from_address(address, D_diag);
|
||||
get_grid_address(address, address_double, PS);
|
||||
reduce_grid_address(address, D_diag);
|
||||
return get_grid_index_from_address(address, D_diag);
|
||||
}
|
||||
|
||||
/* Here address elements have to be zero or positive. */
|
||||
|
@ -360,133 +303,111 @@ static long get_double_grid_index(const long address_double[3],
|
|||
/* done outside of this function. */
|
||||
/* See kgrid.h about GRID_ORDER_XYZ information. */
|
||||
static long get_grid_index_from_address(const long address[3],
|
||||
const long D_diag[3])
|
||||
{
|
||||
const long D_diag[3]) {
|
||||
#ifndef GRID_ORDER_XYZ
|
||||
return (address[2] * D_diag[0] * D_diag[1] + address[1] * D_diag[0] + address[0]);
|
||||
return (address[2] * D_diag[0] * D_diag[1] + address[1] * D_diag[0] +
|
||||
address[0]);
|
||||
#else
|
||||
return (address[0] * D_diag[1] * D_diag[2] + address[1] * D_diag[2] + address[2]);
|
||||
return (address[0] * D_diag[1] * D_diag[2] + address[1] * D_diag[2] +
|
||||
address[2]);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void get_all_grid_addresses(long grid_address[][3],
|
||||
const long D_diag[3])
|
||||
{
|
||||
long i, j, k, grid_index;
|
||||
long address[3];
|
||||
const long D_diag[3]) {
|
||||
long i, j, k, grid_index;
|
||||
long address[3];
|
||||
|
||||
for (i = 0; i < D_diag[0]; i++)
|
||||
{
|
||||
address[0] = i;
|
||||
for (j = 0; j < D_diag[1]; j++)
|
||||
{
|
||||
address[1] = j;
|
||||
for (k = 0; k < D_diag[2]; k++)
|
||||
{
|
||||
address[2] = k;
|
||||
grid_index = get_grid_index_from_address(address, D_diag);
|
||||
lagmat_copy_vector_l3(grid_address[grid_index], address);
|
||||
}
|
||||
for (i = 0; i < D_diag[0]; i++) {
|
||||
address[0] = i;
|
||||
for (j = 0; j < D_diag[1]; j++) {
|
||||
address[1] = j;
|
||||
for (k = 0; k < D_diag[2]; k++) {
|
||||
address[2] = k;
|
||||
grid_index = get_grid_index_from_address(address, D_diag);
|
||||
lagmat_copy_vector_l3(grid_address[grid_index], address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See grg_get_grid_address_from_index */
|
||||
static void get_grid_address_from_index(long address[3],
|
||||
const long grid_index,
|
||||
const long D_diag[3])
|
||||
{
|
||||
long nn;
|
||||
static void get_grid_address_from_index(long address[3], const long grid_index,
|
||||
const long D_diag[3]) {
|
||||
long nn;
|
||||
|
||||
#ifndef GRID_ORDER_XYZ
|
||||
nn = D_diag[0] * D_diag[1];
|
||||
address[0] = grid_index % D_diag[0];
|
||||
address[2] = grid_index / nn;
|
||||
address[1] = (grid_index - address[2] * nn) / D_diag[0];
|
||||
nn = D_diag[0] * D_diag[1];
|
||||
address[0] = grid_index % D_diag[0];
|
||||
address[2] = grid_index / nn;
|
||||
address[1] = (grid_index - address[2] * nn) / D_diag[0];
|
||||
#else
|
||||
nn = D_diag[1] * D_diag[2];
|
||||
address[2] = grid_index % D_diag[2];
|
||||
address[0] = grid_index / nn;
|
||||
address[1] = (grid_index - address[0] * nn) / D_diag[2];
|
||||
nn = D_diag[1] * D_diag[2];
|
||||
address[2] = grid_index % D_diag[2];
|
||||
address[0] = grid_index / nn;
|
||||
address[1] = (grid_index - address[0] * nn) / D_diag[2];
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Usually address has to be reduced to [0, D_diag[i]) */
|
||||
/* by calling reduce_grid_address after this operation. */
|
||||
static void get_grid_address(long address[3],
|
||||
const long address_double[3],
|
||||
const long PS[3])
|
||||
{
|
||||
long i;
|
||||
static void get_grid_address(long address[3], const long address_double[3],
|
||||
const long PS[3]) {
|
||||
long i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
address[i] = (address_double[i] - PS[i]) / 2;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
address[i] = (address_double[i] - PS[i]) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Usually address_double has to be reduced to [0, 2*D_diag[i]) */
|
||||
/* by calling reduce_double_grid_address after this operation. */
|
||||
static void get_double_grid_address(long address_double[3],
|
||||
const long address[3],
|
||||
const long PS[3])
|
||||
{
|
||||
long i;
|
||||
const long address[3], const long PS[3]) {
|
||||
long i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
address_double[i] = address[i] * 2 + PS[i];
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
address_double[i] = address[i] * 2 + PS[i];
|
||||
}
|
||||
}
|
||||
|
||||
static long rotate_grid_index(const long grid_index,
|
||||
const long rotation[3][3],
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
long adrs[3], dadrs[3], dadrs_rot[3];
|
||||
static long rotate_grid_index(const long grid_index, const long rotation[3][3],
|
||||
const long D_diag[3], const long PS[3]) {
|
||||
long adrs[3], dadrs[3], dadrs_rot[3];
|
||||
|
||||
get_grid_address_from_index(adrs, grid_index, D_diag);
|
||||
get_double_grid_address(dadrs, adrs, PS);
|
||||
lagmat_multiply_matrix_vector_l3(dadrs_rot, rotation, dadrs);
|
||||
return get_double_grid_index(dadrs_rot, D_diag, PS);
|
||||
get_grid_address_from_index(adrs, grid_index, D_diag);
|
||||
get_double_grid_address(dadrs, adrs, PS);
|
||||
lagmat_multiply_matrix_vector_l3(dadrs_rot, rotation, dadrs);
|
||||
return get_double_grid_index(dadrs_rot, D_diag, PS);
|
||||
}
|
||||
|
||||
/* Find ir-grid points. */
|
||||
/* This algorithm relies on the ir-grid index is always smallest */
|
||||
/* number among symmetrically equivalent grid points. */
|
||||
static void get_ir_grid_map(long *ir_grid_map,
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
long gp, num_gp, r_gp;
|
||||
long i;
|
||||
static void get_ir_grid_map(long *ir_grid_map, const long (*rotations)[3][3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long PS[3]) {
|
||||
long gp, num_gp, r_gp;
|
||||
long i;
|
||||
|
||||
num_gp = D_diag[0] * D_diag[1] * D_diag[2];
|
||||
num_gp = D_diag[0] * D_diag[1] * D_diag[2];
|
||||
|
||||
for (gp = 0; gp < num_gp; gp++)
|
||||
{
|
||||
ir_grid_map[gp] = num_gp;
|
||||
}
|
||||
|
||||
/* Do not simply multithreaded this for-loop. */
|
||||
/* This algorithm contains race condition in different gp's. */
|
||||
for (gp = 0; gp < num_gp; gp++)
|
||||
{
|
||||
for (i = 0; i < num_rot; i++)
|
||||
{
|
||||
r_gp = rotate_grid_index(gp, rotations[i], D_diag, PS);
|
||||
if (r_gp < gp)
|
||||
{
|
||||
ir_grid_map[gp] = ir_grid_map[r_gp];
|
||||
break;
|
||||
}
|
||||
for (gp = 0; gp < num_gp; gp++) {
|
||||
ir_grid_map[gp] = num_gp;
|
||||
}
|
||||
if (ir_grid_map[gp] == num_gp)
|
||||
{
|
||||
ir_grid_map[gp] = gp;
|
||||
|
||||
/* Do not simply multithreaded this for-loop. */
|
||||
/* This algorithm contains race condition in different gp's. */
|
||||
for (gp = 0; gp < num_gp; gp++) {
|
||||
for (i = 0; i < num_rot; i++) {
|
||||
r_gp = rotate_grid_index(gp, rotations[i], D_diag, PS);
|
||||
if (r_gp < gp) {
|
||||
ir_grid_map[gp] = ir_grid_map[r_gp];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ir_grid_map[gp] == num_gp) {
|
||||
ir_grid_map[gp] = gp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
37
c/grgrid.h
37
c/grgrid.h
|
@ -37,38 +37,25 @@
|
|||
|
||||
#include <stddef.h>
|
||||
|
||||
long grg_get_snf3x3(long D_diag[3],
|
||||
long P[3][3],
|
||||
long Q[3][3],
|
||||
long grg_get_snf3x3(long D_diag[3], long P[3][3], long Q[3][3],
|
||||
const long A[3][3]);
|
||||
long grg_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3]);
|
||||
const long (*rotations)[3][3], const long num_rot,
|
||||
const long D_diag[3], const long Q[3][3]);
|
||||
void grg_get_all_grid_addresses(long (*grid_address)[3], const long D_diag[3]);
|
||||
void grg_get_double_grid_address(long address_double[3],
|
||||
const long address[3],
|
||||
void grg_get_double_grid_address(long address_double[3], const long address[3],
|
||||
const long PS[3]);
|
||||
void grg_get_grid_address(long address[3],
|
||||
const long address_double[3],
|
||||
void grg_get_grid_address(long address[3], const long address_double[3],
|
||||
const long PS[3]);
|
||||
long grg_get_grid_index(const long address[3],
|
||||
const long D_diag[3]);
|
||||
long grg_get_grid_index(const long address[3], const long D_diag[3]);
|
||||
long grg_get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
void grg_get_grid_address_from_index(long address[3],
|
||||
const long grid_index,
|
||||
const long D_diag[3], const long PS[3]);
|
||||
void grg_get_grid_address_from_index(long address[3], const long grid_index,
|
||||
const long D_diag[3]);
|
||||
long grg_rotate_grid_index(const long grid_index,
|
||||
const long rotations[3][3],
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
void grg_get_ir_grid_map(long *ir_grid_map,
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
long grg_rotate_grid_index(const long grid_index, const long rotations[3][3],
|
||||
const long D_diag[3], const long PS[3]);
|
||||
void grg_get_ir_grid_map(long *ir_grid_map, const long (*rotations)[3][3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long PS[3]);
|
||||
long grg_get_reciprocal_point_group(long rec_rotations[48][3][3],
|
||||
const long (*rotations)[3][3],
|
||||
|
|
369
c/gridsys.c
369
c/gridsys.c
|
@ -34,76 +34,58 @@
|
|||
|
||||
#include "gridsys.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bzgrid.h"
|
||||
#include "lagrid.h"
|
||||
#include "grgrid.h"
|
||||
#include "lagrid.h"
|
||||
#include "tetrahedron_method.h"
|
||||
#include "triplet.h"
|
||||
#include "triplet_iw.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void gridsys_get_all_grid_addresses(long (*gr_grid_addresses)[3],
|
||||
const long D_diag[3])
|
||||
{
|
||||
grg_get_all_grid_addresses(gr_grid_addresses, D_diag);
|
||||
const long D_diag[3]) {
|
||||
grg_get_all_grid_addresses(gr_grid_addresses, D_diag);
|
||||
}
|
||||
|
||||
void gridsys_get_double_grid_address(long address_double[3],
|
||||
const long address[3],
|
||||
const long PS[3])
|
||||
{
|
||||
grg_get_double_grid_address(address_double, address, PS);
|
||||
const long address[3], const long PS[3]) {
|
||||
grg_get_double_grid_address(address_double, address, PS);
|
||||
}
|
||||
|
||||
void gridsys_get_grid_address_from_index(long address[3],
|
||||
const long grid_index,
|
||||
const long D_diag[3])
|
||||
{
|
||||
grg_get_grid_address_from_index(address, grid_index, D_diag);
|
||||
void gridsys_get_grid_address_from_index(long address[3], const long grid_index,
|
||||
const long D_diag[3]) {
|
||||
grg_get_grid_address_from_index(address, grid_index, D_diag);
|
||||
}
|
||||
|
||||
long gridsys_get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
return grg_get_double_grid_index(address_double, D_diag, PS);
|
||||
const long D_diag[3], const long PS[3]) {
|
||||
return grg_get_double_grid_index(address_double, D_diag, PS);
|
||||
}
|
||||
|
||||
/* From single address to grid index */
|
||||
long gridsys_get_grid_index_from_address(const long address[3],
|
||||
const long D_diag[3])
|
||||
{
|
||||
return grg_get_grid_index(address, D_diag);
|
||||
const long D_diag[3]) {
|
||||
return grg_get_grid_index(address, D_diag);
|
||||
}
|
||||
|
||||
long gridsys_rotate_grid_index(const long grid_index,
|
||||
const long rotation[3][3],
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
return grg_rotate_grid_index(grid_index, rotation, D_diag, PS);
|
||||
long gridsys_rotate_grid_index(const long grid_index, const long rotation[3][3],
|
||||
const long D_diag[3], const long PS[3]) {
|
||||
return grg_rotate_grid_index(grid_index, rotation, D_diag, PS);
|
||||
}
|
||||
|
||||
long gridsys_get_reciprocal_point_group(long rec_rotations[48][3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long is_time_reversal)
|
||||
{
|
||||
return grg_get_reciprocal_point_group(rec_rotations,
|
||||
rotations,
|
||||
num_rot,
|
||||
is_time_reversal,
|
||||
1);
|
||||
const long is_time_reversal) {
|
||||
return grg_get_reciprocal_point_group(rec_rotations, rotations, num_rot,
|
||||
is_time_reversal, 1);
|
||||
}
|
||||
|
||||
long gridsys_get_snf3x3(long D_diag[3],
|
||||
long P[3][3],
|
||||
long Q[3][3],
|
||||
const long A[3][3])
|
||||
{
|
||||
return grg_get_snf3x3(D_diag, P, Q, A);
|
||||
long gridsys_get_snf3x3(long D_diag[3], long P[3][3], long Q[3][3],
|
||||
const long A[3][3]) {
|
||||
return grg_get_snf3x3(D_diag, P, Q, A);
|
||||
}
|
||||
|
||||
/* Rotation matrices with respect to reciprocal basis vectors are
|
||||
|
@ -111,43 +93,33 @@ long gridsys_get_snf3x3(long D_diag[3],
|
|||
* used always in GRGrid handling. */
|
||||
long gridsys_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3])
|
||||
{
|
||||
long succeeded;
|
||||
succeeded = grg_transform_rotations(transformed_rots,
|
||||
rotations,
|
||||
num_rot,
|
||||
D_diag,
|
||||
Q);
|
||||
return succeeded;
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long Q[3][3]) {
|
||||
long succeeded;
|
||||
succeeded = grg_transform_rotations(transformed_rots, rotations, num_rot,
|
||||
D_diag, Q);
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
double gridsys_get_thm_integration_weight(const double omega,
|
||||
const double tetrahedra_omegas[24][4],
|
||||
const char function)
|
||||
{
|
||||
return thm_get_integration_weight(omega, tetrahedra_omegas, function);
|
||||
const char function) {
|
||||
return thm_get_integration_weight(omega, tetrahedra_omegas, function);
|
||||
}
|
||||
|
||||
/* Get one dataset of relative grid address used for tetrahedron */
|
||||
/* method. rec_lattice is used to choose the one. */
|
||||
/* rec_lattice : microzone basis vectors in column vectors */
|
||||
void gridsys_get_thm_relative_grid_address(long relative_grid_addresses[24][4][3],
|
||||
const double rec_lattice[3][3])
|
||||
{
|
||||
thm_get_relative_grid_address(relative_grid_addresses, rec_lattice);
|
||||
void gridsys_get_thm_relative_grid_address(
|
||||
long relative_grid_addresses[24][4][3], const double rec_lattice[3][3]) {
|
||||
thm_get_relative_grid_address(relative_grid_addresses, rec_lattice);
|
||||
}
|
||||
|
||||
/* The rotations are those after proper transformation in GRGrid. */
|
||||
void gridsys_get_ir_grid_map(long *ir_grid_map,
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long PS[3])
|
||||
{
|
||||
grg_get_ir_grid_map(ir_grid_map, rotations, num_rot, D_diag, PS);
|
||||
void gridsys_get_ir_grid_map(long *ir_grid_map, const long (*rotations)[3][3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long PS[3]) {
|
||||
grg_get_ir_grid_map(ir_grid_map, rotations, num_rot, D_diag, PS);
|
||||
}
|
||||
|
||||
/* Find shortest grid points from Gamma considering periodicity of */
|
||||
|
@ -173,197 +145,130 @@ void gridsys_get_ir_grid_map(long *ir_grid_map,
|
|||
/* len(bzg2grg) == len(bz_grid_addresses) <= product(D_diag + 1). */
|
||||
/* (function return) size : */
|
||||
/* Number of bz_grid_addresses stored. */
|
||||
long gridsys_get_bz_grid_addresses(long (*bz_grid_addresses)[3],
|
||||
long *bz_map,
|
||||
long *bzg2grg,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const long PS[3],
|
||||
long gridsys_get_bz_grid_addresses(long (*bz_grid_addresses)[3], long *bz_map,
|
||||
long *bzg2grg, const long D_diag[3],
|
||||
const long Q[3][3], const long PS[3],
|
||||
const double rec_lattice[3][3],
|
||||
const long type)
|
||||
{
|
||||
BZGrid *bzgrid;
|
||||
long i, j, size;
|
||||
const long type) {
|
||||
BZGrid *bzgrid;
|
||||
long i, j, size;
|
||||
|
||||
if ((bzgrid = (BZGrid *)malloc(sizeof(BZGrid))) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bzgrid->addresses = bz_grid_addresses;
|
||||
bzgrid->gp_map = bz_map;
|
||||
bzgrid->bzg2grg = bzg2grg;
|
||||
bzgrid->type = type;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
bzgrid->D_diag[i] = D_diag[i];
|
||||
bzgrid->PS[i] = PS[i];
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bzgrid->Q[i][j] = Q[i][j];
|
||||
bzgrid->reclat[i][j] = rec_lattice[i][j];
|
||||
if ((bzgrid = (BZGrid *)malloc(sizeof(BZGrid))) == NULL) {
|
||||
warning_print("Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (bzg_get_bz_grid_addresses(bzgrid))
|
||||
{
|
||||
size = bzgrid->size;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 0;
|
||||
}
|
||||
bzgrid->addresses = bz_grid_addresses;
|
||||
bzgrid->gp_map = bz_map;
|
||||
bzgrid->bzg2grg = bzg2grg;
|
||||
bzgrid->type = type;
|
||||
for (i = 0; i < 3; i++) {
|
||||
bzgrid->D_diag[i] = D_diag[i];
|
||||
bzgrid->PS[i] = PS[i];
|
||||
for (j = 0; j < 3; j++) {
|
||||
bzgrid->Q[i][j] = Q[i][j];
|
||||
bzgrid->reclat[i][j] = rec_lattice[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
free(bzgrid);
|
||||
bzgrid = NULL;
|
||||
if (bzg_get_bz_grid_addresses(bzgrid)) {
|
||||
size = bzgrid->size;
|
||||
} else {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
free(bzgrid);
|
||||
bzgrid = NULL;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
long gridsys_get_triplets_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const long is_time_reversal,
|
||||
const long num_rot,
|
||||
long gridsys_get_triplets_at_q(long *map_triplets, long *map_q,
|
||||
const long grid_point, const long D_diag[3],
|
||||
const long is_time_reversal, const long num_rot,
|
||||
const long (*rec_rotations)[3][3],
|
||||
const long swappable)
|
||||
{
|
||||
return tpl_get_triplets_reciprocal_mesh_at_q(map_triplets,
|
||||
map_q,
|
||||
grid_point,
|
||||
D_diag,
|
||||
is_time_reversal,
|
||||
num_rot,
|
||||
rec_rotations,
|
||||
swappable);
|
||||
const long swappable) {
|
||||
return tpl_get_triplets_reciprocal_mesh_at_q(
|
||||
map_triplets, map_q, grid_point, D_diag, is_time_reversal, num_rot,
|
||||
rec_rotations, swappable);
|
||||
}
|
||||
|
||||
long gridsys_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
long gridsys_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long *map_triplets,
|
||||
const long *bz_map, const long *map_triplets,
|
||||
const long num_map_triplets,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const long bz_grid_type)
|
||||
{
|
||||
ConstBZGrid *bzgrid;
|
||||
long i, j, num_ir;
|
||||
const long D_diag[3], const long Q[3][3],
|
||||
const long bz_grid_type) {
|
||||
ConstBZGrid *bzgrid;
|
||||
long i, j, num_ir;
|
||||
|
||||
if ((bzgrid = (ConstBZGrid *)malloc(sizeof(ConstBZGrid))) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bzgrid->addresses = bz_grid_addresses;
|
||||
bzgrid->gp_map = bz_map;
|
||||
bzgrid->type = bz_grid_type;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
bzgrid->D_diag[i] = D_diag[i];
|
||||
bzgrid->PS[i] = 0;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bzgrid->Q[i][j] = Q[i][j];
|
||||
if ((bzgrid = (ConstBZGrid *)malloc(sizeof(ConstBZGrid))) == NULL) {
|
||||
warning_print("Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
bzgrid->size = num_map_triplets;
|
||||
|
||||
num_ir = tpl_get_BZ_triplets_at_q(triplets,
|
||||
grid_point,
|
||||
bzgrid,
|
||||
map_triplets);
|
||||
free(bzgrid);
|
||||
bzgrid = NULL;
|
||||
bzgrid->addresses = bz_grid_addresses;
|
||||
bzgrid->gp_map = bz_map;
|
||||
bzgrid->type = bz_grid_type;
|
||||
for (i = 0; i < 3; i++) {
|
||||
bzgrid->D_diag[i] = D_diag[i];
|
||||
bzgrid->PS[i] = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
bzgrid->Q[i][j] = Q[i][j];
|
||||
}
|
||||
}
|
||||
bzgrid->size = num_map_triplets;
|
||||
|
||||
return num_ir;
|
||||
num_ir =
|
||||
tpl_get_BZ_triplets_at_q(triplets, grid_point, bzgrid, map_triplets);
|
||||
free(bzgrid);
|
||||
bzgrid = NULL;
|
||||
|
||||
return num_ir;
|
||||
}
|
||||
|
||||
/* relative_grid_addresses are given as P multipled with those from */
|
||||
/* dataset, i.e., */
|
||||
/* np.dot(relative_grid_addresses, P.T) */
|
||||
long gridsys_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long D_diag[3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long bz_grid_type,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_triplets,
|
||||
const long openmp_per_bands)
|
||||
{
|
||||
ConstBZGrid *bzgrid;
|
||||
long i;
|
||||
long gridsys_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long relative_grid_address[24][4][3],
|
||||
const long D_diag[3], const long (*triplets)[3], const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3], const long *bz_map,
|
||||
const long bz_grid_type, const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_triplets, const long openmp_per_bands) {
|
||||
ConstBZGrid *bzgrid;
|
||||
long i;
|
||||
|
||||
if ((bzgrid = (ConstBZGrid *)malloc(sizeof(ConstBZGrid))) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
if ((bzgrid = (ConstBZGrid *)malloc(sizeof(ConstBZGrid))) == NULL) {
|
||||
warning_print("Memory could not be allocated.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bzgrid->addresses = bz_grid_addresses;
|
||||
bzgrid->gp_map = bz_map;
|
||||
bzgrid->type = bz_grid_type;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
bzgrid->D_diag[i] = D_diag[i];
|
||||
}
|
||||
bzgrid->addresses = bz_grid_addresses;
|
||||
bzgrid->gp_map = bz_map;
|
||||
bzgrid->type = bz_grid_type;
|
||||
for (i = 0; i < 3; i++) {
|
||||
bzgrid->D_diag[i] = D_diag[i];
|
||||
}
|
||||
|
||||
tpl_get_integration_weight(iw,
|
||||
iw_zero,
|
||||
frequency_points,
|
||||
num_band0,
|
||||
relative_grid_address,
|
||||
triplets,
|
||||
num_triplets,
|
||||
bzgrid,
|
||||
frequencies1,
|
||||
num_band1,
|
||||
frequencies2,
|
||||
num_band2,
|
||||
tp_type,
|
||||
openmp_per_triplets,
|
||||
openmp_per_bands);
|
||||
free(bzgrid);
|
||||
bzgrid = NULL;
|
||||
tpl_get_integration_weight(
|
||||
iw, iw_zero, frequency_points, num_band0, relative_grid_address,
|
||||
triplets, num_triplets, bzgrid, frequencies1, num_band1, frequencies2,
|
||||
num_band2, tp_type, openmp_per_triplets, openmp_per_bands);
|
||||
free(bzgrid);
|
||||
bzgrid = NULL;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void gridsys_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type)
|
||||
{
|
||||
tpl_get_integration_weight_with_sigma(iw,
|
||||
iw_zero,
|
||||
sigma,
|
||||
sigma_cutoff,
|
||||
frequency_points,
|
||||
num_band0,
|
||||
triplets,
|
||||
num_triplets,
|
||||
frequencies,
|
||||
num_band,
|
||||
tp_type);
|
||||
void gridsys_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double sigma_cutoff,
|
||||
const double *frequency_points, const long num_band0,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const double *frequencies, const long num_band, const long tp_type) {
|
||||
tpl_get_integration_weight_with_sigma(
|
||||
iw, iw_zero, sigma, sigma_cutoff, frequency_points, num_band0, triplets,
|
||||
num_triplets, frequencies, num_band, tp_type);
|
||||
}
|
||||
|
|
154
c/gridsys.h
154
c/gridsys.h
|
@ -36,104 +36,68 @@
|
|||
#define __gridsys_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void gridsys_get_all_grid_addresses(long (*gr_grid_addresses)[3],
|
||||
const long D_diag[3]);
|
||||
void gridsys_get_double_grid_address(long address_double[3],
|
||||
const long address[3],
|
||||
const long PS[3]);
|
||||
void gridsys_get_grid_address_from_index(long address[3],
|
||||
const long grid_index,
|
||||
const long D_diag[3]);
|
||||
long gridsys_get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
long gridsys_get_grid_index_from_address(const long address[3],
|
||||
const long D_diag[3]);
|
||||
long gridsys_rotate_grid_index(const long grid_index,
|
||||
const long rotation[3][3],
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
long gridsys_get_reciprocal_point_group(long rec_rotations[48][3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long is_time_reversal);
|
||||
long gridsys_get_snf3x3(long D_diag[3],
|
||||
long P[3][3],
|
||||
long Q[3][3],
|
||||
const long A[3][3]);
|
||||
long gridsys_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3]);
|
||||
double gridsys_get_thm_integration_weight(const double omega,
|
||||
const double tetrahedra_omegas[24][4],
|
||||
const char function);
|
||||
void gridsys_get_thm_relative_grid_address(long relative_grid_addresses[24][4][3],
|
||||
const double rec_lattice[3][3]);
|
||||
void gridsys_get_ir_grid_map(long *ir_grid_map,
|
||||
void gridsys_get_all_grid_addresses(long (*gr_grid_addresses)[3],
|
||||
const long D_diag[3]);
|
||||
void gridsys_get_double_grid_address(long address_double[3],
|
||||
const long address[3], const long PS[3]);
|
||||
void gridsys_get_grid_address_from_index(long address[3], const long grid_index,
|
||||
const long D_diag[3]);
|
||||
long gridsys_get_double_grid_index(const long address_double[3],
|
||||
const long D_diag[3], const long PS[3]);
|
||||
long gridsys_get_grid_index_from_address(const long address[3],
|
||||
const long D_diag[3]);
|
||||
long gridsys_rotate_grid_index(const long grid_index, const long rotation[3][3],
|
||||
const long D_diag[3], const long PS[3]);
|
||||
long gridsys_get_reciprocal_point_group(long rec_rotations[48][3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long is_time_reversal);
|
||||
long gridsys_get_snf3x3(long D_diag[3], long P[3][3], long Q[3][3],
|
||||
const long A[3][3]);
|
||||
long gridsys_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long PS[3]);
|
||||
long gridsys_get_bz_grid_addresses(long (*bz_grid_addresses)[3],
|
||||
long *bz_map,
|
||||
long *bzg2grg,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const long PS[3],
|
||||
const double rec_lattice[3][3],
|
||||
const long type);
|
||||
long gridsys_get_triplets_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const long is_time_reversal,
|
||||
const long num_rot,
|
||||
const long (*rec_rotations)[3][3],
|
||||
const long swappable);
|
||||
long gridsys_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long *map_triplets,
|
||||
const long num_map_triplets,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const long bz_grid_type);
|
||||
long gridsys_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long D_diag[3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long bz_grid_type,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_triplets,
|
||||
const long openmp_per_bands);
|
||||
void gridsys_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type);
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long Q[3][3]);
|
||||
double gridsys_get_thm_integration_weight(const double omega,
|
||||
const double tetrahedra_omegas[24][4],
|
||||
const char function);
|
||||
void gridsys_get_thm_relative_grid_address(
|
||||
long relative_grid_addresses[24][4][3], const double rec_lattice[3][3]);
|
||||
void gridsys_get_ir_grid_map(long *ir_grid_map, const long (*rotations)[3][3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long PS[3]);
|
||||
long gridsys_get_bz_grid_addresses(long (*bz_grid_addresses)[3], long *bz_map,
|
||||
long *bzg2grg, const long D_diag[3],
|
||||
const long Q[3][3], const long PS[3],
|
||||
const double rec_lattice[3][3],
|
||||
const long type);
|
||||
long gridsys_get_triplets_at_q(long *map_triplets, long *map_q,
|
||||
const long grid_point, const long D_diag[3],
|
||||
const long is_time_reversal, const long num_rot,
|
||||
const long (*rec_rotations)[3][3],
|
||||
const long swappable);
|
||||
long gridsys_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map, const long *map_triplets,
|
||||
const long num_map_triplets,
|
||||
const long D_diag[3], const long Q[3][3],
|
||||
const long bz_grid_type);
|
||||
long gridsys_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long relative_grid_address[24][4][3],
|
||||
const long D_diag[3], const long (*triplets)[3], const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3], const long *bz_map,
|
||||
const long bz_grid_type, const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_triplets, const long openmp_per_bands);
|
||||
void gridsys_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double sigma_cutoff,
|
||||
const double *frequency_points, const long num_band0,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const double *frequencies, const long num_band, const long tp_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -32,568 +32,411 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "imag_self_energy_with_g.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "lagrid.h"
|
||||
#include "phonoc_array.h"
|
||||
#include "phonoc_utils.h"
|
||||
#include "imag_self_energy_with_g.h"
|
||||
#include "triplet.h"
|
||||
|
||||
static long ise_set_g_pos_frequency_point(long (*g_pos)[4],
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const char *g_zero);
|
||||
static void
|
||||
detailed_imag_self_energy_at_triplet(double *detailed_imag_self_energy,
|
||||
double *imag_self_energy,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long triplet[3],
|
||||
const double *g1,
|
||||
const double *g2_3,
|
||||
const char *g_zero,
|
||||
const double *temperatures,
|
||||
const long num_temps,
|
||||
const double cutoff_frequency);
|
||||
static double
|
||||
collect_detailed_imag_self_energy(double *imag_self_energy,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *n1,
|
||||
const double *n2,
|
||||
const double *g1,
|
||||
const double *g2_3,
|
||||
const char *g_zero);
|
||||
static double
|
||||
collect_detailed_imag_self_energy_0K(double *imag_self_energy,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *n1,
|
||||
const double *n2,
|
||||
const double *g,
|
||||
const char *g_zero);
|
||||
static void set_occupations(double *n1,
|
||||
double *n2,
|
||||
const long num_band,
|
||||
const double temperature,
|
||||
const long triplet[3],
|
||||
static void detailed_imag_self_energy_at_triplet(
|
||||
double *detailed_imag_self_energy, double *imag_self_energy,
|
||||
const long num_band0, const long num_band, const double *fc3_normal_squared,
|
||||
const double *frequencies, const long triplet[3], const double *g1,
|
||||
const double *g2_3, const char *g_zero, const double *temperatures,
|
||||
const long num_temps, const double cutoff_frequency);
|
||||
static double collect_detailed_imag_self_energy(
|
||||
double *imag_self_energy, const long num_band,
|
||||
const double *fc3_normal_squared, const double *n1, const double *n2,
|
||||
const double *g1, const double *g2_3, const char *g_zero);
|
||||
static double collect_detailed_imag_self_energy_0K(
|
||||
double *imag_self_energy, const long num_band,
|
||||
const double *fc3_normal_squared, const double *n1, const double *n2,
|
||||
const double *g, const char *g_zero);
|
||||
static void set_occupations(double *n1, double *n2, const long num_band,
|
||||
const double temperature, const long triplet[3],
|
||||
const double *frequencies,
|
||||
const double cutoff_frequency);
|
||||
|
||||
void ise_get_imag_self_energy_at_bands_with_g(double *imag_self_energy,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double temperature,
|
||||
const double cutoff_frequency,
|
||||
const long num_frequency_points,
|
||||
const long frequency_point_index)
|
||||
{
|
||||
long i, j, num_triplets, num_band0, num_band, num_band_prod;
|
||||
long num_g_pos, g_index_dims, g_index_shift;
|
||||
long(*g_pos)[4];
|
||||
double *ise;
|
||||
long at_a_frequency_point;
|
||||
void ise_get_imag_self_energy_at_bands_with_g(
|
||||
double *imag_self_energy, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double *g, const char *g_zero,
|
||||
const double temperature, const double cutoff_frequency,
|
||||
const long num_frequency_points, const long frequency_point_index) {
|
||||
long i, j, num_triplets, num_band0, num_band, num_band_prod;
|
||||
long num_g_pos, g_index_dims, g_index_shift;
|
||||
long(*g_pos)[4];
|
||||
double *ise;
|
||||
long at_a_frequency_point;
|
||||
|
||||
g_pos = NULL;
|
||||
ise = NULL;
|
||||
g_pos = NULL;
|
||||
ise = NULL;
|
||||
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
ise = (double *)malloc(sizeof(double) * num_triplets * num_band0);
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
ise = (double *)malloc(sizeof(double) * num_triplets * num_band0);
|
||||
|
||||
if (frequency_point_index < 0)
|
||||
{
|
||||
/* frequency_points == frequencies at bands */
|
||||
at_a_frequency_point = 0;
|
||||
g_index_dims = num_band_prod;
|
||||
g_index_shift = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* At an arbitrary frequency point. */
|
||||
at_a_frequency_point = 1;
|
||||
g_index_dims = num_frequency_points * num_band * num_band;
|
||||
g_index_shift = frequency_point_index * num_band * num_band;
|
||||
}
|
||||
if (frequency_point_index < 0) {
|
||||
/* frequency_points == frequencies at bands */
|
||||
at_a_frequency_point = 0;
|
||||
g_index_dims = num_band_prod;
|
||||
g_index_shift = 0;
|
||||
} else {
|
||||
/* At an arbitrary frequency point. */
|
||||
at_a_frequency_point = 1;
|
||||
g_index_dims = num_frequency_points * num_band * num_band;
|
||||
g_index_shift = frequency_point_index * num_band * num_band;
|
||||
}
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(num_g_pos, j, g_pos)
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
g_pos = (long(*)[4])malloc(sizeof(long[4]) * num_band_prod);
|
||||
/* ise_set_g_pos only works for the case of frquency points at */
|
||||
/* bands. For frequency sampling mode, g_zero is assumed all */
|
||||
/* with the array shape of (num_triplets, num_band0, num_band, */
|
||||
/* num_band). */
|
||||
if (at_a_frequency_point)
|
||||
{
|
||||
num_g_pos = ise_set_g_pos_frequency_point(
|
||||
g_pos,
|
||||
num_band0,
|
||||
num_band,
|
||||
g_zero + i * g_index_dims + g_index_shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_g_pos = ise_set_g_pos(g_pos,
|
||||
num_band0,
|
||||
num_band,
|
||||
g_zero + i * num_band_prod);
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
g_pos = (long(*)[4])malloc(sizeof(long[4]) * num_band_prod);
|
||||
/* ise_set_g_pos only works for the case of frquency points at */
|
||||
/* bands. For frequency sampling mode, g_zero is assumed all */
|
||||
/* with the array shape of (num_triplets, num_band0, num_band, */
|
||||
/* num_band). */
|
||||
if (at_a_frequency_point) {
|
||||
num_g_pos = ise_set_g_pos_frequency_point(
|
||||
g_pos, num_band0, num_band,
|
||||
g_zero + i * g_index_dims + g_index_shift);
|
||||
} else {
|
||||
num_g_pos = ise_set_g_pos(g_pos, num_band0, num_band,
|
||||
g_zero + i * num_band_prod);
|
||||
}
|
||||
|
||||
ise_imag_self_energy_at_triplet(
|
||||
ise + i * num_band0, num_band0, num_band,
|
||||
fc3_normal_squared->data + i * num_band_prod, frequencies,
|
||||
triplets[i], triplet_weights[i],
|
||||
g + i * g_index_dims + g_index_shift,
|
||||
g + (i + num_triplets) * g_index_dims + g_index_shift, g_pos,
|
||||
num_g_pos, &temperature, 1, cutoff_frequency, 0,
|
||||
at_a_frequency_point);
|
||||
|
||||
free(g_pos);
|
||||
g_pos = NULL;
|
||||
}
|
||||
|
||||
ise_imag_self_energy_at_triplet(
|
||||
ise + i * num_band0,
|
||||
num_band0,
|
||||
num_band,
|
||||
fc3_normal_squared->data + i * num_band_prod,
|
||||
frequencies,
|
||||
triplets[i],
|
||||
triplet_weights[i],
|
||||
g + i * g_index_dims + g_index_shift,
|
||||
g + (i + num_triplets) * g_index_dims + g_index_shift,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
&temperature,
|
||||
1,
|
||||
cutoff_frequency,
|
||||
0,
|
||||
at_a_frequency_point);
|
||||
|
||||
free(g_pos);
|
||||
g_pos = NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
imag_self_energy[j] += ise[i * num_band0 + j];
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
imag_self_energy[j] += ise[i * num_band0 + j];
|
||||
}
|
||||
}
|
||||
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
}
|
||||
|
||||
void ise_get_detailed_imag_self_energy_at_bands_with_g(double *detailed_imag_self_energy,
|
||||
double *imag_self_energy_N,
|
||||
double *imag_self_energy_U,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double temperature,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
double *ise;
|
||||
long i, j, num_triplets, num_band0, num_band, num_band_prod;
|
||||
long *is_N;
|
||||
double ise_tmp, N, U;
|
||||
void ise_get_detailed_imag_self_energy_at_bands_with_g(
|
||||
double *detailed_imag_self_energy, double *imag_self_energy_N,
|
||||
double *imag_self_energy_U, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const long (*bz_grid_addresses)[3],
|
||||
const double *g, const char *g_zero, const double temperature,
|
||||
const double cutoff_frequency) {
|
||||
double *ise;
|
||||
long i, j, num_triplets, num_band0, num_band, num_band_prod;
|
||||
long *is_N;
|
||||
double ise_tmp, N, U;
|
||||
|
||||
ise = NULL;
|
||||
is_N = NULL;
|
||||
ise = NULL;
|
||||
is_N = NULL;
|
||||
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
ise = (double *)malloc(sizeof(double) * num_triplets * num_band0);
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
ise = (double *)malloc(sizeof(double) * num_triplets * num_band0);
|
||||
|
||||
/* detailed_imag_self_energy has the same shape as fc3_normal_squared. */
|
||||
/* detailed_imag_self_energy has the same shape as fc3_normal_squared. */
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
detailed_imag_self_energy_at_triplet(detailed_imag_self_energy + i * num_band_prod,
|
||||
ise + i * num_band0,
|
||||
num_band0,
|
||||
num_band,
|
||||
fc3_normal_squared->data + i * num_band_prod,
|
||||
frequencies,
|
||||
triplets[i],
|
||||
g + i * num_band_prod,
|
||||
g + (i + num_triplets) * num_band_prod,
|
||||
g_zero + i * num_band_prod,
|
||||
&temperature,
|
||||
1,
|
||||
cutoff_frequency);
|
||||
}
|
||||
|
||||
is_N = (long *)malloc(sizeof(long) * num_triplets);
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
is_N[i] = tpl_is_N(triplets[i], bz_grid_addresses);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
N = 0;
|
||||
U = 0;
|
||||
/* #ifdef PHPYOPENMP */
|
||||
/* #pragma omp parallel for private(ise_tmp) reduction(+:N,U) */
|
||||
/* #endif */
|
||||
for (j = 0; j < num_triplets; j++)
|
||||
{
|
||||
ise_tmp = ise[j * num_band0 + i] * triplet_weights[j];
|
||||
if (is_N[j])
|
||||
{
|
||||
N += ise_tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
U += ise_tmp;
|
||||
}
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
detailed_imag_self_energy_at_triplet(
|
||||
detailed_imag_self_energy + i * num_band_prod, ise + i * num_band0,
|
||||
num_band0, num_band, fc3_normal_squared->data + i * num_band_prod,
|
||||
frequencies, triplets[i], g + i * num_band_prod,
|
||||
g + (i + num_triplets) * num_band_prod, g_zero + i * num_band_prod,
|
||||
&temperature, 1, cutoff_frequency);
|
||||
}
|
||||
imag_self_energy_N[i] = N;
|
||||
imag_self_energy_U[i] = U;
|
||||
}
|
||||
|
||||
free(is_N);
|
||||
is_N = NULL;
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
is_N = (long *)malloc(sizeof(long) * num_triplets);
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
is_N[i] = tpl_is_N(triplets[i], bz_grid_addresses);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
N = 0;
|
||||
U = 0;
|
||||
/* #ifdef PHPYOPENMP */
|
||||
/* #pragma omp parallel for private(ise_tmp) reduction(+:N,U) */
|
||||
/* #endif */
|
||||
for (j = 0; j < num_triplets; j++) {
|
||||
ise_tmp = ise[j * num_band0 + i] * triplet_weights[j];
|
||||
if (is_N[j]) {
|
||||
N += ise_tmp;
|
||||
} else {
|
||||
U += ise_tmp;
|
||||
}
|
||||
}
|
||||
imag_self_energy_N[i] = N;
|
||||
imag_self_energy_U[i] = U;
|
||||
}
|
||||
|
||||
free(is_N);
|
||||
is_N = NULL;
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
}
|
||||
|
||||
void ise_imag_self_energy_at_triplet(double *imag_self_energy,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long triplet[3],
|
||||
const long triplet_weight,
|
||||
const double *g1,
|
||||
const double *g2_3,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const double *temperatures,
|
||||
const long num_temps,
|
||||
const double cutoff_frequency,
|
||||
const long openmp_at_bands,
|
||||
const long at_a_frequency_point)
|
||||
{
|
||||
long i, j;
|
||||
double *n1, *n2;
|
||||
long g_pos_3;
|
||||
void ise_imag_self_energy_at_triplet(
|
||||
double *imag_self_energy, const long num_band0, const long num_band,
|
||||
const double *fc3_normal_squared, const double *frequencies,
|
||||
const long triplet[3], const long triplet_weight, const double *g1,
|
||||
const double *g2_3, const long (*g_pos)[4], const long num_g_pos,
|
||||
const double *temperatures, const long num_temps,
|
||||
const double cutoff_frequency, const long openmp_at_bands,
|
||||
const long at_a_frequency_point) {
|
||||
long i, j;
|
||||
double *n1, *n2;
|
||||
long g_pos_3;
|
||||
|
||||
n1 = (double *)malloc(sizeof(double) * num_temps * num_band);
|
||||
n2 = (double *)malloc(sizeof(double) * num_temps * num_band);
|
||||
for (i = 0; i < num_temps; i++)
|
||||
{
|
||||
set_occupations(n1 + i * num_band,
|
||||
n2 + i * num_band,
|
||||
num_band,
|
||||
temperatures[i],
|
||||
triplet,
|
||||
frequencies,
|
||||
cutoff_frequency);
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0 * num_temps; i++)
|
||||
{
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
|
||||
/* Do not use OpenMP here!! */
|
||||
/* g_pos[i][0] takes value 0 <= x < num_band0 only, */
|
||||
/* which causes race condition. */
|
||||
for (i = 0; i < num_g_pos; i++)
|
||||
{
|
||||
if (at_a_frequency_point)
|
||||
{
|
||||
/* At an arbitrary frequency point */
|
||||
g_pos_3 = g_pos[i][3] % (num_band * num_band);
|
||||
n1 = (double *)malloc(sizeof(double) * num_temps * num_band);
|
||||
n2 = (double *)malloc(sizeof(double) * num_temps * num_band);
|
||||
for (i = 0; i < num_temps; i++) {
|
||||
set_occupations(n1 + i * num_band, n2 + i * num_band, num_band,
|
||||
temperatures[i], triplet, frequencies,
|
||||
cutoff_frequency);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* frequency_points == frequencies at bands */
|
||||
g_pos_3 = g_pos[i][3];
|
||||
|
||||
for (i = 0; i < num_band0 * num_temps; i++) {
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
for (j = 0; j < num_temps; j++)
|
||||
{
|
||||
if (n1[j * num_band + g_pos[i][1]] < 0 ||
|
||||
n2[j * num_band + g_pos[i][2]] < 0)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (temperatures[j] > 0)
|
||||
{
|
||||
imag_self_energy[j * num_band0 + g_pos[i][0]] +=
|
||||
((n1[j * num_band + g_pos[i][1]] +
|
||||
n2[j * num_band + g_pos[i][2]] + 1) *
|
||||
g1[g_pos_3] +
|
||||
(n1[j * num_band + g_pos[i][1]] -
|
||||
n2[j * num_band + g_pos[i][2]]) *
|
||||
g2_3[g_pos_3]) *
|
||||
fc3_normal_squared[g_pos[i][3]] * triplet_weight;
|
||||
|
||||
/* Do not use OpenMP here!! */
|
||||
/* g_pos[i][0] takes value 0 <= x < num_band0 only, */
|
||||
/* which causes race condition. */
|
||||
for (i = 0; i < num_g_pos; i++) {
|
||||
if (at_a_frequency_point) {
|
||||
/* At an arbitrary frequency point */
|
||||
g_pos_3 = g_pos[i][3] % (num_band * num_band);
|
||||
} else {
|
||||
/* frequency_points == frequencies at bands */
|
||||
g_pos_3 = g_pos[i][3];
|
||||
}
|
||||
else
|
||||
{
|
||||
imag_self_energy[j * num_band0 + g_pos[i][0]] +=
|
||||
g1[g_pos_3] * fc3_normal_squared[g_pos[i][3]] * triplet_weight;
|
||||
for (j = 0; j < num_temps; j++) {
|
||||
if (n1[j * num_band + g_pos[i][1]] < 0 ||
|
||||
n2[j * num_band + g_pos[i][2]] < 0) {
|
||||
;
|
||||
} else {
|
||||
if (temperatures[j] > 0) {
|
||||
imag_self_energy[j * num_band0 + g_pos[i][0]] +=
|
||||
((n1[j * num_band + g_pos[i][1]] +
|
||||
n2[j * num_band + g_pos[i][2]] + 1) *
|
||||
g1[g_pos_3] +
|
||||
(n1[j * num_band + g_pos[i][1]] -
|
||||
n2[j * num_band + g_pos[i][2]]) *
|
||||
g2_3[g_pos_3]) *
|
||||
fc3_normal_squared[g_pos[i][3]] * triplet_weight;
|
||||
} else {
|
||||
imag_self_energy[j * num_band0 + g_pos[i][0]] +=
|
||||
g1[g_pos_3] * fc3_normal_squared[g_pos[i][3]] *
|
||||
triplet_weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(n1);
|
||||
n1 = NULL;
|
||||
free(n2);
|
||||
n2 = NULL;
|
||||
free(n1);
|
||||
n1 = NULL;
|
||||
free(n2);
|
||||
n2 = NULL;
|
||||
}
|
||||
|
||||
long ise_set_g_pos(long (*g_pos)[4],
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const char *g_zero)
|
||||
{
|
||||
long num_g_pos, j, k, l, jkl;
|
||||
long ise_set_g_pos(long (*g_pos)[4], const long num_band0, const long num_band,
|
||||
const char *g_zero) {
|
||||
long num_g_pos, j, k, l, jkl;
|
||||
|
||||
num_g_pos = 0;
|
||||
jkl = 0;
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
for (k = 0; k < num_band; k++)
|
||||
{
|
||||
for (l = 0; l < num_band; l++)
|
||||
{
|
||||
if (!g_zero[jkl])
|
||||
{
|
||||
g_pos[num_g_pos][0] = j;
|
||||
g_pos[num_g_pos][1] = k;
|
||||
g_pos[num_g_pos][2] = l;
|
||||
g_pos[num_g_pos][3] = jkl;
|
||||
num_g_pos++;
|
||||
num_g_pos = 0;
|
||||
jkl = 0;
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
for (k = 0; k < num_band; k++) {
|
||||
for (l = 0; l < num_band; l++) {
|
||||
if (!g_zero[jkl]) {
|
||||
g_pos[num_g_pos][0] = j;
|
||||
g_pos[num_g_pos][1] = k;
|
||||
g_pos[num_g_pos][2] = l;
|
||||
g_pos[num_g_pos][3] = jkl;
|
||||
num_g_pos++;
|
||||
}
|
||||
jkl++;
|
||||
}
|
||||
}
|
||||
jkl++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return num_g_pos;
|
||||
return num_g_pos;
|
||||
}
|
||||
|
||||
static long ise_set_g_pos_frequency_point(long (*g_pos)[4],
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const char *g_zero)
|
||||
{
|
||||
long num_g_pos, j, k, l, kl, jkl;
|
||||
const char *g_zero) {
|
||||
long num_g_pos, j, k, l, kl, jkl;
|
||||
|
||||
num_g_pos = 0;
|
||||
jkl = 0;
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
kl = 0;
|
||||
for (k = 0; k < num_band; k++)
|
||||
{
|
||||
for (l = 0; l < num_band; l++)
|
||||
{
|
||||
if (!g_zero[kl])
|
||||
{
|
||||
g_pos[num_g_pos][0] = j;
|
||||
g_pos[num_g_pos][1] = k;
|
||||
g_pos[num_g_pos][2] = l;
|
||||
g_pos[num_g_pos][3] = jkl;
|
||||
num_g_pos++;
|
||||
num_g_pos = 0;
|
||||
jkl = 0;
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
kl = 0;
|
||||
for (k = 0; k < num_band; k++) {
|
||||
for (l = 0; l < num_band; l++) {
|
||||
if (!g_zero[kl]) {
|
||||
g_pos[num_g_pos][0] = j;
|
||||
g_pos[num_g_pos][1] = k;
|
||||
g_pos[num_g_pos][2] = l;
|
||||
g_pos[num_g_pos][3] = jkl;
|
||||
num_g_pos++;
|
||||
}
|
||||
jkl++;
|
||||
kl++;
|
||||
}
|
||||
}
|
||||
jkl++;
|
||||
kl++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return num_g_pos;
|
||||
return num_g_pos;
|
||||
}
|
||||
|
||||
static void
|
||||
detailed_imag_self_energy_at_triplet(double *detailed_imag_self_energy,
|
||||
double *imag_self_energy,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long triplet[3],
|
||||
const double *g1,
|
||||
const double *g2_3,
|
||||
const char *g_zero,
|
||||
const double *temperatures,
|
||||
const long num_temps,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j, adrs_shift;
|
||||
double *n1, *n2;
|
||||
static void detailed_imag_self_energy_at_triplet(
|
||||
double *detailed_imag_self_energy, double *imag_self_energy,
|
||||
const long num_band0, const long num_band, const double *fc3_normal_squared,
|
||||
const double *frequencies, const long triplet[3], const double *g1,
|
||||
const double *g2_3, const char *g_zero, const double *temperatures,
|
||||
const long num_temps, const double cutoff_frequency) {
|
||||
long i, j, adrs_shift;
|
||||
double *n1, *n2;
|
||||
|
||||
n1 = NULL;
|
||||
n2 = NULL;
|
||||
n1 = NULL;
|
||||
n2 = NULL;
|
||||
|
||||
n1 = (double *)malloc(sizeof(double) * num_band);
|
||||
n2 = (double *)malloc(sizeof(double) * num_band);
|
||||
n1 = (double *)malloc(sizeof(double) * num_band);
|
||||
n2 = (double *)malloc(sizeof(double) * num_band);
|
||||
|
||||
for (i = 0; i < num_temps; i++)
|
||||
{
|
||||
set_occupations(n1,
|
||||
n2,
|
||||
num_band,
|
||||
temperatures[i],
|
||||
triplet,
|
||||
frequencies,
|
||||
cutoff_frequency);
|
||||
for (i = 0; i < num_temps; i++) {
|
||||
set_occupations(n1, n2, num_band, temperatures[i], triplet, frequencies,
|
||||
cutoff_frequency);
|
||||
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
adrs_shift = j * num_band * num_band;
|
||||
if (temperatures[i] > 0)
|
||||
{
|
||||
imag_self_energy[i * num_band0 + j] =
|
||||
collect_detailed_imag_self_energy(detailed_imag_self_energy + adrs_shift,
|
||||
num_band,
|
||||
fc3_normal_squared + adrs_shift,
|
||||
n1,
|
||||
n2,
|
||||
g1 + adrs_shift,
|
||||
g2_3 + adrs_shift,
|
||||
g_zero + adrs_shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
imag_self_energy[i * num_band0 + j] =
|
||||
collect_detailed_imag_self_energy_0K(detailed_imag_self_energy + adrs_shift,
|
||||
num_band,
|
||||
fc3_normal_squared + adrs_shift,
|
||||
n1,
|
||||
n2,
|
||||
g1 + adrs_shift,
|
||||
g_zero + adrs_shift);
|
||||
}
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
adrs_shift = j * num_band * num_band;
|
||||
if (temperatures[i] > 0) {
|
||||
imag_self_energy[i * num_band0 + j] =
|
||||
collect_detailed_imag_self_energy(
|
||||
detailed_imag_self_energy + adrs_shift, num_band,
|
||||
fc3_normal_squared + adrs_shift, n1, n2,
|
||||
g1 + adrs_shift, g2_3 + adrs_shift,
|
||||
g_zero + adrs_shift);
|
||||
} else {
|
||||
imag_self_energy[i * num_band0 + j] =
|
||||
collect_detailed_imag_self_energy_0K(
|
||||
detailed_imag_self_energy + adrs_shift, num_band,
|
||||
fc3_normal_squared + adrs_shift, n1, n2,
|
||||
g1 + adrs_shift, g_zero + adrs_shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(n1);
|
||||
n1 = NULL;
|
||||
free(n2);
|
||||
n2 = NULL;
|
||||
free(n1);
|
||||
n1 = NULL;
|
||||
free(n2);
|
||||
n2 = NULL;
|
||||
}
|
||||
|
||||
static double
|
||||
collect_detailed_imag_self_energy(double *imag_self_energy,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *n1,
|
||||
const double *n2,
|
||||
const double *g1,
|
||||
const double *g2_3,
|
||||
const char *g_zero)
|
||||
{
|
||||
long ij, i, j;
|
||||
double sum_g;
|
||||
static double collect_detailed_imag_self_energy(
|
||||
double *imag_self_energy, const long num_band,
|
||||
const double *fc3_normal_squared, const double *n1, const double *n2,
|
||||
const double *g1, const double *g2_3, const char *g_zero) {
|
||||
long ij, i, j;
|
||||
double sum_g;
|
||||
|
||||
sum_g = 0;
|
||||
for (ij = 0; ij < num_band * num_band; ij++)
|
||||
{
|
||||
imag_self_energy[ij] = 0;
|
||||
if (g_zero[ij])
|
||||
{
|
||||
continue;
|
||||
sum_g = 0;
|
||||
for (ij = 0; ij < num_band * num_band; ij++) {
|
||||
imag_self_energy[ij] = 0;
|
||||
if (g_zero[ij]) {
|
||||
continue;
|
||||
}
|
||||
i = ij / num_band;
|
||||
j = ij % num_band;
|
||||
if (n1[i] < 0 || n2[j] < 0) {
|
||||
continue;
|
||||
}
|
||||
imag_self_energy[ij] =
|
||||
(((n1[i] + n2[j] + 1) * g1[ij] + (n1[i] - n2[j]) * g2_3[ij]) *
|
||||
fc3_normal_squared[ij]);
|
||||
sum_g += imag_self_energy[ij];
|
||||
}
|
||||
i = ij / num_band;
|
||||
j = ij % num_band;
|
||||
if (n1[i] < 0 || n2[j] < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
imag_self_energy[ij] = (((n1[i] + n2[j] + 1) * g1[ij] +
|
||||
(n1[i] - n2[j]) * g2_3[ij]) *
|
||||
fc3_normal_squared[ij]);
|
||||
sum_g += imag_self_energy[ij];
|
||||
}
|
||||
|
||||
return sum_g;
|
||||
return sum_g;
|
||||
}
|
||||
|
||||
static double
|
||||
collect_detailed_imag_self_energy_0K(double *imag_self_energy,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *n1,
|
||||
const double *n2,
|
||||
const double *g1,
|
||||
const char *g_zero)
|
||||
{
|
||||
long ij, i, j;
|
||||
double sum_g;
|
||||
static double collect_detailed_imag_self_energy_0K(
|
||||
double *imag_self_energy, const long num_band,
|
||||
const double *fc3_normal_squared, const double *n1, const double *n2,
|
||||
const double *g1, const char *g_zero) {
|
||||
long ij, i, j;
|
||||
double sum_g;
|
||||
|
||||
sum_g = 0;
|
||||
for (ij = 0; ij < num_band * num_band; ij++)
|
||||
{
|
||||
imag_self_energy[ij] = 0;
|
||||
if (g_zero[ij])
|
||||
{
|
||||
continue;
|
||||
sum_g = 0;
|
||||
for (ij = 0; ij < num_band * num_band; ij++) {
|
||||
imag_self_energy[ij] = 0;
|
||||
if (g_zero[ij]) {
|
||||
continue;
|
||||
}
|
||||
i = ij / num_band;
|
||||
j = ij % num_band;
|
||||
if (n1[i] < 0 || n2[j] < 0) {
|
||||
continue;
|
||||
}
|
||||
imag_self_energy[ij] = g1[ij] * fc3_normal_squared[ij];
|
||||
sum_g += imag_self_energy[ij];
|
||||
}
|
||||
i = ij / num_band;
|
||||
j = ij % num_band;
|
||||
if (n1[i] < 0 || n2[j] < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
imag_self_energy[ij] = g1[ij] * fc3_normal_squared[ij];
|
||||
sum_g += imag_self_energy[ij];
|
||||
}
|
||||
|
||||
return sum_g;
|
||||
return sum_g;
|
||||
}
|
||||
|
||||
static void set_occupations(double *n1,
|
||||
double *n2,
|
||||
const long num_band,
|
||||
const double temperature,
|
||||
const long triplet[3],
|
||||
static void set_occupations(double *n1, double *n2, const long num_band,
|
||||
const double temperature, const long triplet[3],
|
||||
const double *frequencies,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long j;
|
||||
double f1, f2;
|
||||
const double cutoff_frequency) {
|
||||
long j;
|
||||
double f1, f2;
|
||||
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
f1 = frequencies[triplet[1] * num_band + j];
|
||||
f2 = frequencies[triplet[2] * num_band + j];
|
||||
if (f1 > cutoff_frequency)
|
||||
{
|
||||
n1[j] = phonoc_bose_einstein(f1, temperature);
|
||||
for (j = 0; j < num_band; j++) {
|
||||
f1 = frequencies[triplet[1] * num_band + j];
|
||||
f2 = frequencies[triplet[2] * num_band + j];
|
||||
if (f1 > cutoff_frequency) {
|
||||
n1[j] = phonoc_bose_einstein(f1, temperature);
|
||||
} else {
|
||||
n1[j] = -1;
|
||||
}
|
||||
if (f2 > cutoff_frequency) {
|
||||
n2[j] = phonoc_bose_einstein(f2, temperature);
|
||||
} else {
|
||||
n2[j] = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
n1[j] = -1;
|
||||
}
|
||||
if (f2 > cutoff_frequency)
|
||||
{
|
||||
n2[j] = phonoc_bose_einstein(f2, temperature);
|
||||
}
|
||||
else
|
||||
{
|
||||
n2[j] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,50 +36,31 @@
|
|||
#define __imag_self_energy_with_g_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "phonoc_array.h"
|
||||
|
||||
void ise_get_imag_self_energy_at_bands_with_g(double *imag_self_energy,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double temperature,
|
||||
const double cutoff_frequency,
|
||||
const long num_frequency_points,
|
||||
const long frequency_point_index);
|
||||
void ise_get_detailed_imag_self_energy_at_bands_with_g(double *detailed_imag_self_energy,
|
||||
double *imag_self_energy_N,
|
||||
double *imag_self_energy_U,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double temperature,
|
||||
const double cutoff_frequency);
|
||||
void ise_imag_self_energy_at_triplet(double *imag_self_energy,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long triplet[3],
|
||||
const long triplet_weight,
|
||||
const double *g1,
|
||||
const double *g2_3,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const double *temperatures,
|
||||
const long num_temps,
|
||||
const double cutoff_frequency,
|
||||
const long openmp_at_bands,
|
||||
const long at_a_frequency_point);
|
||||
long ise_set_g_pos(long (*g_pos)[4],
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
void ise_get_imag_self_energy_at_bands_with_g(
|
||||
double *imag_self_energy, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double *g, const char *g_zero,
|
||||
const double temperature, const double cutoff_frequency,
|
||||
const long num_frequency_points, const long frequency_point_index);
|
||||
void ise_get_detailed_imag_self_energy_at_bands_with_g(
|
||||
double *detailed_imag_self_energy, double *imag_self_energy_N,
|
||||
double *imag_self_energy_U, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const long (*bz_grid_addresses)[3],
|
||||
const double *g, const char *g_zero, const double temperature,
|
||||
const double cutoff_frequency);
|
||||
void ise_imag_self_energy_at_triplet(
|
||||
double *imag_self_energy, const long num_band0, const long num_band,
|
||||
const double *fc3_normal_squared, const double *frequencies,
|
||||
const long triplet[3], const long triplet_weight, const double *g1,
|
||||
const double *g2_3, const long (*g_pos)[4], const long num_g_pos,
|
||||
const double *temperatures, const long num_temps,
|
||||
const double cutoff_frequency, const long openmp_at_bands,
|
||||
const long at_a_frequency_point);
|
||||
long ise_set_g_pos(long (*g_pos)[4], const long num_band0, const long num_band,
|
||||
const char *g_zero);
|
||||
|
||||
#endif
|
||||
|
|
576
c/interaction.c
576
c/interaction.c
|
@ -32,418 +32,250 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "interaction.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bzgrid.h"
|
||||
#include "interaction.h"
|
||||
#include "imag_self_energy_with_g.h"
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_array.h"
|
||||
#include "real_to_reciprocal.h"
|
||||
#include "reciprocal_to_normal.h"
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
static const long index_exchange[6][3] = {{0, 1, 2},
|
||||
{2, 0, 1},
|
||||
{1, 2, 0},
|
||||
{2, 1, 0},
|
||||
{0, 2, 1},
|
||||
{1, 0, 2}};
|
||||
static void real_to_normal(double *fc3_normal_squared,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const double *freqs0,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index,
|
||||
const long num_triplets,
|
||||
const long openmp_at_bands);
|
||||
static void real_to_normal_sym_q(double *fc3_normal_squared,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
double *const freqs[3],
|
||||
lapack_complex_double *const eigvecs[3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index,
|
||||
const long num_triplets,
|
||||
const long openmp_at_bands);
|
||||
static const long index_exchange[6][3] = {{0, 1, 2}, {2, 0, 1}, {1, 2, 0},
|
||||
{2, 1, 0}, {0, 2, 1}, {1, 0, 2}};
|
||||
static void real_to_normal(
|
||||
double *fc3_normal_squared, const long (*g_pos)[4], const long num_g_pos,
|
||||
const double *freqs0, const double *freqs1, const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2, const double *fc3,
|
||||
const long is_compact_fc3, const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3], const long multi_dims[2],
|
||||
const long (*multiplicity)[2], const double *masses, const long *p2s_map,
|
||||
const long *s2p_map, const long *band_indices, const long num_band,
|
||||
const double cutoff_frequency, const long triplet_index,
|
||||
const long num_triplets, const long openmp_at_bands);
|
||||
static void real_to_normal_sym_q(
|
||||
double *fc3_normal_squared, const long (*g_pos)[4], const long num_g_pos,
|
||||
double *const freqs[3], lapack_complex_double *const eigvecs[3],
|
||||
const double *fc3, const long is_compact_fc3,
|
||||
const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3], const long multi_dims[2],
|
||||
const long (*multiplicity)[2], const double *masses, const long *p2s_map,
|
||||
const long *s2p_map, const long *band_indices, const long num_band0,
|
||||
const long num_band, const double cutoff_frequency,
|
||||
const long triplet_index, const long num_triplets,
|
||||
const long openmp_at_bands);
|
||||
|
||||
/* fc3_normal_squared[num_triplets, num_band0, num_band, num_band] */
|
||||
void itr_get_interaction(Darray *fc3_normal_squared,
|
||||
const char *g_zero,
|
||||
void itr_get_interaction(Darray *fc3_normal_squared, const char *g_zero,
|
||||
const Darray *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long openmp_per_triplets;
|
||||
long(*g_pos)[4];
|
||||
long i;
|
||||
long num_band, num_band0, num_band_prod, num_g_pos;
|
||||
const long (*multiplicity)[2], const double *masses,
|
||||
const long *p2s_map, const long *s2p_map,
|
||||
const long *band_indices, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency) {
|
||||
long openmp_per_triplets;
|
||||
long(*g_pos)[4];
|
||||
long i;
|
||||
long num_band, num_band0, num_band_prod, num_g_pos;
|
||||
|
||||
g_pos = NULL;
|
||||
g_pos = NULL;
|
||||
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = frequencies->dims[1];
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = frequencies->dims[1];
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
|
||||
if (num_triplets > num_band)
|
||||
{
|
||||
openmp_per_triplets = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
openmp_per_triplets = 0;
|
||||
}
|
||||
if (num_triplets > num_band) {
|
||||
openmp_per_triplets = 1;
|
||||
} else {
|
||||
openmp_per_triplets = 0;
|
||||
}
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for schedule(guided) private(num_g_pos, g_pos) if (openmp_per_triplets)
|
||||
#pragma omp parallel for schedule(guided) private( \
|
||||
num_g_pos, g_pos) if (openmp_per_triplets)
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
g_pos = (long(*)[4])malloc(sizeof(long[4]) * num_band_prod);
|
||||
num_g_pos = ise_set_g_pos(g_pos,
|
||||
num_band0,
|
||||
num_band,
|
||||
g_zero + i * num_band_prod);
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
g_pos = (long(*)[4])malloc(sizeof(long[4]) * num_band_prod);
|
||||
num_g_pos = ise_set_g_pos(g_pos, num_band0, num_band,
|
||||
g_zero + i * num_band_prod);
|
||||
|
||||
itr_get_interaction_at_triplet(
|
||||
fc3_normal_squared->data + i * num_band_prod,
|
||||
num_band0,
|
||||
num_band,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
frequencies->data,
|
||||
eigenvectors,
|
||||
triplets[i],
|
||||
bzgrid,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices,
|
||||
symmetrize_fc3_q,
|
||||
cutoff_frequency,
|
||||
i,
|
||||
num_triplets,
|
||||
1 - openmp_per_triplets);
|
||||
itr_get_interaction_at_triplet(
|
||||
fc3_normal_squared->data + i * num_band_prod, num_band0, num_band,
|
||||
g_pos, num_g_pos, frequencies->data, eigenvectors, triplets[i],
|
||||
bzgrid, fc3, is_compact_fc3, svecs, multi_dims, multiplicity,
|
||||
masses, p2s_map, s2p_map, band_indices, symmetrize_fc3_q,
|
||||
cutoff_frequency, i, num_triplets, 1 - openmp_per_triplets);
|
||||
|
||||
free(g_pos);
|
||||
g_pos = NULL;
|
||||
}
|
||||
free(g_pos);
|
||||
g_pos = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void itr_get_interaction_at_triplet(double *fc3_normal_squared,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long triplet[3],
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index, /* only for print */
|
||||
const long num_triplets, /* only for print */
|
||||
const long openmp_at_bands)
|
||||
{
|
||||
long j, k;
|
||||
double *freqs[3];
|
||||
lapack_complex_double *eigvecs[3];
|
||||
double q_vecs[3][3];
|
||||
void itr_get_interaction_at_triplet(
|
||||
double *fc3_normal_squared, const long num_band0, const long num_band,
|
||||
const long (*g_pos)[4], const long num_g_pos, const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors, const long triplet[3],
|
||||
const ConstBZGrid *bzgrid, const double *fc3, const long is_compact_fc3,
|
||||
const double (*svecs)[3], const long multi_dims[2],
|
||||
const long (*multiplicity)[2], const double *masses, const long *p2s_map,
|
||||
const long *s2p_map, const long *band_indices, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index, /* only for print */
|
||||
const long num_triplets, /* only for print */
|
||||
const long openmp_at_bands) {
|
||||
long j, k;
|
||||
double *freqs[3];
|
||||
lapack_complex_double *eigvecs[3];
|
||||
double q_vecs[3][3];
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
q_vecs[j][k] = ((double)bzgrid->addresses[triplet[j]][k]) / bzgrid->D_diag[k];
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
q_vecs[j][k] =
|
||||
((double)bzgrid->addresses[triplet[j]][k]) / bzgrid->D_diag[k];
|
||||
}
|
||||
bzg_multiply_matrix_vector_ld3(q_vecs[j], bzgrid->Q, q_vecs[j]);
|
||||
}
|
||||
bzg_multiply_matrix_vector_ld3(q_vecs[j], bzgrid->Q, q_vecs[j]);
|
||||
}
|
||||
|
||||
if (symmetrize_fc3_q)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
freqs[j] = (double *)malloc(sizeof(double) * num_band);
|
||||
eigvecs[j] = (lapack_complex_double *)
|
||||
malloc(sizeof(lapack_complex_double) * num_band * num_band);
|
||||
for (k = 0; k < num_band; k++)
|
||||
{
|
||||
freqs[j][k] = frequencies[triplet[j] * num_band + k];
|
||||
}
|
||||
for (k = 0; k < num_band * num_band; k++)
|
||||
{
|
||||
eigvecs[j][k] = eigenvectors[triplet[j] * num_band * num_band + k];
|
||||
}
|
||||
if (symmetrize_fc3_q) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
freqs[j] = (double *)malloc(sizeof(double) * num_band);
|
||||
eigvecs[j] = (lapack_complex_double *)malloc(
|
||||
sizeof(lapack_complex_double) * num_band * num_band);
|
||||
for (k = 0; k < num_band; k++) {
|
||||
freqs[j][k] = frequencies[triplet[j] * num_band + k];
|
||||
}
|
||||
for (k = 0; k < num_band * num_band; k++) {
|
||||
eigvecs[j][k] =
|
||||
eigenvectors[triplet[j] * num_band * num_band + k];
|
||||
}
|
||||
}
|
||||
real_to_normal_sym_q(
|
||||
fc3_normal_squared, g_pos, num_g_pos, freqs, eigvecs, fc3,
|
||||
is_compact_fc3, q_vecs, /* q0, q1, q2 */
|
||||
svecs, multi_dims, multiplicity, masses, p2s_map, s2p_map,
|
||||
band_indices, num_band0, num_band, cutoff_frequency, triplet_index,
|
||||
num_triplets, openmp_at_bands);
|
||||
for (j = 0; j < 3; j++) {
|
||||
free(freqs[j]);
|
||||
freqs[j] = NULL;
|
||||
free(eigvecs[j]);
|
||||
eigvecs[j] = NULL;
|
||||
}
|
||||
} else {
|
||||
real_to_normal(fc3_normal_squared, g_pos, num_g_pos,
|
||||
frequencies + triplet[0] * num_band,
|
||||
frequencies + triplet[1] * num_band,
|
||||
frequencies + triplet[2] * num_band,
|
||||
eigenvectors + triplet[0] * num_band * num_band,
|
||||
eigenvectors + triplet[1] * num_band * num_band,
|
||||
eigenvectors + triplet[2] * num_band * num_band, fc3,
|
||||
is_compact_fc3, q_vecs, /* q0, q1, q2 */
|
||||
svecs, multi_dims, multiplicity, masses, p2s_map,
|
||||
s2p_map, band_indices, num_band, cutoff_frequency,
|
||||
triplet_index, num_triplets, openmp_at_bands);
|
||||
}
|
||||
real_to_normal_sym_q(fc3_normal_squared,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
freqs,
|
||||
eigvecs,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
q_vecs, /* q0, q1, q2 */
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices,
|
||||
num_band0,
|
||||
num_band,
|
||||
cutoff_frequency,
|
||||
triplet_index,
|
||||
num_triplets,
|
||||
openmp_at_bands);
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
free(freqs[j]);
|
||||
freqs[j] = NULL;
|
||||
free(eigvecs[j]);
|
||||
eigvecs[j] = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
real_to_normal(fc3_normal_squared,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
frequencies + triplet[0] * num_band,
|
||||
frequencies + triplet[1] * num_band,
|
||||
frequencies + triplet[2] * num_band,
|
||||
eigenvectors + triplet[0] * num_band * num_band,
|
||||
eigenvectors + triplet[1] * num_band * num_band,
|
||||
eigenvectors + triplet[2] * num_band * num_band,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
q_vecs, /* q0, q1, q2 */
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices,
|
||||
num_band,
|
||||
cutoff_frequency,
|
||||
triplet_index,
|
||||
num_triplets,
|
||||
openmp_at_bands);
|
||||
}
|
||||
}
|
||||
|
||||
static void real_to_normal(double *fc3_normal_squared,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const double *freqs0,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index,
|
||||
const long num_triplets,
|
||||
const long openmp_at_bands)
|
||||
{
|
||||
lapack_complex_double *fc3_reciprocal;
|
||||
static void real_to_normal(
|
||||
double *fc3_normal_squared, const long (*g_pos)[4], const long num_g_pos,
|
||||
const double *freqs0, const double *freqs1, const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2, const double *fc3,
|
||||
const long is_compact_fc3, const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3], const long multi_dims[2],
|
||||
const long (*multiplicity)[2], const double *masses, const long *p2s_map,
|
||||
const long *s2p_map, const long *band_indices, const long num_band,
|
||||
const double cutoff_frequency, const long triplet_index,
|
||||
const long num_triplets, const long openmp_at_bands) {
|
||||
lapack_complex_double *fc3_reciprocal;
|
||||
|
||||
fc3_reciprocal =
|
||||
(lapack_complex_double *)malloc(sizeof(lapack_complex_double) *
|
||||
num_band * num_band * num_band);
|
||||
r2r_real_to_reciprocal(fc3_reciprocal,
|
||||
q_vecs,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
openmp_at_bands);
|
||||
fc3_reciprocal = (lapack_complex_double *)malloc(
|
||||
sizeof(lapack_complex_double) * num_band * num_band * num_band);
|
||||
r2r_real_to_reciprocal(fc3_reciprocal, q_vecs, fc3, is_compact_fc3, svecs,
|
||||
multi_dims, multiplicity, p2s_map, s2p_map,
|
||||
openmp_at_bands);
|
||||
|
||||
#ifdef MEASURE_R2N
|
||||
if (openmp_at_bands && num_triplets > 0)
|
||||
{
|
||||
printf("At triplet %d/%d (# of bands=%d):\n",
|
||||
triplet_index, num_triplets, num_band0);
|
||||
}
|
||||
if (openmp_at_bands && num_triplets > 0) {
|
||||
printf("At triplet %d/%d (# of bands=%d):\n", triplet_index,
|
||||
num_triplets, num_band0);
|
||||
}
|
||||
#endif
|
||||
reciprocal_to_normal_squared(fc3_normal_squared,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
fc3_reciprocal,
|
||||
freqs0,
|
||||
freqs1,
|
||||
freqs2,
|
||||
eigvecs0,
|
||||
eigvecs1,
|
||||
eigvecs2,
|
||||
masses,
|
||||
band_indices,
|
||||
num_band,
|
||||
cutoff_frequency,
|
||||
openmp_at_bands);
|
||||
reciprocal_to_normal_squared(
|
||||
fc3_normal_squared, g_pos, num_g_pos, fc3_reciprocal, freqs0, freqs1,
|
||||
freqs2, eigvecs0, eigvecs1, eigvecs2, masses, band_indices, num_band,
|
||||
cutoff_frequency, openmp_at_bands);
|
||||
|
||||
free(fc3_reciprocal);
|
||||
fc3_reciprocal = NULL;
|
||||
free(fc3_reciprocal);
|
||||
fc3_reciprocal = NULL;
|
||||
}
|
||||
|
||||
static void real_to_normal_sym_q(double *fc3_normal_squared,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
double *const freqs[3],
|
||||
lapack_complex_double *const eigvecs[3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index,
|
||||
const long num_triplets,
|
||||
const long openmp_at_bands)
|
||||
{
|
||||
long i, j, k, l;
|
||||
long band_ex[3];
|
||||
double q_vecs_ex[3][3];
|
||||
double *fc3_normal_squared_ex;
|
||||
static void real_to_normal_sym_q(
|
||||
double *fc3_normal_squared, const long (*g_pos)[4], const long num_g_pos,
|
||||
double *const freqs[3], lapack_complex_double *const eigvecs[3],
|
||||
const double *fc3, const long is_compact_fc3,
|
||||
const double q_vecs[3][3], /* q0, q1, q2 */
|
||||
const double (*svecs)[3], const long multi_dims[2],
|
||||
const long (*multiplicity)[2], const double *masses, const long *p2s_map,
|
||||
const long *s2p_map, const long *band_indices, const long num_band0,
|
||||
const long num_band, const double cutoff_frequency,
|
||||
const long triplet_index, const long num_triplets,
|
||||
const long openmp_at_bands) {
|
||||
long i, j, k, l;
|
||||
long band_ex[3];
|
||||
double q_vecs_ex[3][3];
|
||||
double *fc3_normal_squared_ex;
|
||||
|
||||
fc3_normal_squared_ex =
|
||||
(double *)malloc(sizeof(double) * num_band * num_band * num_band);
|
||||
fc3_normal_squared_ex =
|
||||
(double *)malloc(sizeof(double) * num_band * num_band * num_band);
|
||||
|
||||
for (i = 0; i < num_band0 * num_band * num_band; i++)
|
||||
{
|
||||
fc3_normal_squared[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
q_vecs_ex[j][k] = q_vecs[index_exchange[i][j]][k];
|
||||
}
|
||||
for (i = 0; i < num_band0 * num_band * num_band; i++) {
|
||||
fc3_normal_squared[i] = 0;
|
||||
}
|
||||
real_to_normal(fc3_normal_squared_ex,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
freqs[index_exchange[i][0]],
|
||||
freqs[index_exchange[i][1]],
|
||||
freqs[index_exchange[i][2]],
|
||||
eigvecs[index_exchange[i][0]],
|
||||
eigvecs[index_exchange[i][1]],
|
||||
eigvecs[index_exchange[i][2]],
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
q_vecs_ex, /* q0, q1, q2 */
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices,
|
||||
num_band,
|
||||
cutoff_frequency,
|
||||
triplet_index,
|
||||
num_triplets,
|
||||
openmp_at_bands);
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
for (k = 0; k < num_band; k++)
|
||||
{
|
||||
for (l = 0; l < num_band; l++)
|
||||
{
|
||||
band_ex[0] = band_indices[j];
|
||||
band_ex[1] = k;
|
||||
band_ex[2] = l;
|
||||
fc3_normal_squared[j * num_band * num_band +
|
||||
k * num_band +
|
||||
l] +=
|
||||
fc3_normal_squared_ex[band_ex[index_exchange[i][0]] *
|
||||
num_band * num_band +
|
||||
band_ex[index_exchange[i][1]] * num_band +
|
||||
band_ex[index_exchange[i][2]]] /
|
||||
6;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
q_vecs_ex[j][k] = q_vecs[index_exchange[i][j]][k];
|
||||
}
|
||||
}
|
||||
real_to_normal(
|
||||
fc3_normal_squared_ex, g_pos, num_g_pos,
|
||||
freqs[index_exchange[i][0]], freqs[index_exchange[i][1]],
|
||||
freqs[index_exchange[i][2]], eigvecs[index_exchange[i][0]],
|
||||
eigvecs[index_exchange[i][1]], eigvecs[index_exchange[i][2]], fc3,
|
||||
is_compact_fc3, q_vecs_ex, /* q0, q1, q2 */
|
||||
svecs, multi_dims, multiplicity, masses, p2s_map, s2p_map,
|
||||
band_indices, num_band, cutoff_frequency, triplet_index,
|
||||
num_triplets, openmp_at_bands);
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
for (k = 0; k < num_band; k++) {
|
||||
for (l = 0; l < num_band; l++) {
|
||||
band_ex[0] = band_indices[j];
|
||||
band_ex[1] = k;
|
||||
band_ex[2] = l;
|
||||
fc3_normal_squared[j * num_band * num_band + k * num_band +
|
||||
l] +=
|
||||
fc3_normal_squared_ex[band_ex[index_exchange[i][0]] *
|
||||
num_band * num_band +
|
||||
band_ex[index_exchange[i][1]] *
|
||||
num_band +
|
||||
band_ex[index_exchange[i][2]]] /
|
||||
6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(fc3_normal_squared_ex);
|
||||
free(fc3_normal_squared_ex);
|
||||
}
|
||||
|
|
|
@ -39,46 +39,28 @@
|
|||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_array.h"
|
||||
|
||||
void itr_get_interaction(Darray *fc3_normal_squared,
|
||||
const char *g_zero,
|
||||
void itr_get_interaction(Darray *fc3_normal_squared, const char *g_zero,
|
||||
const Darray *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const long (*multiplicity)[2], const double *masses,
|
||||
const long *p2s_map, const long *s2p_map,
|
||||
const long *band_indices, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
void itr_get_interaction_at_triplet(double *fc3_normal_squared,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long triplet[3],
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index, /* only for print */
|
||||
const long num_triplets, /* only for print */
|
||||
const long openmp_at_bands);
|
||||
void itr_get_interaction_at_triplet(
|
||||
double *fc3_normal_squared, const long num_band0, const long num_band,
|
||||
const long (*g_pos)[4], const long num_g_pos, const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors, const long triplet[3],
|
||||
const ConstBZGrid *bzgrid, const double *fc3, const long is_compact_fc3,
|
||||
const double (*svecs)[3], const long multi_dims[2],
|
||||
const long (*multiplicity)[2], const double *masses, const long *p2s_map,
|
||||
const long *s2p_map, const long *band_indices, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency,
|
||||
const long triplet_index, /* only for print */
|
||||
const long num_triplets, /* only for print */
|
||||
const long openmp_at_bands);
|
||||
|
||||
#endif
|
||||
|
|
342
c/isotope.c
342
c/isotope.c
|
@ -32,224 +32,196 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "isotope.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_const.h"
|
||||
#include "phonoc_utils.h"
|
||||
#include "isotope.h"
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
void iso_get_isotope_scattering_strength(double *gamma,
|
||||
const long grid_point,
|
||||
const double *mass_variances,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const long num_band0,
|
||||
const double sigma,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j, k, l, m;
|
||||
double *e0_r, *e0_i, e1_r, e1_i, a, b, f, *f0, dist, sum_g, sum_g_k;
|
||||
void iso_get_isotope_scattering_strength(
|
||||
double *gamma, const long grid_point, const double *mass_variances,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points, const long *band_indices, const long num_band,
|
||||
const long num_band0, const double sigma, const double cutoff_frequency) {
|
||||
long i, j, k, l, m;
|
||||
double *e0_r, *e0_i, e1_r, e1_i, a, b, f, *f0, dist, sum_g, sum_g_k;
|
||||
|
||||
e0_r = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
e0_i = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
f0 = (double *)malloc(sizeof(double) * num_band0);
|
||||
e0_r = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
e0_i = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
f0 = (double *)malloc(sizeof(double) * num_band0);
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
f0[i] = frequencies[grid_point * num_band + band_indices[i]];
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
e0_r[i * num_band + j] = lapack_complex_double_real(eigenvectors[grid_point * num_band * num_band +
|
||||
j * num_band + band_indices[i]]);
|
||||
e0_i[i * num_band + j] = lapack_complex_double_imag(eigenvectors[grid_point * num_band * num_band +
|
||||
j * num_band + band_indices[i]]);
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
f0[i] = frequencies[grid_point * num_band + band_indices[i]];
|
||||
for (j = 0; j < num_band; j++) {
|
||||
e0_r[i * num_band + j] = lapack_complex_double_real(
|
||||
eigenvectors[grid_point * num_band * num_band + j * num_band +
|
||||
band_indices[i]]);
|
||||
e0_i[i * num_band + j] = lapack_complex_double_imag(
|
||||
eigenvectors[grid_point * num_band * num_band + j * num_band +
|
||||
band_indices[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
gamma[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{ /* band index0 */
|
||||
if (f0[i] < cutoff_frequency)
|
||||
{
|
||||
continue;
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
gamma[i] = 0;
|
||||
}
|
||||
sum_g = 0;
|
||||
|
||||
for (i = 0; i < num_band0; i++) { /* band index0 */
|
||||
if (f0[i] < cutoff_frequency) {
|
||||
continue;
|
||||
}
|
||||
sum_g = 0;
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(k, l, m, f, e1_r, e1_i, a, b, dist, sum_g_k) reduction(+ \
|
||||
: sum_g)
|
||||
#endif
|
||||
for (j = 0; j < num_grid_points; j++)
|
||||
{
|
||||
sum_g_k = 0;
|
||||
for (k = 0; k < num_band; k++)
|
||||
{ /* band index */
|
||||
f = frequencies[j * num_band + k];
|
||||
if (f < cutoff_frequency)
|
||||
{
|
||||
continue;
|
||||
for (j = 0; j < num_grid_points; j++) {
|
||||
sum_g_k = 0;
|
||||
for (k = 0; k < num_band; k++) { /* band index */
|
||||
f = frequencies[j * num_band + k];
|
||||
if (f < cutoff_frequency) {
|
||||
continue;
|
||||
}
|
||||
dist = phonoc_gaussian(f - f0[i], sigma);
|
||||
for (l = 0; l < num_band / 3; l++) { /* elements */
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (m = 0; m < 3; m++) {
|
||||
e1_r = lapack_complex_double_real(
|
||||
eigenvectors[j * num_band * num_band +
|
||||
(l * 3 + m) * num_band + k]);
|
||||
e1_i = lapack_complex_double_imag(
|
||||
eigenvectors[j * num_band * num_band +
|
||||
(l * 3 + m) * num_band + k]);
|
||||
a += (e0_r[i * num_band + l * 3 + m] * e1_r +
|
||||
e0_i[i * num_band + l * 3 + m] * e1_i);
|
||||
b += (e0_i[i * num_band + l * 3 + m] * e1_r -
|
||||
e0_r[i * num_band + l * 3 + m] * e1_i);
|
||||
}
|
||||
sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
|
||||
}
|
||||
}
|
||||
sum_g += sum_g_k;
|
||||
}
|
||||
dist = phonoc_gaussian(f - f0[i], sigma);
|
||||
for (l = 0; l < num_band / 3; l++)
|
||||
{ /* elements */
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (m = 0; m < 3; m++)
|
||||
{
|
||||
e1_r = lapack_complex_double_real(eigenvectors[j * num_band * num_band +
|
||||
(l * 3 + m) * num_band + k]);
|
||||
e1_i = lapack_complex_double_imag(eigenvectors[j * num_band * num_band +
|
||||
(l * 3 + m) * num_band + k]);
|
||||
a += (e0_r[i * num_band + l * 3 + m] * e1_r +
|
||||
e0_i[i * num_band + l * 3 + m] * e1_i);
|
||||
b += (e0_i[i * num_band + l * 3 + m] * e1_r -
|
||||
e0_r[i * num_band + l * 3 + m] * e1_i);
|
||||
}
|
||||
sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
|
||||
}
|
||||
}
|
||||
sum_g += sum_g_k;
|
||||
gamma[i] = sum_g;
|
||||
}
|
||||
gamma[i] = sum_g;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
/* Frequency unit to ang-freq: *(2pi)**2/(2pi) */
|
||||
/* Ang-freq to freq unit (for lifetime): /2pi */
|
||||
/* gamma = 1/2t */
|
||||
gamma[i] *= M_2PI / 4 * f0[i] * f0[i] / 2;
|
||||
}
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
/* Frequency unit to ang-freq: *(2pi)**2/(2pi) */
|
||||
/* Ang-freq to freq unit (for lifetime): /2pi */
|
||||
/* gamma = 1/2t */
|
||||
gamma[i] *= M_2PI / 4 * f0[i] * f0[i] / 2;
|
||||
}
|
||||
|
||||
free(f0);
|
||||
f0 = NULL;
|
||||
free(e0_r);
|
||||
e0_r = NULL;
|
||||
free(e0_i);
|
||||
e0_i = NULL;
|
||||
free(f0);
|
||||
f0 = NULL;
|
||||
free(e0_r);
|
||||
e0_r = NULL;
|
||||
free(e0_i);
|
||||
e0_i = NULL;
|
||||
}
|
||||
|
||||
void iso_get_thm_isotope_scattering_strength(double *gamma,
|
||||
const long grid_point,
|
||||
const long *ir_grid_points,
|
||||
const long *weights,
|
||||
const double *mass_variances,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const long num_band0,
|
||||
const double *integration_weights,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j, k, l, m, gp;
|
||||
double *e0_r, *e0_i, *f0, *gamma_ij;
|
||||
double e1_r, e1_i, a, b, f, dist, sum_g_k;
|
||||
void iso_get_thm_isotope_scattering_strength(
|
||||
double *gamma, const long grid_point, const long *ir_grid_points,
|
||||
const long *weights, const double *mass_variances,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points, const long *band_indices, const long num_band,
|
||||
const long num_band0, const double *integration_weights,
|
||||
const double cutoff_frequency) {
|
||||
long i, j, k, l, m, gp;
|
||||
double *e0_r, *e0_i, *f0, *gamma_ij;
|
||||
double e1_r, e1_i, a, b, f, dist, sum_g_k;
|
||||
|
||||
e0_r = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
e0_i = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
f0 = (double *)malloc(sizeof(double) * num_band0);
|
||||
e0_r = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
e0_i = (double *)malloc(sizeof(double) * num_band * num_band0);
|
||||
f0 = (double *)malloc(sizeof(double) * num_band0);
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
f0[i] = frequencies[grid_point * num_band + band_indices[i]];
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
e0_r[i * num_band + j] = lapack_complex_double_real(eigenvectors[grid_point * num_band * num_band +
|
||||
j * num_band + band_indices[i]]);
|
||||
e0_i[i * num_band + j] = lapack_complex_double_imag(eigenvectors[grid_point * num_band * num_band +
|
||||
j * num_band + band_indices[i]]);
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
f0[i] = frequencies[grid_point * num_band + band_indices[i]];
|
||||
for (j = 0; j < num_band; j++) {
|
||||
e0_r[i * num_band + j] = lapack_complex_double_real(
|
||||
eigenvectors[grid_point * num_band * num_band + j * num_band +
|
||||
band_indices[i]]);
|
||||
e0_i[i * num_band + j] = lapack_complex_double_imag(
|
||||
eigenvectors[grid_point * num_band * num_band + j * num_band +
|
||||
band_indices[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gamma_ij = (double *)malloc(sizeof(double) * num_grid_points * num_band0);
|
||||
gamma_ij = (double *)malloc(sizeof(double) * num_grid_points * num_band0);
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (i = 0; i < num_grid_points * num_band0; i++)
|
||||
{
|
||||
gamma_ij[i] = 0;
|
||||
}
|
||||
for (i = 0; i < num_grid_points * num_band0; i++) {
|
||||
gamma_ij[i] = 0;
|
||||
}
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, k, l, m, f, gp, e1_r, e1_i, a, b, dist, sum_g_k)
|
||||
#pragma omp parallel for private(j, k, l, m, f, gp, e1_r, e1_i, a, b, dist, \
|
||||
sum_g_k)
|
||||
#endif
|
||||
for (i = 0; i < num_grid_points; i++)
|
||||
{
|
||||
gp = ir_grid_points[i];
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{ /* band index0 */
|
||||
if (f0[j] < cutoff_frequency)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
sum_g_k = 0;
|
||||
for (k = 0; k < num_band; k++)
|
||||
{ /* band index */
|
||||
f = frequencies[gp * num_band + k];
|
||||
if (f < cutoff_frequency)
|
||||
{
|
||||
continue;
|
||||
for (i = 0; i < num_grid_points; i++) {
|
||||
gp = ir_grid_points[i];
|
||||
for (j = 0; j < num_band0; j++) { /* band index0 */
|
||||
if (f0[j] < cutoff_frequency) {
|
||||
continue;
|
||||
}
|
||||
sum_g_k = 0;
|
||||
for (k = 0; k < num_band; k++) { /* band index */
|
||||
f = frequencies[gp * num_band + k];
|
||||
if (f < cutoff_frequency) {
|
||||
continue;
|
||||
}
|
||||
dist = integration_weights[gp * num_band0 * num_band +
|
||||
j * num_band + k];
|
||||
for (l = 0; l < num_band / 3; l++) { /* elements */
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (m = 0; m < 3; m++) {
|
||||
e1_r = lapack_complex_double_real(
|
||||
eigenvectors[gp * num_band * num_band +
|
||||
(l * 3 + m) * num_band + k]);
|
||||
e1_i = lapack_complex_double_imag(
|
||||
eigenvectors[gp * num_band * num_band +
|
||||
(l * 3 + m) * num_band + k]);
|
||||
a += (e0_r[j * num_band + l * 3 + m] * e1_r +
|
||||
e0_i[j * num_band + l * 3 + m] * e1_i);
|
||||
b += (e0_i[j * num_band + l * 3 + m] * e1_r -
|
||||
e0_r[j * num_band + l * 3 + m] * e1_i);
|
||||
}
|
||||
sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
|
||||
}
|
||||
}
|
||||
gamma_ij[gp * num_band0 + j] = sum_g_k * weights[gp];
|
||||
}
|
||||
dist = integration_weights[gp * num_band0 * num_band +
|
||||
j * num_band + k];
|
||||
for (l = 0; l < num_band / 3; l++)
|
||||
{ /* elements */
|
||||
a = 0;
|
||||
b = 0;
|
||||
for (m = 0; m < 3; m++)
|
||||
{
|
||||
e1_r = lapack_complex_double_real(eigenvectors
|
||||
[gp * num_band * num_band + (l * 3 + m) * num_band + k]);
|
||||
e1_i = lapack_complex_double_imag(eigenvectors
|
||||
[gp * num_band * num_band + (l * 3 + m) * num_band + k]);
|
||||
a += (e0_r[j * num_band + l * 3 + m] * e1_r +
|
||||
e0_i[j * num_band + l * 3 + m] * e1_i);
|
||||
b += (e0_i[j * num_band + l * 3 + m] * e1_r -
|
||||
e0_r[j * num_band + l * 3 + m] * e1_i);
|
||||
}
|
||||
sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
gamma[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_grid_points; i++) {
|
||||
gp = ir_grid_points[i];
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
gamma[j] += gamma_ij[gp * num_band0 + j];
|
||||
}
|
||||
}
|
||||
gamma_ij[gp * num_band0 + j] = sum_g_k * weights[gp];
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
gamma[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_grid_points; i++)
|
||||
{
|
||||
gp = ir_grid_points[i];
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
gamma[j] += gamma_ij[gp * num_band0 + j];
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
/* Frequency unit to ang-freq: *(2pi)**2/(2pi) */
|
||||
/* Ang-freq to freq unit (for lifetime): /2pi */
|
||||
/* gamma = 1/2t */
|
||||
gamma[i] *= M_2PI / 4 * f0[i] * f0[i] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
/* Frequency unit to ang-freq: *(2pi)**2/(2pi) */
|
||||
/* Ang-freq to freq unit (for lifetime): /2pi */
|
||||
/* gamma = 1/2t */
|
||||
gamma[i] *= M_2PI / 4 * f0[i] * f0[i] / 2;
|
||||
}
|
||||
|
||||
free(gamma_ij);
|
||||
gamma_ij = NULL;
|
||||
free(f0);
|
||||
f0 = NULL;
|
||||
free(e0_r);
|
||||
e0_r = NULL;
|
||||
free(e0_i);
|
||||
e0_i = NULL;
|
||||
free(gamma_ij);
|
||||
gamma_ij = NULL;
|
||||
free(f0);
|
||||
f0 = NULL;
|
||||
free(e0_r);
|
||||
e0_r = NULL;
|
||||
free(e0_i);
|
||||
e0_i = NULL;
|
||||
}
|
||||
|
|
36
c/isotope.h
36
c/isotope.h
|
@ -37,28 +37,16 @@
|
|||
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
void iso_get_isotope_scattering_strength(double *gamma,
|
||||
const long grid_point,
|
||||
const double *mass_variances,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const long num_band0,
|
||||
const double sigma,
|
||||
const double cutoff_frequency);
|
||||
void iso_get_thm_isotope_scattering_strength(double *gamma,
|
||||
const long grid_point,
|
||||
const long *ir_grid_points,
|
||||
const long *weights,
|
||||
const double *mass_variances,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const long num_band0,
|
||||
const double *integration_weights,
|
||||
const double cutoff_frequency);
|
||||
void iso_get_isotope_scattering_strength(
|
||||
double *gamma, const long grid_point, const double *mass_variances,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points, const long *band_indices, const long num_band,
|
||||
const long num_band0, const double sigma, const double cutoff_frequency);
|
||||
void iso_get_thm_isotope_scattering_strength(
|
||||
double *gamma, const long grid_point, const long *ir_grid_points,
|
||||
const long *weights, const double *mass_variances,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points, const long *band_indices, const long num_band,
|
||||
const long num_band0, const double *integration_weights,
|
||||
const double cutoff_frequency);
|
||||
#endif
|
||||
|
|
405
c/lagrid.c
405
c/lagrid.c
|
@ -34,265 +34,216 @@
|
|||
|
||||
#include "lagrid.h"
|
||||
|
||||
long lagmat_get_determinant_l3(const long a[3][3])
|
||||
{
|
||||
return a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) + a[0][1] * (a[1][2] * a[2][0] - a[1][0] * a[2][2]) + a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]);
|
||||
long lagmat_get_determinant_l3(const long a[3][3]) {
|
||||
return a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) +
|
||||
a[0][1] * (a[1][2] * a[2][0] - a[1][0] * a[2][2]) +
|
||||
a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]);
|
||||
}
|
||||
|
||||
double lagmat_get_determinant_d3(const double a[3][3])
|
||||
{
|
||||
return a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) + a[0][1] * (a[1][2] * a[2][0] - a[1][0] * a[2][2]) + a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]);
|
||||
double lagmat_get_determinant_d3(const double a[3][3]) {
|
||||
return a[0][0] * (a[1][1] * a[2][2] - a[1][2] * a[2][1]) +
|
||||
a[0][1] * (a[1][2] * a[2][0] - a[1][0] * a[2][2]) +
|
||||
a[0][2] * (a[1][0] * a[2][1] - a[1][1] * a[2][0]);
|
||||
}
|
||||
|
||||
void lagmat_cast_matrix_3l_to_3d(double m[3][3], const long a[3][3])
|
||||
{
|
||||
m[0][0] = a[0][0];
|
||||
m[0][1] = a[0][1];
|
||||
m[0][2] = a[0][2];
|
||||
m[1][0] = a[1][0];
|
||||
m[1][1] = a[1][1];
|
||||
m[1][2] = a[1][2];
|
||||
m[2][0] = a[2][0];
|
||||
m[2][1] = a[2][1];
|
||||
m[2][2] = a[2][2];
|
||||
void lagmat_cast_matrix_3l_to_3d(double m[3][3], const long a[3][3]) {
|
||||
m[0][0] = a[0][0];
|
||||
m[0][1] = a[0][1];
|
||||
m[0][2] = a[0][2];
|
||||
m[1][0] = a[1][0];
|
||||
m[1][1] = a[1][1];
|
||||
m[1][2] = a[1][2];
|
||||
m[2][0] = a[2][0];
|
||||
m[2][1] = a[2][1];
|
||||
m[2][2] = a[2][2];
|
||||
}
|
||||
|
||||
void lagmat_cast_matrix_3d_to_3l(long m[3][3], const double a[3][3])
|
||||
{
|
||||
m[0][0] = lagmat_Nint(a[0][0]);
|
||||
m[0][1] = lagmat_Nint(a[0][1]);
|
||||
m[0][2] = lagmat_Nint(a[0][2]);
|
||||
m[1][0] = lagmat_Nint(a[1][0]);
|
||||
m[1][1] = lagmat_Nint(a[1][1]);
|
||||
m[1][2] = lagmat_Nint(a[1][2]);
|
||||
m[2][0] = lagmat_Nint(a[2][0]);
|
||||
m[2][1] = lagmat_Nint(a[2][1]);
|
||||
m[2][2] = lagmat_Nint(a[2][2]);
|
||||
void lagmat_cast_matrix_3d_to_3l(long m[3][3], const double a[3][3]) {
|
||||
m[0][0] = lagmat_Nint(a[0][0]);
|
||||
m[0][1] = lagmat_Nint(a[0][1]);
|
||||
m[0][2] = lagmat_Nint(a[0][2]);
|
||||
m[1][0] = lagmat_Nint(a[1][0]);
|
||||
m[1][1] = lagmat_Nint(a[1][1]);
|
||||
m[1][2] = lagmat_Nint(a[1][2]);
|
||||
m[2][0] = lagmat_Nint(a[2][0]);
|
||||
m[2][1] = lagmat_Nint(a[2][1]);
|
||||
m[2][2] = lagmat_Nint(a[2][2]);
|
||||
}
|
||||
|
||||
long lagmat_get_similar_matrix_ld3(double m[3][3],
|
||||
const long a[3][3],
|
||||
long lagmat_get_similar_matrix_ld3(double m[3][3], const long a[3][3],
|
||||
const double b[3][3],
|
||||
const double precision)
|
||||
{
|
||||
double c[3][3];
|
||||
if (!lagmat_inverse_matrix_d3(c, b, precision))
|
||||
{
|
||||
warning_print("No similar matrix due to 0 determinant.\n");
|
||||
return 0;
|
||||
}
|
||||
lagmat_multiply_matrix_ld3(m, a, b);
|
||||
lagmat_multiply_matrix_d3(m, c, m);
|
||||
return 1;
|
||||
}
|
||||
|
||||
long lagmat_check_identity_matrix_l3(const long a[3][3],
|
||||
const long b[3][3])
|
||||
{
|
||||
if (a[0][0] - b[0][0] ||
|
||||
a[0][1] - b[0][1] ||
|
||||
a[0][2] - b[0][2] ||
|
||||
a[1][0] - b[1][0] ||
|
||||
a[1][1] - b[1][1] ||
|
||||
a[1][2] - b[1][2] ||
|
||||
a[2][0] - b[2][0] ||
|
||||
a[2][1] - b[2][1] ||
|
||||
a[2][2] - b[2][2])
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
const double precision) {
|
||||
double c[3][3];
|
||||
if (!lagmat_inverse_matrix_d3(c, b, precision)) {
|
||||
warning_print("No similar matrix due to 0 determinant.\n");
|
||||
return 0;
|
||||
}
|
||||
lagmat_multiply_matrix_ld3(m, a, b);
|
||||
lagmat_multiply_matrix_d3(m, c, m);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
long lagmat_check_identity_matrix_ld3(const long a[3][3],
|
||||
const double b[3][3],
|
||||
const double symprec)
|
||||
{
|
||||
if (lagmat_Dabs(a[0][0] - b[0][0]) > symprec ||
|
||||
lagmat_Dabs(a[0][1] - b[0][1]) > symprec ||
|
||||
lagmat_Dabs(a[0][2] - b[0][2]) > symprec ||
|
||||
lagmat_Dabs(a[1][0] - b[1][0]) > symprec ||
|
||||
lagmat_Dabs(a[1][1] - b[1][1]) > symprec ||
|
||||
lagmat_Dabs(a[1][2] - b[1][2]) > symprec ||
|
||||
lagmat_Dabs(a[2][0] - b[2][0]) > symprec ||
|
||||
lagmat_Dabs(a[2][1] - b[2][1]) > symprec ||
|
||||
lagmat_Dabs(a[2][2] - b[2][2]) > symprec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
long lagmat_check_identity_matrix_l3(const long a[3][3], const long b[3][3]) {
|
||||
if (a[0][0] - b[0][0] || a[0][1] - b[0][1] || a[0][2] - b[0][2] ||
|
||||
a[1][0] - b[1][0] || a[1][1] - b[1][1] || a[1][2] - b[1][2] ||
|
||||
a[2][0] - b[2][0] || a[2][1] - b[2][1] || a[2][2] - b[2][2]) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
long lagmat_check_identity_matrix_ld3(const long a[3][3], const double b[3][3],
|
||||
const double symprec) {
|
||||
if (lagmat_Dabs(a[0][0] - b[0][0]) > symprec ||
|
||||
lagmat_Dabs(a[0][1] - b[0][1]) > symprec ||
|
||||
lagmat_Dabs(a[0][2] - b[0][2]) > symprec ||
|
||||
lagmat_Dabs(a[1][0] - b[1][0]) > symprec ||
|
||||
lagmat_Dabs(a[1][1] - b[1][1]) > symprec ||
|
||||
lagmat_Dabs(a[1][2] - b[1][2]) > symprec ||
|
||||
lagmat_Dabs(a[2][0] - b[2][0]) > symprec ||
|
||||
lagmat_Dabs(a[2][1] - b[2][1]) > symprec ||
|
||||
lagmat_Dabs(a[2][2] - b[2][2]) > symprec) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
long lagmat_inverse_matrix_d3(double m[3][3], const double a[3][3],
|
||||
const double precision) {
|
||||
double det;
|
||||
double c[3][3];
|
||||
det = lagmat_get_determinant_d3(a);
|
||||
if (lagmat_Dabs(det) < precision) {
|
||||
warning_print("No inverse matrix (det=%f)\n", det);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det;
|
||||
c[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det;
|
||||
c[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det;
|
||||
c[0][1] = (a[2][1] * a[0][2] - a[2][2] * a[0][1]) / det;
|
||||
c[1][1] = (a[2][2] * a[0][0] - a[2][0] * a[0][2]) / det;
|
||||
c[2][1] = (a[2][0] * a[0][1] - a[2][1] * a[0][0]) / det;
|
||||
c[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det;
|
||||
c[1][2] = (a[0][2] * a[1][0] - a[0][0] * a[1][2]) / det;
|
||||
c[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det;
|
||||
lagmat_copy_matrix_d3(m, c);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
long lagmat_inverse_matrix_d3(double m[3][3],
|
||||
const double a[3][3],
|
||||
const double precision)
|
||||
{
|
||||
double det;
|
||||
double c[3][3];
|
||||
det = lagmat_get_determinant_d3(a);
|
||||
if (lagmat_Dabs(det) < precision)
|
||||
{
|
||||
warning_print("No inverse matrix (det=%f)\n", det);
|
||||
return 0;
|
||||
}
|
||||
|
||||
c[0][0] = (a[1][1] * a[2][2] - a[1][2] * a[2][1]) / det;
|
||||
c[1][0] = (a[1][2] * a[2][0] - a[1][0] * a[2][2]) / det;
|
||||
c[2][0] = (a[1][0] * a[2][1] - a[1][1] * a[2][0]) / det;
|
||||
c[0][1] = (a[2][1] * a[0][2] - a[2][2] * a[0][1]) / det;
|
||||
c[1][1] = (a[2][2] * a[0][0] - a[2][0] * a[0][2]) / det;
|
||||
c[2][1] = (a[2][0] * a[0][1] - a[2][1] * a[0][0]) / det;
|
||||
c[0][2] = (a[0][1] * a[1][2] - a[0][2] * a[1][1]) / det;
|
||||
c[1][2] = (a[0][2] * a[1][0] - a[0][0] * a[1][2]) / det;
|
||||
c[2][2] = (a[0][0] * a[1][1] - a[0][1] * a[1][0]) / det;
|
||||
lagmat_copy_matrix_d3(m, c);
|
||||
return 1;
|
||||
void lagmat_transpose_matrix_l3(long a[3][3], const long b[3][3]) {
|
||||
long c[3][3];
|
||||
c[0][0] = b[0][0];
|
||||
c[0][1] = b[1][0];
|
||||
c[0][2] = b[2][0];
|
||||
c[1][0] = b[0][1];
|
||||
c[1][1] = b[1][1];
|
||||
c[1][2] = b[2][1];
|
||||
c[2][0] = b[0][2];
|
||||
c[2][1] = b[1][2];
|
||||
c[2][2] = b[2][2];
|
||||
lagmat_copy_matrix_l3(a, c);
|
||||
}
|
||||
|
||||
void lagmat_transpose_matrix_l3(long a[3][3], const long b[3][3])
|
||||
{
|
||||
long c[3][3];
|
||||
c[0][0] = b[0][0];
|
||||
c[0][1] = b[1][0];
|
||||
c[0][2] = b[2][0];
|
||||
c[1][0] = b[0][1];
|
||||
c[1][1] = b[1][1];
|
||||
c[1][2] = b[2][1];
|
||||
c[2][0] = b[0][2];
|
||||
c[2][1] = b[1][2];
|
||||
c[2][2] = b[2][2];
|
||||
lagmat_copy_matrix_l3(a, c);
|
||||
}
|
||||
|
||||
void lagmat_multiply_matrix_vector_l3(long v[3],
|
||||
const long a[3][3],
|
||||
const long b[3])
|
||||
{
|
||||
long i;
|
||||
long c[3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
|
||||
}
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
v[i] = c[i];
|
||||
}
|
||||
}
|
||||
|
||||
void lagmat_multiply_matrix_l3(long m[3][3],
|
||||
const long a[3][3],
|
||||
const long b[3][3])
|
||||
{
|
||||
long i, j; /* a_ij */
|
||||
long c[3][3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
c[i][j] =
|
||||
a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
void lagmat_multiply_matrix_vector_l3(long v[3], const long a[3][3],
|
||||
const long b[3]) {
|
||||
long i;
|
||||
long c[3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
c[i] = a[i][0] * b[0] + a[i][1] * b[1] + a[i][2] * b[2];
|
||||
}
|
||||
}
|
||||
lagmat_copy_matrix_l3(m, c);
|
||||
}
|
||||
|
||||
void lagmat_multiply_matrix_ld3(double m[3][3],
|
||||
const long a[3][3],
|
||||
const double b[3][3])
|
||||
{
|
||||
long i, j; /* a_ij */
|
||||
double c[3][3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
c[i][j] =
|
||||
a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
for (i = 0; i < 3; i++) {
|
||||
v[i] = c[i];
|
||||
}
|
||||
}
|
||||
lagmat_copy_matrix_d3(m, c);
|
||||
}
|
||||
|
||||
void lagmat_multiply_matrix_d3(double m[3][3],
|
||||
const double a[3][3],
|
||||
const double b[3][3])
|
||||
{
|
||||
long i, j; /* a_ij */
|
||||
double c[3][3];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
c[i][j] =
|
||||
a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
void lagmat_multiply_matrix_l3(long m[3][3], const long a[3][3],
|
||||
const long b[3][3]) {
|
||||
long i, j; /* a_ij */
|
||||
long c[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
lagmat_copy_matrix_d3(m, c);
|
||||
lagmat_copy_matrix_l3(m, c);
|
||||
}
|
||||
|
||||
void lagmat_copy_matrix_l3(long a[3][3], const long b[3][3])
|
||||
{
|
||||
a[0][0] = b[0][0];
|
||||
a[0][1] = b[0][1];
|
||||
a[0][2] = b[0][2];
|
||||
a[1][0] = b[1][0];
|
||||
a[1][1] = b[1][1];
|
||||
a[1][2] = b[1][2];
|
||||
a[2][0] = b[2][0];
|
||||
a[2][1] = b[2][1];
|
||||
a[2][2] = b[2][2];
|
||||
void lagmat_multiply_matrix_ld3(double m[3][3], const long a[3][3],
|
||||
const double b[3][3]) {
|
||||
long i, j; /* a_ij */
|
||||
double c[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
}
|
||||
}
|
||||
lagmat_copy_matrix_d3(m, c);
|
||||
}
|
||||
|
||||
void lagmat_copy_matrix_d3(double a[3][3], const double b[3][3])
|
||||
{
|
||||
a[0][0] = b[0][0];
|
||||
a[0][1] = b[0][1];
|
||||
a[0][2] = b[0][2];
|
||||
a[1][0] = b[1][0];
|
||||
a[1][1] = b[1][1];
|
||||
a[1][2] = b[1][2];
|
||||
a[2][0] = b[2][0];
|
||||
a[2][1] = b[2][1];
|
||||
a[2][2] = b[2][2];
|
||||
void lagmat_multiply_matrix_d3(double m[3][3], const double a[3][3],
|
||||
const double b[3][3]) {
|
||||
long i, j; /* a_ij */
|
||||
double c[3][3];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
}
|
||||
}
|
||||
lagmat_copy_matrix_d3(m, c);
|
||||
}
|
||||
|
||||
void lagmat_copy_vector_l3(long a[3], const long b[3])
|
||||
{
|
||||
a[0] = b[0];
|
||||
a[1] = b[1];
|
||||
a[2] = b[2];
|
||||
void lagmat_copy_matrix_l3(long a[3][3], const long b[3][3]) {
|
||||
a[0][0] = b[0][0];
|
||||
a[0][1] = b[0][1];
|
||||
a[0][2] = b[0][2];
|
||||
a[1][0] = b[1][0];
|
||||
a[1][1] = b[1][1];
|
||||
a[1][2] = b[1][2];
|
||||
a[2][0] = b[2][0];
|
||||
a[2][1] = b[2][1];
|
||||
a[2][2] = b[2][2];
|
||||
}
|
||||
|
||||
long lagmat_modulo_l(const long a, const long b)
|
||||
{
|
||||
long c;
|
||||
c = a % b;
|
||||
if (c < 0)
|
||||
{
|
||||
c += b;
|
||||
}
|
||||
return c;
|
||||
void lagmat_copy_matrix_d3(double a[3][3], const double b[3][3]) {
|
||||
a[0][0] = b[0][0];
|
||||
a[0][1] = b[0][1];
|
||||
a[0][2] = b[0][2];
|
||||
a[1][0] = b[1][0];
|
||||
a[1][1] = b[1][1];
|
||||
a[1][2] = b[1][2];
|
||||
a[2][0] = b[2][0];
|
||||
a[2][1] = b[2][1];
|
||||
a[2][2] = b[2][2];
|
||||
}
|
||||
|
||||
long lagmat_Nint(const double a)
|
||||
{
|
||||
if (a < 0.0)
|
||||
return (long)(a - 0.5);
|
||||
else
|
||||
return (long)(a + 0.5);
|
||||
void lagmat_copy_vector_l3(long a[3], const long b[3]) {
|
||||
a[0] = b[0];
|
||||
a[1] = b[1];
|
||||
a[2] = b[2];
|
||||
}
|
||||
|
||||
double lagmat_Dabs(const double a)
|
||||
{
|
||||
if (a < 0.0)
|
||||
return -a;
|
||||
else
|
||||
return a;
|
||||
long lagmat_modulo_l(const long a, const long b) {
|
||||
long c;
|
||||
c = a % b;
|
||||
if (c < 0) {
|
||||
c += b;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
long lagmat_Nint(const double a) {
|
||||
if (a < 0.0)
|
||||
return (long)(a - 0.5);
|
||||
else
|
||||
return (long)(a + 0.5);
|
||||
}
|
||||
|
||||
double lagmat_Dabs(const double a) {
|
||||
if (a < 0.0)
|
||||
return -a;
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
|
26
c/lagrid.h
26
c/lagrid.h
|
@ -36,7 +36,7 @@
|
|||
#define __lagrid_H__
|
||||
|
||||
#ifdef LAGWARNING
|
||||
#define warning_print(...) fprintf(stderr,__VA_ARGS__)
|
||||
#define warning_print(...) fprintf(stderr, __VA_ARGS__)
|
||||
#else
|
||||
#define warning_print(...)
|
||||
#endif
|
||||
|
@ -45,30 +45,22 @@ long lagmat_get_determinant_l3(const long a[3][3]);
|
|||
double lagmat_get_determinant_d3(const double a[3][3]);
|
||||
void lagmat_cast_matrix_3l_to_3d(double m[3][3], const long a[3][3]);
|
||||
void lagmat_cast_matrix_3d_to_3l(long m[3][3], const double a[3][3]);
|
||||
long lagmat_get_similar_matrix_ld3(double m[3][3],
|
||||
const long a[3][3],
|
||||
long lagmat_get_similar_matrix_ld3(double m[3][3], const long a[3][3],
|
||||
const double b[3][3],
|
||||
const double precision);
|
||||
long lagmat_check_identity_matrix_l3(const long a[3][3],
|
||||
const long b[3][3]);
|
||||
long lagmat_check_identity_matrix_ld3(const long a[3][3],
|
||||
const double b[3][3],
|
||||
long lagmat_check_identity_matrix_l3(const long a[3][3], const long b[3][3]);
|
||||
long lagmat_check_identity_matrix_ld3(const long a[3][3], const double b[3][3],
|
||||
const double symprec);
|
||||
long lagmat_inverse_matrix_d3(double m[3][3],
|
||||
const double a[3][3],
|
||||
long lagmat_inverse_matrix_d3(double m[3][3], const double a[3][3],
|
||||
const double precision);
|
||||
void lagmat_transpose_matrix_l3(long a[3][3], const long b[3][3]);
|
||||
void lagmat_multiply_matrix_vector_l3(long v[3],
|
||||
const long a[3][3],
|
||||
void lagmat_multiply_matrix_vector_l3(long v[3], const long a[3][3],
|
||||
const long b[3]);
|
||||
void lagmat_multiply_matrix_l3(long m[3][3],
|
||||
const long a[3][3],
|
||||
void lagmat_multiply_matrix_l3(long m[3][3], const long a[3][3],
|
||||
const long b[3][3]);
|
||||
void lagmat_multiply_matrix_ld3(double m[3][3],
|
||||
const long a[3][3],
|
||||
void lagmat_multiply_matrix_ld3(double m[3][3], const long a[3][3],
|
||||
const double b[3][3]);
|
||||
void lagmat_multiply_matrix_d3(double m[3][3],
|
||||
const double a[3][3],
|
||||
void lagmat_multiply_matrix_d3(double m[3][3], const double a[3][3],
|
||||
const double b[3][3]);
|
||||
void lagmat_copy_matrix_l3(long a[3][3], const long b[3][3]);
|
||||
void lagmat_copy_matrix_d3(double a[3][3], const double b[3][3]);
|
||||
|
|
|
@ -37,12 +37,11 @@
|
|||
#define min(a, b) ((a) > (b) ? (b) : (a))
|
||||
|
||||
#ifdef MKL_LAPACKE
|
||||
MKL_Complex16 lapack_make_complex_double(double re, double im)
|
||||
{
|
||||
MKL_Complex16 z;
|
||||
z.real = re;
|
||||
z.imag = im;
|
||||
return z;
|
||||
MKL_Complex16 lapack_make_complex_double(double re, double im) {
|
||||
MKL_Complex16 z;
|
||||
z.real = re;
|
||||
z.imag = im;
|
||||
return z;
|
||||
}
|
||||
#ifndef LAPACKE_malloc
|
||||
#define LAPACKE_malloc(size) malloc(size)
|
||||
|
@ -52,204 +51,146 @@ MKL_Complex16 lapack_make_complex_double(double re, double im)
|
|||
#endif
|
||||
#endif
|
||||
|
||||
int phonopy_zheev(double *w,
|
||||
lapack_complex_double *a,
|
||||
const int n,
|
||||
const char uplo)
|
||||
{
|
||||
lapack_int info;
|
||||
info = LAPACKE_zheev(LAPACK_ROW_MAJOR, 'V', uplo,
|
||||
(lapack_int)n, a, (lapack_int)n, w);
|
||||
return (int)info;
|
||||
int phonopy_zheev(double *w, lapack_complex_double *a, const int n,
|
||||
const char uplo) {
|
||||
lapack_int info;
|
||||
info = LAPACKE_zheev(LAPACK_ROW_MAJOR, 'V', uplo, (lapack_int)n, a,
|
||||
(lapack_int)n, w);
|
||||
return (int)info;
|
||||
}
|
||||
|
||||
int phonopy_pinv(double *data_out,
|
||||
const double *data_in,
|
||||
const int m,
|
||||
const int n,
|
||||
const double cutoff)
|
||||
{
|
||||
int i, j, k;
|
||||
lapack_int info;
|
||||
double *s, *a, *u, *vt, *superb;
|
||||
int phonopy_pinv(double *data_out, const double *data_in, const int m,
|
||||
const int n, const double cutoff) {
|
||||
int i, j, k;
|
||||
lapack_int info;
|
||||
double *s, *a, *u, *vt, *superb;
|
||||
|
||||
a = (double *)malloc(sizeof(double) * m * n);
|
||||
s = (double *)malloc(sizeof(double) * min(m, n));
|
||||
u = (double *)malloc(sizeof(double) * m * m);
|
||||
vt = (double *)malloc(sizeof(double) * n * n);
|
||||
superb = (double *)malloc(sizeof(double) * (min(m, n) - 1));
|
||||
a = (double *)malloc(sizeof(double) * m * n);
|
||||
s = (double *)malloc(sizeof(double) * min(m, n));
|
||||
u = (double *)malloc(sizeof(double) * m * m);
|
||||
vt = (double *)malloc(sizeof(double) * n * n);
|
||||
superb = (double *)malloc(sizeof(double) * (min(m, n) - 1));
|
||||
|
||||
for (i = 0; i < m * n; i++)
|
||||
{
|
||||
a[i] = data_in[i];
|
||||
}
|
||||
|
||||
info = LAPACKE_dgesvd(LAPACK_ROW_MAJOR,
|
||||
'A',
|
||||
'A',
|
||||
(lapack_int)m,
|
||||
(lapack_int)n,
|
||||
a,
|
||||
(lapack_int)n,
|
||||
s,
|
||||
u,
|
||||
(lapack_int)m,
|
||||
vt,
|
||||
(lapack_int)n,
|
||||
superb);
|
||||
|
||||
for (i = 0; i < n * m; i++)
|
||||
{
|
||||
data_out[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < m; i++)
|
||||
{
|
||||
for (j = 0; j < n; j++)
|
||||
{
|
||||
for (k = 0; k < min(m, n); k++)
|
||||
{
|
||||
if (s[k] > cutoff)
|
||||
{
|
||||
data_out[j * m + i] += u[i * m + k] / s[k] * vt[k * n + j];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < m * n; i++) {
|
||||
a[i] = data_in[i];
|
||||
}
|
||||
}
|
||||
|
||||
free(a);
|
||||
free(s);
|
||||
free(u);
|
||||
free(vt);
|
||||
free(superb);
|
||||
info = LAPACKE_dgesvd(LAPACK_ROW_MAJOR, 'A', 'A', (lapack_int)m,
|
||||
(lapack_int)n, a, (lapack_int)n, s, u, (lapack_int)m,
|
||||
vt, (lapack_int)n, superb);
|
||||
|
||||
return (int)info;
|
||||
for (i = 0; i < n * m; i++) {
|
||||
data_out[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < m; i++) {
|
||||
for (j = 0; j < n; j++) {
|
||||
for (k = 0; k < min(m, n); k++) {
|
||||
if (s[k] > cutoff) {
|
||||
data_out[j * m + i] += u[i * m + k] / s[k] * vt[k * n + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(a);
|
||||
free(s);
|
||||
free(u);
|
||||
free(vt);
|
||||
free(superb);
|
||||
|
||||
return (int)info;
|
||||
}
|
||||
|
||||
void phonopy_pinv_mt(double *data_out,
|
||||
int *info_out,
|
||||
const double *data_in,
|
||||
const int num_thread,
|
||||
const int *row_nums,
|
||||
const int max_row_num,
|
||||
const int column_num,
|
||||
const double cutoff)
|
||||
{
|
||||
int i;
|
||||
void phonopy_pinv_mt(double *data_out, int *info_out, const double *data_in,
|
||||
const int num_thread, const int *row_nums,
|
||||
const int max_row_num, const int column_num,
|
||||
const double cutoff) {
|
||||
int i;
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (i = 0; i < num_thread; i++)
|
||||
{
|
||||
info_out[i] = phonopy_pinv(data_out + i * max_row_num * column_num,
|
||||
data_in + i * max_row_num * column_num,
|
||||
row_nums[i],
|
||||
column_num,
|
||||
cutoff);
|
||||
}
|
||||
for (i = 0; i < num_thread; i++) {
|
||||
info_out[i] = phonopy_pinv(data_out + i * max_row_num * column_num,
|
||||
data_in + i * max_row_num * column_num,
|
||||
row_nums[i], column_num, cutoff);
|
||||
}
|
||||
}
|
||||
|
||||
int phonopy_dsyev(double *data,
|
||||
double *eigvals,
|
||||
const int size,
|
||||
const int algorithm)
|
||||
{
|
||||
lapack_int info;
|
||||
int phonopy_dsyev(double *data, double *eigvals, const int size,
|
||||
const int algorithm) {
|
||||
lapack_int info;
|
||||
|
||||
lapack_int liwork;
|
||||
long lwork;
|
||||
lapack_int *iwork;
|
||||
double *work;
|
||||
lapack_int iwork_query;
|
||||
double work_query;
|
||||
lapack_int liwork;
|
||||
long lwork;
|
||||
lapack_int *iwork;
|
||||
double *work;
|
||||
lapack_int iwork_query;
|
||||
double work_query;
|
||||
|
||||
info = 0;
|
||||
liwork = -1;
|
||||
lwork = -1;
|
||||
iwork = NULL;
|
||||
work = NULL;
|
||||
info = 0;
|
||||
liwork = -1;
|
||||
lwork = -1;
|
||||
iwork = NULL;
|
||||
work = NULL;
|
||||
|
||||
switch (algorithm)
|
||||
{
|
||||
case 0: /* dsyev */
|
||||
info = LAPACKE_dsyev(LAPACK_COL_MAJOR,
|
||||
'V',
|
||||
'U',
|
||||
(lapack_int)size,
|
||||
data,
|
||||
(lapack_int)size,
|
||||
eigvals);
|
||||
break;
|
||||
case 1: /* dsyevd */
|
||||
info = LAPACKE_dsyevd_work(LAPACK_COL_MAJOR,
|
||||
'V',
|
||||
'U',
|
||||
(lapack_int)size,
|
||||
data,
|
||||
(lapack_int)size,
|
||||
eigvals,
|
||||
&work_query,
|
||||
lwork,
|
||||
&iwork_query,
|
||||
liwork);
|
||||
liwork = iwork_query;
|
||||
lwork = (long)work_query;
|
||||
/* printf("liwork %d, lwork %ld\n", liwork, lwork); */
|
||||
if ((iwork = (lapack_int *)LAPACKE_malloc(sizeof(lapack_int) * liwork)) == NULL)
|
||||
{
|
||||
goto end;
|
||||
};
|
||||
if ((work = (double *)LAPACKE_malloc(sizeof(double) * lwork)) == NULL)
|
||||
{
|
||||
goto end;
|
||||
switch (algorithm) {
|
||||
case 0: /* dsyev */
|
||||
info = LAPACKE_dsyev(LAPACK_COL_MAJOR, 'V', 'U', (lapack_int)size,
|
||||
data, (lapack_int)size, eigvals);
|
||||
break;
|
||||
case 1: /* dsyevd */
|
||||
info = LAPACKE_dsyevd_work(LAPACK_COL_MAJOR, 'V', 'U',
|
||||
(lapack_int)size, data, (lapack_int)size,
|
||||
eigvals, &work_query, lwork,
|
||||
&iwork_query, liwork);
|
||||
liwork = iwork_query;
|
||||
lwork = (long)work_query;
|
||||
/* printf("liwork %d, lwork %ld\n", liwork, lwork); */
|
||||
if ((iwork = (lapack_int *)LAPACKE_malloc(sizeof(lapack_int) *
|
||||
liwork)) == NULL) {
|
||||
goto end;
|
||||
};
|
||||
if ((work = (double *)LAPACKE_malloc(sizeof(double) * lwork)) ==
|
||||
NULL) {
|
||||
goto end;
|
||||
}
|
||||
|
||||
info = LAPACKE_dsyevd_work(LAPACK_COL_MAJOR, 'V', 'U',
|
||||
(lapack_int)size, data, (lapack_int)size,
|
||||
eigvals, work, lwork, iwork, liwork);
|
||||
|
||||
end:
|
||||
if (iwork) {
|
||||
LAPACKE_free(iwork);
|
||||
iwork = NULL;
|
||||
}
|
||||
if (work) {
|
||||
LAPACKE_free(work);
|
||||
work = NULL;
|
||||
}
|
||||
|
||||
/* info = LAPACKE_dsyevd(LAPACK_COL_MAJOR, */
|
||||
/* 'V', */
|
||||
/* 'U', */
|
||||
/* (lapack_int)size, */
|
||||
/* data, */
|
||||
/* (lapack_int)size, */
|
||||
/* eigvals); */
|
||||
break;
|
||||
}
|
||||
|
||||
info = LAPACKE_dsyevd_work(LAPACK_COL_MAJOR,
|
||||
'V',
|
||||
'U',
|
||||
(lapack_int)size,
|
||||
data,
|
||||
(lapack_int)size,
|
||||
eigvals,
|
||||
work,
|
||||
lwork,
|
||||
iwork,
|
||||
liwork);
|
||||
|
||||
end:
|
||||
if (iwork)
|
||||
{
|
||||
LAPACKE_free(iwork);
|
||||
iwork = NULL;
|
||||
}
|
||||
if (work)
|
||||
{
|
||||
LAPACKE_free(work);
|
||||
work = NULL;
|
||||
}
|
||||
|
||||
/* info = LAPACKE_dsyevd(LAPACK_COL_MAJOR, */
|
||||
/* 'V', */
|
||||
/* 'U', */
|
||||
/* (lapack_int)size, */
|
||||
/* data, */
|
||||
/* (lapack_int)size, */
|
||||
/* eigvals); */
|
||||
break;
|
||||
}
|
||||
|
||||
return (int)info;
|
||||
return (int)info;
|
||||
}
|
||||
|
||||
lapack_complex_double
|
||||
phonoc_complex_prod(const lapack_complex_double a,
|
||||
const lapack_complex_double b)
|
||||
{
|
||||
lapack_complex_double c;
|
||||
c = lapack_make_complex_double(lapack_complex_double_real(a) * lapack_complex_double_real(b) -
|
||||
lapack_complex_double_imag(a) * lapack_complex_double_imag(b),
|
||||
lapack_complex_double_imag(a) * lapack_complex_double_real(b) +
|
||||
lapack_complex_double_real(a) * lapack_complex_double_imag(b));
|
||||
return c;
|
||||
lapack_complex_double phonoc_complex_prod(const lapack_complex_double a,
|
||||
const lapack_complex_double b) {
|
||||
lapack_complex_double c;
|
||||
c = lapack_make_complex_double(
|
||||
lapack_complex_double_real(a) * lapack_complex_double_real(b) -
|
||||
lapack_complex_double_imag(a) * lapack_complex_double_imag(b),
|
||||
lapack_complex_double_imag(a) * lapack_complex_double_real(b) +
|
||||
lapack_complex_double_real(a) * lapack_complex_double_imag(b));
|
||||
return c;
|
||||
}
|
||||
|
|
|
@ -45,30 +45,18 @@ MKL_Complex16 lapack_make_complex_double(double re, double im);
|
|||
#include <lapacke.h>
|
||||
#endif
|
||||
|
||||
int phonopy_zheev(double *w,
|
||||
lapack_complex_double *a,
|
||||
const int n,
|
||||
int phonopy_zheev(double *w, lapack_complex_double *a, const int n,
|
||||
const char uplo);
|
||||
int phonopy_pinv(double *data_out,
|
||||
const double *data_in,
|
||||
const int m,
|
||||
const int n,
|
||||
const double cutoff);
|
||||
void phonopy_pinv_mt(double *data_out,
|
||||
int *info_out,
|
||||
const double *data_in,
|
||||
const int num_thread,
|
||||
const int *row_nums,
|
||||
const int max_row_num,
|
||||
const int column_num,
|
||||
int phonopy_pinv(double *data_out, const double *data_in, const int m,
|
||||
const int n, const double cutoff);
|
||||
void phonopy_pinv_mt(double *data_out, int *info_out, const double *data_in,
|
||||
const int num_thread, const int *row_nums,
|
||||
const int max_row_num, const int column_num,
|
||||
const double cutoff);
|
||||
int phonopy_dsyev(double *data,
|
||||
double *eigvals,
|
||||
const int size,
|
||||
int phonopy_dsyev(double *data, double *eigvals, const int size,
|
||||
const int algorithm);
|
||||
|
||||
lapack_complex_double
|
||||
phonoc_complex_prod(const lapack_complex_double a,
|
||||
const lapack_complex_double b);
|
||||
lapack_complex_double phonoc_complex_prod(const lapack_complex_double a,
|
||||
const lapack_complex_double b);
|
||||
|
||||
#endif
|
||||
|
|
1382
c/phono3py.c
1382
c/phono3py.c
File diff suppressed because it is too large
Load Diff
407
c/phono3py.h
407
c/phono3py.h
|
@ -42,251 +42,130 @@
|
|||
#endif
|
||||
#include "phonoc_array.h"
|
||||
|
||||
long ph3py_get_interaction(Darray *fc3_normal_squared,
|
||||
const char *g_zero,
|
||||
const Darray *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multi)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
long ph3py_get_pp_collision(double *imag_self_energy,
|
||||
const long relative_grid_address[24][4][3], /* thm */
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long *triplet_weights,
|
||||
const long (*bz_grid_addresses)[3], /* thm */
|
||||
const long *bz_map, /* thm */
|
||||
const long bz_grid_type,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multi)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const Larray *band_indices,
|
||||
const Darray *temperatures,
|
||||
const long is_NU,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
long ph3py_get_pp_collision_with_sigma(
|
||||
long ph3py_get_interaction(
|
||||
Darray *fc3_normal_squared, const char *g_zero, const Darray *frequencies,
|
||||
const lapack_complex_double *eigenvectors, const long (*triplets)[3],
|
||||
const long num_triplets, const long (*bz_grid_addresses)[3],
|
||||
const long D_diag[3], const long Q[3][3], const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multi)[2], const double *masses,
|
||||
const long *p2s_map, const long *s2p_map, const long *band_indices,
|
||||
const long symmetrize_fc3_q, const double cutoff_frequency);
|
||||
long ph3py_get_pp_collision(
|
||||
double *imag_self_energy,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long *triplet_weights,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multi)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const Larray *band_indices,
|
||||
const Darray *temperatures,
|
||||
const long is_NU,
|
||||
const long symmetrize_fc3_q,
|
||||
const long relative_grid_address[24][4][3], /* thm */
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long *triplet_weights, const long (*bz_grid_addresses)[3], /* thm */
|
||||
const long *bz_map, /* thm */
|
||||
const long bz_grid_type, const long D_diag[3], const long Q[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multi)[2], const double *masses,
|
||||
const long *p2s_map, const long *s2p_map, const Larray *band_indices,
|
||||
const Darray *temperatures, const long is_NU, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
long ph3py_get_pp_collision_with_sigma(
|
||||
double *imag_self_energy, const double sigma, const double sigma_cutoff,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long *triplet_weights, const long (*bz_grid_addresses)[3],
|
||||
const long D_diag[3], const long Q[3][3], const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multi)[2], const double *masses,
|
||||
const long *p2s_map, const long *s2p_map, const Larray *band_indices,
|
||||
const Darray *temperatures, const long is_NU, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
void ph3py_get_imag_self_energy_at_bands_with_g(
|
||||
double *imag_self_energy,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double temperature,
|
||||
const double cutoff_frequency,
|
||||
const long num_frequency_points,
|
||||
const long frequency_point_index);
|
||||
double *imag_self_energy, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double *g, const char *g_zero,
|
||||
const double temperature, const double cutoff_frequency,
|
||||
const long num_frequency_points, const long frequency_point_index);
|
||||
void ph3py_get_detailed_imag_self_energy_at_bands_with_g(
|
||||
double *detailed_imag_self_energy,
|
||||
double *imag_self_energy_N,
|
||||
double *imag_self_energy_U,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double temperature,
|
||||
double *detailed_imag_self_energy, double *imag_self_energy_N,
|
||||
double *imag_self_energy_U, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const long (*bz_grid_addresses)[3],
|
||||
const double *g, const char *g_zero, const double temperature,
|
||||
const double cutoff_frequency);
|
||||
void ph3py_get_real_self_energy_at_bands(double *real_self_energy,
|
||||
const Darray *fc3_normal_squared,
|
||||
const long *band_indices,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
void ph3py_get_real_self_energy_at_bands(
|
||||
double *real_self_energy, const Darray *fc3_normal_squared,
|
||||
const long *band_indices, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplet_weights,
|
||||
const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
void ph3py_get_real_self_energy_at_frequency_point(
|
||||
double *real_self_energy,
|
||||
const double frequency_point,
|
||||
const Darray *fc3_normal_squared,
|
||||
const long *band_indices,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
void ph3py_get_collision_matrix(double *collision_matrix,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const long *rotated_grid_points,
|
||||
const double *rotations_cartesian,
|
||||
const double *g,
|
||||
const long num_ir_gp,
|
||||
const long num_gp,
|
||||
const long num_rot,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
void ph3py_get_reducible_collision_matrix(double *collision_matrix,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplets_map,
|
||||
const long *map_q,
|
||||
const double *g,
|
||||
const long num_gp,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
double *real_self_energy, const double frequency_point,
|
||||
const Darray *fc3_normal_squared, const long *band_indices,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
void ph3py_get_collision_matrix(
|
||||
double *collision_matrix, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplets_map, const long *map_q,
|
||||
const long *rotated_grid_points, const double *rotations_cartesian,
|
||||
const double *g, const long num_ir_gp, const long num_gp,
|
||||
const long num_rot, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
void ph3py_get_reducible_collision_matrix(
|
||||
double *collision_matrix, const Darray *fc3_normal_squared,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplets_map, const long *map_q, const double *g,
|
||||
const long num_gp, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
void ph3py_get_isotope_scattering_strength(
|
||||
double *gamma,
|
||||
const long grid_point,
|
||||
const double *mass_variances,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const long num_band0,
|
||||
const double sigma,
|
||||
const double cutoff_frequency);
|
||||
double *gamma, const long grid_point, const double *mass_variances,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long num_grid_points, const long *band_indices, const long num_band,
|
||||
const long num_band0, const double sigma, const double cutoff_frequency);
|
||||
void ph3py_get_thm_isotope_scattering_strength(
|
||||
double *gamma,
|
||||
const long grid_point,
|
||||
const long *ir_grid_points,
|
||||
const long *weights,
|
||||
const double *mass_variances,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long num_ir_grid_points,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const long num_band0,
|
||||
const double *integration_weights,
|
||||
const double cutoff_frequency);
|
||||
void ph3py_distribute_fc3(double *fc3,
|
||||
const long target,
|
||||
const long source,
|
||||
const long *atom_mapping,
|
||||
const long num_atom,
|
||||
double *gamma, const long grid_point, const long *ir_grid_points,
|
||||
const long *weights, const double *mass_variances,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long num_ir_grid_points, const long *band_indices,
|
||||
const long num_band, const long num_band0,
|
||||
const double *integration_weights, const double cutoff_frequency);
|
||||
void ph3py_distribute_fc3(double *fc3, const long target, const long source,
|
||||
const long *atom_mapping, const long num_atom,
|
||||
const double *rot_cart);
|
||||
void ph3py_rotate_delta_fc2(double (*fc3)[3][3][3],
|
||||
const double (*delta_fc2s)[3][3],
|
||||
const double *inv_U,
|
||||
const double (*site_sym_cart)[3][3],
|
||||
const long *rot_map_syms,
|
||||
const long num_atom,
|
||||
const long num_site_sym,
|
||||
const long num_disp);
|
||||
const long *rot_map_syms, const long num_atom,
|
||||
const long num_site_sym, const long num_disp);
|
||||
void ph3py_get_permutation_symmetry_fc3(double *fc3, const long num_atom);
|
||||
void ph3py_get_permutation_symmetry_compact_fc3(double *fc3,
|
||||
const long p2s[],
|
||||
const long s2pp[],
|
||||
const long nsym_list[],
|
||||
const long perms[],
|
||||
const long n_satom,
|
||||
const long n_patom);
|
||||
void ph3py_transpose_compact_fc3(double *fc3,
|
||||
const long p2s[],
|
||||
const long s2pp[],
|
||||
const long nsym_list[],
|
||||
const long perms[],
|
||||
const long n_satom,
|
||||
const long n_patom,
|
||||
const long t_type);
|
||||
long ph3py_get_triplets_reciprocal_mesh_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long mesh[3],
|
||||
const long is_time_reversal,
|
||||
const long num_rot,
|
||||
const long (*rec_rotations)[3][3],
|
||||
const long swappable);
|
||||
long ph3py_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
void ph3py_get_permutation_symmetry_compact_fc3(
|
||||
double *fc3, const long p2s[], const long s2pp[], const long nsym_list[],
|
||||
const long perms[], const long n_satom, const long n_patom);
|
||||
void ph3py_transpose_compact_fc3(double *fc3, const long p2s[],
|
||||
const long s2pp[], const long nsym_list[],
|
||||
const long perms[], const long n_satom,
|
||||
const long n_patom, const long t_type);
|
||||
long ph3py_get_triplets_reciprocal_mesh_at_q(
|
||||
long *map_triplets, long *map_q, const long grid_point, const long mesh[3],
|
||||
const long is_time_reversal, const long num_rot,
|
||||
const long (*rec_rotations)[3][3], const long swappable);
|
||||
long ph3py_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long *map_triplets,
|
||||
const long *bz_map, const long *map_triplets,
|
||||
const long num_map_triplets,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const long D_diag[3], const long Q[3][3],
|
||||
const long bz_grid_type);
|
||||
long ph3py_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long mesh[3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long bz_grid_type,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_triplets,
|
||||
const long openmp_per_bands);
|
||||
void ph3py_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type);
|
||||
long ph3py_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long relative_grid_address[24][4][3],
|
||||
const long mesh[3], const long (*triplets)[3], const long num_triplets,
|
||||
const long (*bz_grid_addresses)[3], const long *bz_map,
|
||||
const long bz_grid_type, const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_triplets, const long openmp_per_bands);
|
||||
void ph3py_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double sigma_cutoff,
|
||||
const double *frequency_points, const long num_band0,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const double *frequencies, const long num_band, const long tp_type);
|
||||
long ph3py_get_grid_index_from_address(const long address[3],
|
||||
const long mesh[3]);
|
||||
void ph3py_get_gr_grid_addresses(long gr_grid_addresses[][3],
|
||||
|
@ -297,38 +176,27 @@ long ph3py_get_reciprocal_rotations(long rec_rotations[48][3][3],
|
|||
const long is_time_reversal);
|
||||
long ph3py_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long Q[3][3]);
|
||||
long ph3py_get_snf3x3(long D_diag[3],
|
||||
long P[3][3],
|
||||
long Q[3][3],
|
||||
long ph3py_get_snf3x3(long D_diag[3], long P[3][3], long Q[3][3],
|
||||
const long A[3][3]);
|
||||
long ph3py_transform_rotations(long (*transformed_rots)[3][3],
|
||||
const long (*rotations)[3][3],
|
||||
const long num_rot,
|
||||
const long D_diag[3],
|
||||
const long num_rot, const long D_diag[3],
|
||||
const long Q[3][3]);
|
||||
long ph3py_get_ir_grid_map(long *ir_grid_map,
|
||||
const long D_diag[3],
|
||||
const long PS[3],
|
||||
const long (*grg_rotations)[3][3],
|
||||
long ph3py_get_ir_grid_map(long *ir_grid_map, const long D_diag[3],
|
||||
const long PS[3], const long (*grg_rotations)[3][3],
|
||||
const long num_rot);
|
||||
long ph3py_get_bz_grid_addresses(long (*bz_grid_addresses)[3],
|
||||
long *bz_map,
|
||||
long *bzg2grg,
|
||||
const long D_diag[3],
|
||||
const long Q[3][3],
|
||||
const long PS[3],
|
||||
long ph3py_get_bz_grid_addresses(long (*bz_grid_addresses)[3], long *bz_map,
|
||||
long *bzg2grg, const long D_diag[3],
|
||||
const long Q[3][3], const long PS[3],
|
||||
const double rec_lattice[3][3],
|
||||
const long type);
|
||||
long ph3py_rotate_bz_grid_index(const long bz_grid_index,
|
||||
const long rotation[3][3],
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long D_diag[3],
|
||||
const long PS[3],
|
||||
const long bz_grid_type);
|
||||
const long *bz_map, const long D_diag[3],
|
||||
const long PS[3], const long bz_grid_type);
|
||||
void ph3py_symmetrize_collision_matrix(double *collision_matrix,
|
||||
const long num_column,
|
||||
const long num_temp,
|
||||
|
@ -338,33 +206,20 @@ void ph3py_expand_collision_matrix(double *collision_matrix,
|
|||
const long *ir_grid_points,
|
||||
const long num_ir_gp,
|
||||
const long num_grid_points,
|
||||
const long num_rot,
|
||||
const long num_sigma,
|
||||
const long num_temp,
|
||||
const long num_band);
|
||||
long ph3py_get_neighboring_gird_points(long *relative_grid_points,
|
||||
const long *grid_points,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long mesh[3],
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long bz_grid_type,
|
||||
const long num_grid_points,
|
||||
const long num_relative_grid_address);
|
||||
const long num_rot, const long num_sigma,
|
||||
const long num_temp, const long num_band);
|
||||
long ph3py_get_neighboring_gird_points(
|
||||
long *relative_grid_points, const long *grid_points,
|
||||
const long (*relative_grid_address)[3], const long mesh[3],
|
||||
const long (*bz_grid_addresses)[3], const long *bz_map,
|
||||
const long bz_grid_type, const long num_grid_points,
|
||||
const long num_relative_grid_address);
|
||||
long ph3py_get_thm_integration_weights_at_grid_points(
|
||||
double *iw,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const long num_gp,
|
||||
const long (*relative_grid_address)[4][3],
|
||||
const long D_diag[3],
|
||||
const long *grid_points,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map,
|
||||
const long bz_grid_type,
|
||||
const double *frequencies,
|
||||
const long *gp2irgp_map,
|
||||
const char function);
|
||||
double *iw, const double *frequency_points, const long num_band0,
|
||||
const long num_band, const long num_gp,
|
||||
const long (*relative_grid_address)[4][3], const long D_diag[3],
|
||||
const long *grid_points, const long (*bz_grid_addresses)[3],
|
||||
const long *bz_map, const long bz_grid_type, const double *frequencies,
|
||||
const long *gp2irgp_map, const char function);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,13 +39,13 @@
|
|||
|
||||
/* It is assumed that number of dimensions is known for each array. */
|
||||
typedef struct {
|
||||
long dims[MAX_NUM_DIM];
|
||||
long *data;
|
||||
long dims[MAX_NUM_DIM];
|
||||
long *data;
|
||||
} Larray;
|
||||
|
||||
typedef struct {
|
||||
int dims[MAX_NUM_DIM];
|
||||
double *data;
|
||||
int dims[MAX_NUM_DIM];
|
||||
double *data;
|
||||
} Darray;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,24 +32,23 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <math.h>
|
||||
#include "phonoc_const.h"
|
||||
#include "phonoc_utils.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "phonoc_const.h"
|
||||
|
||||
#define THZTOEVPARKB 47.992398658977166
|
||||
#define INVSQRT2PI 0.3989422804014327
|
||||
|
||||
double phonoc_bose_einstein(const double x, const double t)
|
||||
{
|
||||
return 1.0 / (exp(THZTOEVPARKB * x / t) - 1);
|
||||
double phonoc_bose_einstein(const double x, const double t) {
|
||||
return 1.0 / (exp(THZTOEVPARKB * x / t) - 1);
|
||||
}
|
||||
|
||||
double phonoc_gaussian(const double x, const double sigma)
|
||||
{
|
||||
return INVSQRT2PI / sigma * exp(-x * x / 2 / sigma / sigma);
|
||||
double phonoc_gaussian(const double x, const double sigma) {
|
||||
return INVSQRT2PI / sigma * exp(-x * x / 2 / sigma / sigma);
|
||||
}
|
||||
|
||||
double phonoc_inv_sinh_occupation(const double x, const double t)
|
||||
{
|
||||
return 1.0 / sinh(x * THZTOEVPARKB / 2 / t);
|
||||
double phonoc_inv_sinh_occupation(const double x, const double t) {
|
||||
return 1.0 / sinh(x * THZTOEVPARKB / 2 / t);
|
||||
}
|
||||
|
|
1003
c/phonon.c
1003
c/phonon.c
File diff suppressed because it is too large
Load Diff
74
c/phonon.h
74
c/phonon.h
|
@ -38,55 +38,27 @@
|
|||
#include "dynmat.h"
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
void phn_get_phonons_at_gridpoints(double *frequencies,
|
||||
lapack_complex_double *eigenvectors,
|
||||
char *phonon_done,
|
||||
const long num_phonons,
|
||||
const long *grid_points,
|
||||
const long num_grid_points,
|
||||
const long (*grid_address)[3],
|
||||
const double QDinv[3][3],
|
||||
const double *fc2,
|
||||
const double (*svecs_fc2)[3],
|
||||
const long (*multi_fc2)[2],
|
||||
const long num_patom,
|
||||
const long num_satom,
|
||||
const double *masses_fc2,
|
||||
const long *p2s_fc2,
|
||||
const long *s2p_fc2,
|
||||
const double unit_conversion_factor,
|
||||
const double (*born)[3][3],
|
||||
const double dielectric[3][3],
|
||||
const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* must be pointer */
|
||||
const double nac_factor,
|
||||
const char uplo);
|
||||
void phn_get_gonze_phonons_at_gridpoints(double *frequencies,
|
||||
lapack_complex_double *eigenvectors,
|
||||
char *phonon_done,
|
||||
const long num_phonons,
|
||||
const long *grid_points,
|
||||
const long num_grid_points,
|
||||
const long (*grid_address)[3],
|
||||
const double QDinv[3][3],
|
||||
const double *fc2,
|
||||
const double (*svecs_fc2)[3],
|
||||
const long (*multi_fc2)[2],
|
||||
const double (*positions)[3],
|
||||
const long num_patom,
|
||||
const long num_satom,
|
||||
const double *masses_fc2,
|
||||
const long *p2s_fc2,
|
||||
const long *s2p_fc2,
|
||||
const double unit_conversion_factor,
|
||||
const double (*born)[3][3],
|
||||
const double dielectric[3][3],
|
||||
const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* pointer */
|
||||
const double nac_factor,
|
||||
const double *dd_q0,
|
||||
const double (*G_list)[3],
|
||||
const long num_G_points,
|
||||
const double lambda,
|
||||
const char uplo);
|
||||
void phn_get_phonons_at_gridpoints(
|
||||
double *frequencies, lapack_complex_double *eigenvectors, char *phonon_done,
|
||||
const long num_phonons, const long *grid_points, const long num_grid_points,
|
||||
const long (*grid_address)[3], const double QDinv[3][3], const double *fc2,
|
||||
const double (*svecs_fc2)[3], const long (*multi_fc2)[2],
|
||||
const long num_patom, const long num_satom, const double *masses_fc2,
|
||||
const long *p2s_fc2, const long *s2p_fc2,
|
||||
const double unit_conversion_factor, const double (*born)[3][3],
|
||||
const double dielectric[3][3], const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* must be pointer */
|
||||
const double nac_factor, const char uplo);
|
||||
void phn_get_gonze_phonons_at_gridpoints(
|
||||
double *frequencies, lapack_complex_double *eigenvectors, char *phonon_done,
|
||||
const long num_phonons, const long *grid_points, const long num_grid_points,
|
||||
const long (*grid_address)[3], const double QDinv[3][3], const double *fc2,
|
||||
const double (*svecs_fc2)[3], const long (*multi_fc2)[2],
|
||||
const double (*positions)[3], const long num_patom, const long num_satom,
|
||||
const double *masses_fc2, const long *p2s_fc2, const long *s2p_fc2,
|
||||
const double unit_conversion_factor, const double (*born)[3][3],
|
||||
const double dielectric[3][3], const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* pointer */
|
||||
const double nac_factor, const double *dd_q0, const double (*G_list)[3],
|
||||
const long num_G_points, const double lambda, const char uplo);
|
||||
#endif
|
||||
|
|
115
c/phononmod.c
115
c/phononmod.c
|
@ -33,93 +33,36 @@
|
|||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "phononmod.h"
|
||||
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phonon.h"
|
||||
|
||||
void phmod_get_phonons_at_gridpoints(double *frequencies,
|
||||
lapack_complex_double *eigenvectors,
|
||||
char *phonon_done,
|
||||
const long num_phonons,
|
||||
const long *grid_points,
|
||||
const long num_grid_points,
|
||||
const long (*grid_address)[3],
|
||||
const double QDinv[3][3],
|
||||
const double *fc2,
|
||||
const double (*svecs_fc2)[3],
|
||||
const long (*multi_fc2)[2],
|
||||
const double (*positions_fc2)[3],
|
||||
const long num_patom,
|
||||
const long num_satom,
|
||||
const double *masses_fc2,
|
||||
const long *p2s_fc2,
|
||||
const long *s2p_fc2,
|
||||
const double unit_conversion_factor,
|
||||
const double (*born)[3][3],
|
||||
const double dielectric[3][3],
|
||||
const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* pointer */
|
||||
const double nac_factor,
|
||||
const double *dd_q0,
|
||||
const double (*G_list)[3],
|
||||
const long num_G_points,
|
||||
const double lambda,
|
||||
const char uplo)
|
||||
{
|
||||
if (!dd_q0)
|
||||
{
|
||||
phn_get_phonons_at_gridpoints(frequencies,
|
||||
eigenvectors,
|
||||
phonon_done,
|
||||
num_phonons,
|
||||
grid_points,
|
||||
num_grid_points,
|
||||
grid_address,
|
||||
QDinv,
|
||||
fc2,
|
||||
svecs_fc2,
|
||||
multi_fc2,
|
||||
num_patom,
|
||||
num_satom,
|
||||
masses_fc2,
|
||||
p2s_fc2,
|
||||
s2p_fc2,
|
||||
unit_conversion_factor,
|
||||
born,
|
||||
dielectric,
|
||||
reciprocal_lattice,
|
||||
q_direction,
|
||||
nac_factor,
|
||||
uplo);
|
||||
}
|
||||
else
|
||||
{
|
||||
phn_get_gonze_phonons_at_gridpoints(frequencies,
|
||||
eigenvectors,
|
||||
phonon_done,
|
||||
num_phonons,
|
||||
grid_points,
|
||||
num_grid_points,
|
||||
grid_address,
|
||||
QDinv,
|
||||
fc2,
|
||||
svecs_fc2,
|
||||
multi_fc2,
|
||||
positions_fc2,
|
||||
num_patom,
|
||||
num_satom,
|
||||
masses_fc2,
|
||||
p2s_fc2,
|
||||
s2p_fc2,
|
||||
unit_conversion_factor,
|
||||
born,
|
||||
dielectric,
|
||||
reciprocal_lattice,
|
||||
q_direction,
|
||||
nac_factor,
|
||||
dd_q0,
|
||||
G_list,
|
||||
num_G_points,
|
||||
lambda,
|
||||
uplo);
|
||||
}
|
||||
void phmod_get_phonons_at_gridpoints(
|
||||
double *frequencies, lapack_complex_double *eigenvectors, char *phonon_done,
|
||||
const long num_phonons, const long *grid_points, const long num_grid_points,
|
||||
const long (*grid_address)[3], const double QDinv[3][3], const double *fc2,
|
||||
const double (*svecs_fc2)[3], const long (*multi_fc2)[2],
|
||||
const double (*positions_fc2)[3], const long num_patom,
|
||||
const long num_satom, const double *masses_fc2, const long *p2s_fc2,
|
||||
const long *s2p_fc2, const double unit_conversion_factor,
|
||||
const double (*born)[3][3], const double dielectric[3][3],
|
||||
const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* pointer */
|
||||
const double nac_factor, const double *dd_q0, const double (*G_list)[3],
|
||||
const long num_G_points, const double lambda, const char uplo) {
|
||||
if (!dd_q0) {
|
||||
phn_get_phonons_at_gridpoints(
|
||||
frequencies, eigenvectors, phonon_done, num_phonons, grid_points,
|
||||
num_grid_points, grid_address, QDinv, fc2, svecs_fc2, multi_fc2,
|
||||
num_patom, num_satom, masses_fc2, p2s_fc2, s2p_fc2,
|
||||
unit_conversion_factor, born, dielectric, reciprocal_lattice,
|
||||
q_direction, nac_factor, uplo);
|
||||
} else {
|
||||
phn_get_gonze_phonons_at_gridpoints(
|
||||
frequencies, eigenvectors, phonon_done, num_phonons, grid_points,
|
||||
num_grid_points, grid_address, QDinv, fc2, svecs_fc2, multi_fc2,
|
||||
positions_fc2, num_patom, num_satom, masses_fc2, p2s_fc2, s2p_fc2,
|
||||
unit_conversion_factor, born, dielectric, reciprocal_lattice,
|
||||
q_direction, nac_factor, dd_q0, G_list, num_G_points, lambda, uplo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,33 +37,18 @@
|
|||
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
void phmod_get_phonons_at_gridpoints(double *frequencies,
|
||||
lapack_complex_double *eigenvectors,
|
||||
char *phonon_done,
|
||||
const long num_phonons,
|
||||
const long *grid_points,
|
||||
const long num_grid_points,
|
||||
const long (*grid_address)[3],
|
||||
const double QDinv[3][3],
|
||||
const double *fc2,
|
||||
const double (*svecs_fc2)[3],
|
||||
const long (*multi_fc2)[2],
|
||||
const double (*positions_fc2)[3],
|
||||
const long num_patom,
|
||||
const long num_satom,
|
||||
const double *masses_fc2,
|
||||
const long *p2s_fc2,
|
||||
const long *s2p_fc2,
|
||||
const double unit_conversion_factor,
|
||||
const double (*born)[3][3],
|
||||
const double dielectric[3][3],
|
||||
const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* pointer */
|
||||
const double nac_factor,
|
||||
const double *dd_q0,
|
||||
const double (*G_list)[3],
|
||||
const long num_G_points,
|
||||
const double lambda,
|
||||
const char uplo);
|
||||
void phmod_get_phonons_at_gridpoints(
|
||||
double *frequencies, lapack_complex_double *eigenvectors, char *phonon_done,
|
||||
const long num_phonons, const long *grid_points, const long num_grid_points,
|
||||
const long (*grid_address)[3], const double QDinv[3][3], const double *fc2,
|
||||
const double (*svecs_fc2)[3], const long (*multi_fc2)[2],
|
||||
const double (*positions_fc2)[3], const long num_patom,
|
||||
const long num_satom, const double *masses_fc2, const long *p2s_fc2,
|
||||
const long *s2p_fc2, const double unit_conversion_factor,
|
||||
const double (*born)[3][3], const double dielectric[3][3],
|
||||
const double reciprocal_lattice[3][3],
|
||||
const double *q_direction, /* pointer */
|
||||
const double nac_factor, const double *dd_q0, const double (*G_list)[3],
|
||||
const long num_G_points, const double lambda, const char uplo);
|
||||
|
||||
#endif
|
||||
|
|
615
c/pp_collision.c
615
c/pp_collision.c
|
@ -32,454 +32,277 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "pp_collision.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "imag_self_energy_with_g.h"
|
||||
#include "interaction.h"
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_array.h"
|
||||
#include "phonoc_utils.h"
|
||||
#include "pp_collision.h"
|
||||
#include "triplet.h"
|
||||
#include "triplet_iw.h"
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
static void get_collision(double *ise,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const long num_temps,
|
||||
const double *temperatures,
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long triplet[3],
|
||||
const long triplet_weight,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency,
|
||||
const long openmp_per_triplets);
|
||||
static void finalize_ise(double *imag_self_energy,
|
||||
const double *ise,
|
||||
static void get_collision(
|
||||
double *ise, const long num_band0, const long num_band,
|
||||
const long num_temps, const double *temperatures, const double *g,
|
||||
const char *g_zero, const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors, const long triplet[3],
|
||||
const long triplet_weight, const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const double *masses, const long *p2s_map, const long *s2p_map,
|
||||
const long *band_indices, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency, const long openmp_per_triplets);
|
||||
static void finalize_ise(double *imag_self_energy, const double *ise,
|
||||
const long (*bz_grid_address)[3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long num_temps,
|
||||
const long num_band0,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long num_temps, const long num_band0,
|
||||
const long is_NU);
|
||||
|
||||
void ppc_get_pp_collision(double *imag_self_energy,
|
||||
const long relative_grid_address[24][4][3], /* thm */
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long *triplet_weights,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const Larray *band_indices,
|
||||
const Darray *temperatures,
|
||||
const long is_NU,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i;
|
||||
long num_band, num_band0, num_band_prod, num_temps;
|
||||
long openmp_per_triplets;
|
||||
double *ise, *freqs_at_gp, *g;
|
||||
char *g_zero;
|
||||
long tp_relative_grid_address[2][24][4][3];
|
||||
void ppc_get_pp_collision(
|
||||
double *imag_self_energy,
|
||||
const long relative_grid_address[24][4][3], /* thm */
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long *triplet_weights, const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const double *masses, const long *p2s_map, const long *s2p_map,
|
||||
const Larray *band_indices, const Darray *temperatures, const long is_NU,
|
||||
const long symmetrize_fc3_q, const double cutoff_frequency) {
|
||||
long i;
|
||||
long num_band, num_band0, num_band_prod, num_temps;
|
||||
long openmp_per_triplets;
|
||||
double *ise, *freqs_at_gp, *g;
|
||||
char *g_zero;
|
||||
long tp_relative_grid_address[2][24][4][3];
|
||||
|
||||
ise = NULL;
|
||||
freqs_at_gp = NULL;
|
||||
g = NULL;
|
||||
g_zero = NULL;
|
||||
ise = NULL;
|
||||
freqs_at_gp = NULL;
|
||||
g = NULL;
|
||||
g_zero = NULL;
|
||||
|
||||
num_band0 = band_indices->dims[0];
|
||||
num_band = multi_dims[1] * 3;
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
num_temps = temperatures->dims[0];
|
||||
ise = (double *)malloc(sizeof(double) * num_triplets * num_temps * num_band0);
|
||||
freqs_at_gp = (double *)malloc(sizeof(double) * num_band0);
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
freqs_at_gp[i] = frequencies[triplets[0][0] * num_band + band_indices->data[i]];
|
||||
}
|
||||
num_band0 = band_indices->dims[0];
|
||||
num_band = multi_dims[1] * 3;
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
num_temps = temperatures->dims[0];
|
||||
ise =
|
||||
(double *)malloc(sizeof(double) * num_triplets * num_temps * num_band0);
|
||||
freqs_at_gp = (double *)malloc(sizeof(double) * num_band0);
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
freqs_at_gp[i] =
|
||||
frequencies[triplets[0][0] * num_band + band_indices->data[i]];
|
||||
}
|
||||
|
||||
if (num_triplets > num_band)
|
||||
{
|
||||
openmp_per_triplets = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
openmp_per_triplets = 0;
|
||||
}
|
||||
if (num_triplets > num_band) {
|
||||
openmp_per_triplets = 1;
|
||||
} else {
|
||||
openmp_per_triplets = 0;
|
||||
}
|
||||
|
||||
tpl_set_relative_grid_address(tp_relative_grid_address,
|
||||
relative_grid_address,
|
||||
2);
|
||||
tpl_set_relative_grid_address(tp_relative_grid_address,
|
||||
relative_grid_address, 2);
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for schedule(guided) private(g, g_zero) if (openmp_per_triplets)
|
||||
#pragma omp parallel for schedule(guided) private( \
|
||||
g, g_zero) if (openmp_per_triplets)
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
g = (double *)malloc(sizeof(double) * 2 * num_band_prod);
|
||||
g_zero = (char *)malloc(sizeof(char) * num_band_prod);
|
||||
tpi_get_integration_weight(g,
|
||||
g_zero,
|
||||
freqs_at_gp, /* used as f0 */
|
||||
num_band0,
|
||||
tp_relative_grid_address,
|
||||
triplets[i],
|
||||
1,
|
||||
bzgrid,
|
||||
frequencies, /* used as f1 */
|
||||
num_band,
|
||||
frequencies, /* used as f2 */
|
||||
num_band,
|
||||
2,
|
||||
1 - openmp_per_triplets);
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
g = (double *)malloc(sizeof(double) * 2 * num_band_prod);
|
||||
g_zero = (char *)malloc(sizeof(char) * num_band_prod);
|
||||
tpi_get_integration_weight(g, g_zero, freqs_at_gp, /* used as f0 */
|
||||
num_band0, tp_relative_grid_address,
|
||||
triplets[i], 1, bzgrid,
|
||||
frequencies, /* used as f1 */
|
||||
num_band, frequencies, /* used as f2 */
|
||||
num_band, 2, 1 - openmp_per_triplets);
|
||||
|
||||
get_collision(ise + i * num_temps * num_band0,
|
||||
num_band0,
|
||||
num_band,
|
||||
num_temps,
|
||||
temperatures->data,
|
||||
g,
|
||||
g_zero,
|
||||
frequencies,
|
||||
eigenvectors,
|
||||
triplets[i],
|
||||
triplet_weights[i],
|
||||
bzgrid,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices->data,
|
||||
symmetrize_fc3_q,
|
||||
cutoff_frequency,
|
||||
openmp_per_triplets);
|
||||
get_collision(ise + i * num_temps * num_band0, num_band0, num_band,
|
||||
num_temps, temperatures->data, g, g_zero, frequencies,
|
||||
eigenvectors, triplets[i], triplet_weights[i], bzgrid,
|
||||
fc3, is_compact_fc3, svecs, multi_dims, multiplicity,
|
||||
masses, p2s_map, s2p_map, band_indices->data,
|
||||
symmetrize_fc3_q, cutoff_frequency, openmp_per_triplets);
|
||||
|
||||
free(g_zero);
|
||||
g_zero = NULL;
|
||||
free(g);
|
||||
g = NULL;
|
||||
}
|
||||
free(g_zero);
|
||||
g_zero = NULL;
|
||||
free(g);
|
||||
g = NULL;
|
||||
}
|
||||
|
||||
finalize_ise(imag_self_energy,
|
||||
ise,
|
||||
bzgrid->addresses,
|
||||
triplets,
|
||||
num_triplets,
|
||||
num_temps,
|
||||
num_band0,
|
||||
is_NU);
|
||||
finalize_ise(imag_self_energy, ise, bzgrid->addresses, triplets,
|
||||
num_triplets, num_temps, num_band0, is_NU);
|
||||
|
||||
free(freqs_at_gp);
|
||||
freqs_at_gp = NULL;
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
free(freqs_at_gp);
|
||||
freqs_at_gp = NULL;
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
}
|
||||
|
||||
void ppc_get_pp_collision_with_sigma(
|
||||
double *imag_self_energy,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long *triplet_weights,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const Larray *band_indices,
|
||||
const Darray *temperatures,
|
||||
const long is_NU,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i;
|
||||
long num_band, num_band0, num_band_prod, num_temps;
|
||||
long openmp_per_triplets, const_adrs_shift;
|
||||
double cutoff;
|
||||
double *ise, *freqs_at_gp, *g;
|
||||
char *g_zero;
|
||||
double *imag_self_energy, const double sigma, const double sigma_cutoff,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long *triplet_weights, const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const double *masses, const long *p2s_map, const long *s2p_map,
|
||||
const Larray *band_indices, const Darray *temperatures, const long is_NU,
|
||||
const long symmetrize_fc3_q, const double cutoff_frequency) {
|
||||
long i;
|
||||
long num_band, num_band0, num_band_prod, num_temps;
|
||||
long openmp_per_triplets, const_adrs_shift;
|
||||
double cutoff;
|
||||
double *ise, *freqs_at_gp, *g;
|
||||
char *g_zero;
|
||||
|
||||
ise = NULL;
|
||||
freqs_at_gp = NULL;
|
||||
g = NULL;
|
||||
g_zero = NULL;
|
||||
ise = NULL;
|
||||
freqs_at_gp = NULL;
|
||||
g = NULL;
|
||||
g_zero = NULL;
|
||||
|
||||
num_band0 = band_indices->dims[0];
|
||||
num_band = multi_dims[1] * 3;
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
num_temps = temperatures->dims[0];
|
||||
const_adrs_shift = num_band_prod;
|
||||
num_band0 = band_indices->dims[0];
|
||||
num_band = multi_dims[1] * 3;
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
num_temps = temperatures->dims[0];
|
||||
const_adrs_shift = num_band_prod;
|
||||
|
||||
ise = (double *)malloc(sizeof(double) * num_triplets * num_temps * num_band0);
|
||||
freqs_at_gp = (double *)malloc(sizeof(double) * num_band0);
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
freqs_at_gp[i] = frequencies[triplets[0][0] * num_band +
|
||||
band_indices->data[i]];
|
||||
}
|
||||
ise =
|
||||
(double *)malloc(sizeof(double) * num_triplets * num_temps * num_band0);
|
||||
freqs_at_gp = (double *)malloc(sizeof(double) * num_band0);
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
freqs_at_gp[i] =
|
||||
frequencies[triplets[0][0] * num_band + band_indices->data[i]];
|
||||
}
|
||||
|
||||
if (num_triplets > num_band)
|
||||
{
|
||||
openmp_per_triplets = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
openmp_per_triplets = 0;
|
||||
}
|
||||
if (num_triplets > num_band) {
|
||||
openmp_per_triplets = 1;
|
||||
} else {
|
||||
openmp_per_triplets = 0;
|
||||
}
|
||||
|
||||
cutoff = sigma * sigma_cutoff;
|
||||
cutoff = sigma * sigma_cutoff;
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for schedule(guided) private(g, g_zero) if (openmp_per_triplets)
|
||||
#pragma omp parallel for schedule(guided) private( \
|
||||
g, g_zero) if (openmp_per_triplets)
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
g = (double *)malloc(sizeof(double) * 2 * num_band_prod);
|
||||
g_zero = (char *)malloc(sizeof(char) * num_band_prod);
|
||||
tpi_get_integration_weight_with_sigma(g,
|
||||
g_zero,
|
||||
sigma,
|
||||
cutoff,
|
||||
freqs_at_gp,
|
||||
num_band0,
|
||||
triplets[i],
|
||||
const_adrs_shift,
|
||||
frequencies,
|
||||
num_band,
|
||||
2,
|
||||
0);
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
g = (double *)malloc(sizeof(double) * 2 * num_band_prod);
|
||||
g_zero = (char *)malloc(sizeof(char) * num_band_prod);
|
||||
tpi_get_integration_weight_with_sigma(
|
||||
g, g_zero, sigma, cutoff, freqs_at_gp, num_band0, triplets[i],
|
||||
const_adrs_shift, frequencies, num_band, 2, 0);
|
||||
|
||||
get_collision(ise + i * num_temps * num_band0,
|
||||
num_band0,
|
||||
num_band,
|
||||
num_temps,
|
||||
temperatures->data,
|
||||
g,
|
||||
g_zero,
|
||||
frequencies,
|
||||
eigenvectors,
|
||||
triplets[i],
|
||||
triplet_weights[i],
|
||||
bzgrid,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices->data,
|
||||
symmetrize_fc3_q,
|
||||
cutoff_frequency,
|
||||
openmp_per_triplets);
|
||||
get_collision(ise + i * num_temps * num_band0, num_band0, num_band,
|
||||
num_temps, temperatures->data, g, g_zero, frequencies,
|
||||
eigenvectors, triplets[i], triplet_weights[i], bzgrid,
|
||||
fc3, is_compact_fc3, svecs, multi_dims, multiplicity,
|
||||
masses, p2s_map, s2p_map, band_indices->data,
|
||||
symmetrize_fc3_q, cutoff_frequency, openmp_per_triplets);
|
||||
|
||||
free(g_zero);
|
||||
g_zero = NULL;
|
||||
free(g);
|
||||
g = NULL;
|
||||
}
|
||||
free(g_zero);
|
||||
g_zero = NULL;
|
||||
free(g);
|
||||
g = NULL;
|
||||
}
|
||||
|
||||
finalize_ise(imag_self_energy,
|
||||
ise,
|
||||
bzgrid->addresses,
|
||||
triplets,
|
||||
num_triplets,
|
||||
num_temps,
|
||||
num_band0,
|
||||
is_NU);
|
||||
finalize_ise(imag_self_energy, ise, bzgrid->addresses, triplets,
|
||||
num_triplets, num_temps, num_band0, is_NU);
|
||||
|
||||
free(freqs_at_gp);
|
||||
freqs_at_gp = NULL;
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
free(freqs_at_gp);
|
||||
freqs_at_gp = NULL;
|
||||
free(ise);
|
||||
ise = NULL;
|
||||
}
|
||||
|
||||
static void get_collision(double *ise,
|
||||
const long num_band0,
|
||||
const long num_band,
|
||||
const long num_temps,
|
||||
const double *temperatures,
|
||||
const double *g,
|
||||
const char *g_zero,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long triplet[3],
|
||||
const long triplet_weight,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long *band_indices,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency,
|
||||
const long openmp_per_triplets)
|
||||
{
|
||||
long i;
|
||||
long num_band_prod, num_g_pos;
|
||||
double *fc3_normal_squared;
|
||||
long(*g_pos)[4];
|
||||
static void get_collision(
|
||||
double *ise, const long num_band0, const long num_band,
|
||||
const long num_temps, const double *temperatures, const double *g,
|
||||
const char *g_zero, const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors, const long triplet[3],
|
||||
const long triplet_weight, const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const double *masses, const long *p2s_map, const long *s2p_map,
|
||||
const long *band_indices, const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency, const long openmp_per_triplets) {
|
||||
long i;
|
||||
long num_band_prod, num_g_pos;
|
||||
double *fc3_normal_squared;
|
||||
long(*g_pos)[4];
|
||||
|
||||
fc3_normal_squared = NULL;
|
||||
g_pos = NULL;
|
||||
fc3_normal_squared = NULL;
|
||||
g_pos = NULL;
|
||||
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
fc3_normal_squared = (double *)malloc(sizeof(double) * num_band_prod);
|
||||
g_pos = (long(*)[4])malloc(sizeof(long[4]) * num_band_prod);
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
fc3_normal_squared = (double *)malloc(sizeof(double) * num_band_prod);
|
||||
g_pos = (long(*)[4])malloc(sizeof(long[4]) * num_band_prod);
|
||||
|
||||
for (i = 0; i < num_band_prod; i++)
|
||||
{
|
||||
fc3_normal_squared[i] = 0;
|
||||
}
|
||||
for (i = 0; i < num_band_prod; i++) {
|
||||
fc3_normal_squared[i] = 0;
|
||||
}
|
||||
|
||||
num_g_pos = ise_set_g_pos(g_pos,
|
||||
num_band0,
|
||||
num_band,
|
||||
g_zero);
|
||||
num_g_pos = ise_set_g_pos(g_pos, num_band0, num_band, g_zero);
|
||||
|
||||
itr_get_interaction_at_triplet(
|
||||
fc3_normal_squared,
|
||||
num_band0,
|
||||
num_band,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
frequencies,
|
||||
eigenvectors,
|
||||
triplet,
|
||||
bzgrid,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
masses,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
band_indices,
|
||||
symmetrize_fc3_q,
|
||||
cutoff_frequency,
|
||||
0,
|
||||
0,
|
||||
1 - openmp_per_triplets);
|
||||
itr_get_interaction_at_triplet(
|
||||
fc3_normal_squared, num_band0, num_band, g_pos, num_g_pos, frequencies,
|
||||
eigenvectors, triplet, bzgrid, fc3, is_compact_fc3, svecs, multi_dims,
|
||||
multiplicity, masses, p2s_map, s2p_map, band_indices, symmetrize_fc3_q,
|
||||
cutoff_frequency, 0, 0, 1 - openmp_per_triplets);
|
||||
|
||||
ise_imag_self_energy_at_triplet(
|
||||
ise,
|
||||
num_band0,
|
||||
num_band,
|
||||
fc3_normal_squared,
|
||||
frequencies,
|
||||
triplet,
|
||||
triplet_weight,
|
||||
g,
|
||||
g + num_band_prod,
|
||||
g_pos,
|
||||
num_g_pos,
|
||||
temperatures,
|
||||
num_temps,
|
||||
cutoff_frequency,
|
||||
1 - openmp_per_triplets,
|
||||
0);
|
||||
ise_imag_self_energy_at_triplet(
|
||||
ise, num_band0, num_band, fc3_normal_squared, frequencies, triplet,
|
||||
triplet_weight, g, g + num_band_prod, g_pos, num_g_pos, temperatures,
|
||||
num_temps, cutoff_frequency, 1 - openmp_per_triplets, 0);
|
||||
|
||||
free(fc3_normal_squared);
|
||||
fc3_normal_squared = NULL;
|
||||
free(g_pos);
|
||||
g_pos = NULL;
|
||||
free(fc3_normal_squared);
|
||||
fc3_normal_squared = NULL;
|
||||
free(g_pos);
|
||||
g_pos = NULL;
|
||||
}
|
||||
|
||||
static void finalize_ise(double *imag_self_energy,
|
||||
const double *ise,
|
||||
static void finalize_ise(double *imag_self_energy, const double *ise,
|
||||
const long (*bz_grid_addresses)[3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long num_temps,
|
||||
const long num_band0,
|
||||
const long is_NU)
|
||||
{
|
||||
long i, j, k;
|
||||
long is_N;
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long num_temps, const long num_band0,
|
||||
const long is_NU) {
|
||||
long i, j, k;
|
||||
long is_N;
|
||||
|
||||
if (is_NU)
|
||||
{
|
||||
for (i = 0; i < 2 * num_temps * num_band0; i++)
|
||||
{
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
is_N = tpl_is_N(triplets[i], bz_grid_addresses);
|
||||
for (j = 0; j < num_temps; j++)
|
||||
{
|
||||
for (k = 0; k < num_band0; k++)
|
||||
{
|
||||
if (is_N)
|
||||
{
|
||||
imag_self_energy[j * num_band0 + k] +=
|
||||
ise[i * num_temps * num_band0 + j * num_band0 + k];
|
||||
}
|
||||
else
|
||||
{
|
||||
imag_self_energy[num_temps * num_band0 + j * num_band0 + k] +=
|
||||
ise[i * num_temps * num_band0 + j * num_band0 + k];
|
||||
}
|
||||
if (is_NU) {
|
||||
for (i = 0; i < 2 * num_temps * num_band0; i++) {
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < num_temps * num_band0; i++)
|
||||
{
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
for (j = 0; j < num_temps; j++)
|
||||
{
|
||||
for (k = 0; k < num_band0; k++)
|
||||
{
|
||||
imag_self_energy[j * num_band0 + k] +=
|
||||
ise[i * num_temps * num_band0 + j * num_band0 + k];
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
is_N = tpl_is_N(triplets[i], bz_grid_addresses);
|
||||
for (j = 0; j < num_temps; j++) {
|
||||
for (k = 0; k < num_band0; k++) {
|
||||
if (is_N) {
|
||||
imag_self_energy[j * num_band0 + k] +=
|
||||
ise[i * num_temps * num_band0 + j * num_band0 + k];
|
||||
} else {
|
||||
imag_self_energy[num_temps * num_band0 + j * num_band0 +
|
||||
k] +=
|
||||
ise[i * num_temps * num_band0 + j * num_band0 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < num_temps * num_band0; i++) {
|
||||
imag_self_energy[i] = 0;
|
||||
}
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
for (j = 0; j < num_temps; j++) {
|
||||
for (k = 0; k < num_band0; k++) {
|
||||
imag_self_energy[j * num_band0 + k] +=
|
||||
ise[i * num_temps * num_band0 + j * num_band0 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,49 +39,26 @@
|
|||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_array.h"
|
||||
|
||||
void ppc_get_pp_collision(double *imag_self_energy,
|
||||
const long relative_grid_address[24][4][3], /* thm */
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long *triplet_weights,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const Larray *band_indices,
|
||||
const Darray *temperatures,
|
||||
const long is_NU,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
void ppc_get_pp_collision(
|
||||
double *imag_self_energy,
|
||||
const long relative_grid_address[24][4][3], /* thm */
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long *triplet_weights, const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const double *masses, const long *p2s_map, const long *s2p_map,
|
||||
const Larray *band_indices, const Darray *temperatures, const long is_NU,
|
||||
const long symmetrize_fc3_q, const double cutoff_frequency);
|
||||
void ppc_get_pp_collision_with_sigma(
|
||||
double *imag_self_energy,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequencies,
|
||||
const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const long *triplet_weights,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const double *masses,
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const Larray *band_indices,
|
||||
const Darray *temperatures,
|
||||
const long is_NU,
|
||||
const long symmetrize_fc3_q,
|
||||
const double cutoff_frequency);
|
||||
double *imag_self_energy, const double sigma, const double sigma_cutoff,
|
||||
const double *frequencies, const lapack_complex_double *eigenvectors,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const long *triplet_weights, const ConstBZGrid *bzgrid, const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const double *masses, const long *p2s_map, const long *s2p_map,
|
||||
const Larray *band_indices, const Darray *temperatures, const long is_NU,
|
||||
const long symmetrize_fc3_q, const double cutoff_frequency);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -32,263 +32,191 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "real_self_energy.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "phonoc_array.h"
|
||||
#include "phonoc_utils.h"
|
||||
#include "real_self_energy.h"
|
||||
#include "real_to_reciprocal.h"
|
||||
|
||||
static double get_real_self_energy_at_band(const long band_index,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double fpoint,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
static double sum_real_self_energy_at_band(const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double fpoint,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double cutoff_frequency);
|
||||
static double sum_real_self_energy_at_band_0K(const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double fpoint,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const double epsilon,
|
||||
const double cutoff_frequency);
|
||||
static double get_real_self_energy_at_band(
|
||||
const long band_index, const Darray *fc3_normal_squared,
|
||||
const double fpoint, const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
static double sum_real_self_energy_at_band(
|
||||
const long num_band, const double *fc3_normal_squared, const double fpoint,
|
||||
const double *freqs1, const double *freqs2, const double epsilon,
|
||||
const double temperature, const double cutoff_frequency);
|
||||
static double sum_real_self_energy_at_band_0K(
|
||||
const long num_band, const double *fc3_normal_squared, const double fpoint,
|
||||
const double *freqs1, const double *freqs2, const double epsilon,
|
||||
const double cutoff_frequency);
|
||||
|
||||
void rse_get_real_self_energy_at_bands(double *real_self_energy,
|
||||
const Darray *fc3_normal_squared,
|
||||
const long *band_indices,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, num_band0, num_band, gp0;
|
||||
double fpoint;
|
||||
void rse_get_real_self_energy_at_bands(
|
||||
double *real_self_energy, const Darray *fc3_normal_squared,
|
||||
const long *band_indices, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplet_weights,
|
||||
const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency) {
|
||||
long i, num_band0, num_band, gp0;
|
||||
double fpoint;
|
||||
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
gp0 = triplets[0][0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
gp0 = triplets[0][0];
|
||||
|
||||
/* num_band0 and num_band_indices have to be same. */
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
fpoint = frequencies[gp0 * num_band + band_indices[i]];
|
||||
if (fpoint < cutoff_frequency)
|
||||
{
|
||||
real_self_energy[i] = 0;
|
||||
/* num_band0 and num_band_indices have to be same. */
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
fpoint = frequencies[gp0 * num_band + band_indices[i]];
|
||||
if (fpoint < cutoff_frequency) {
|
||||
real_self_energy[i] = 0;
|
||||
} else {
|
||||
real_self_energy[i] = get_real_self_energy_at_band(
|
||||
i, fc3_normal_squared, fpoint, frequencies, triplets,
|
||||
triplet_weights, epsilon, temperature, unit_conversion_factor,
|
||||
cutoff_frequency);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
real_self_energy[i] =
|
||||
get_real_self_energy_at_band(i,
|
||||
fc3_normal_squared,
|
||||
fpoint,
|
||||
frequencies,
|
||||
triplets,
|
||||
triplet_weights,
|
||||
epsilon,
|
||||
temperature,
|
||||
unit_conversion_factor,
|
||||
cutoff_frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rse_get_real_self_energy_at_frequency_point(
|
||||
double *real_self_energy,
|
||||
const double frequency_point,
|
||||
const Darray *fc3_normal_squared,
|
||||
const long *band_indices,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, num_band0;
|
||||
double *real_self_energy, const double frequency_point,
|
||||
const Darray *fc3_normal_squared, const long *band_indices,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency) {
|
||||
long i, num_band0;
|
||||
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
|
||||
/* num_band0 and num_band_indices have to be same. */
|
||||
for (i = 0; i < num_band0; i++)
|
||||
{
|
||||
if (frequency_point < cutoff_frequency)
|
||||
{
|
||||
real_self_energy[i] = 0;
|
||||
/* num_band0 and num_band_indices have to be same. */
|
||||
for (i = 0; i < num_band0; i++) {
|
||||
if (frequency_point < cutoff_frequency) {
|
||||
real_self_energy[i] = 0;
|
||||
} else {
|
||||
real_self_energy[i] = get_real_self_energy_at_band(
|
||||
i, fc3_normal_squared, frequency_point, frequencies, triplets,
|
||||
triplet_weights, epsilon, temperature, unit_conversion_factor,
|
||||
cutoff_frequency);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
real_self_energy[i] =
|
||||
get_real_self_energy_at_band(i,
|
||||
fc3_normal_squared,
|
||||
frequency_point,
|
||||
frequencies,
|
||||
triplets,
|
||||
triplet_weights,
|
||||
epsilon,
|
||||
temperature,
|
||||
unit_conversion_factor,
|
||||
cutoff_frequency);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static double get_real_self_energy_at_band(const long band_index,
|
||||
const Darray *fc3_normal_squared,
|
||||
const double fpoint,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, num_triplets, num_band0, num_band, gp1, gp2;
|
||||
double shift;
|
||||
static double get_real_self_energy_at_band(
|
||||
const long band_index, const Darray *fc3_normal_squared,
|
||||
const double fpoint, const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency) {
|
||||
long i, num_triplets, num_band0, num_band, gp1, gp2;
|
||||
double shift;
|
||||
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
num_triplets = fc3_normal_squared->dims[0];
|
||||
num_band0 = fc3_normal_squared->dims[1];
|
||||
num_band = fc3_normal_squared->dims[2];
|
||||
|
||||
shift = 0;
|
||||
shift = 0;
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(gp1, gp2) reduction(+ \
|
||||
: shift)
|
||||
#pragma omp parallel for private(gp1, gp2) reduction(+ : shift)
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
gp1 = triplets[i][1];
|
||||
gp2 = triplets[i][2];
|
||||
if (temperature > 0)
|
||||
{
|
||||
shift +=
|
||||
sum_real_self_energy_at_band(num_band,
|
||||
fc3_normal_squared->data +
|
||||
i * num_band0 * num_band * num_band +
|
||||
band_index * num_band * num_band,
|
||||
fpoint,
|
||||
frequencies + gp1 * num_band,
|
||||
frequencies + gp2 * num_band,
|
||||
epsilon,
|
||||
temperature,
|
||||
cutoff_frequency) *
|
||||
triplet_weights[i] * unit_conversion_factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
shift +=
|
||||
sum_real_self_energy_at_band_0K(num_band,
|
||||
fc3_normal_squared->data +
|
||||
i * num_band0 * num_band * num_band +
|
||||
band_index * num_band * num_band,
|
||||
fpoint,
|
||||
frequencies + gp1 * num_band,
|
||||
frequencies + gp2 * num_band,
|
||||
epsilon,
|
||||
cutoff_frequency) *
|
||||
triplet_weights[i] * unit_conversion_factor;
|
||||
}
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
||||
static double sum_real_self_energy_at_band(const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double fpoint,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j;
|
||||
double n1, n2, f1, f2, f3, f4, shift;
|
||||
/* double sum; */
|
||||
|
||||
shift = 0;
|
||||
for (i = 0; i < num_band; i++)
|
||||
{
|
||||
if (freqs1[i] > cutoff_frequency)
|
||||
{
|
||||
n1 = phonoc_bose_einstein(freqs1[i], temperature);
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
if (freqs2[j] > cutoff_frequency)
|
||||
{
|
||||
n2 = phonoc_bose_einstein(freqs2[j], temperature);
|
||||
f1 = fpoint + freqs1[i] + freqs2[j];
|
||||
f2 = fpoint - freqs1[i] - freqs2[j];
|
||||
f3 = fpoint - freqs1[i] + freqs2[j];
|
||||
f4 = fpoint + freqs1[i] - freqs2[j];
|
||||
|
||||
/* sum = 0;
|
||||
* if (fabs(f1) > epsilon) {
|
||||
* sum -= (n1 + n2 + 1) / f1;
|
||||
* }
|
||||
* if (fabs(f2) > epsilon) {
|
||||
* sum += (n1 + n2 + 1) / f2;
|
||||
* }
|
||||
* if (fabs(f3) > epsilon) {
|
||||
* sum -= (n1 - n2) / f3;
|
||||
* }
|
||||
* if (fabs(f4) > epsilon) {
|
||||
* sum += (n1 - n2) / f4;
|
||||
* }
|
||||
* shift += sum * fc3_normal_squared[i * num_band + j]; */
|
||||
|
||||
shift += (-(n1 + n2 + 1) * f1 / (f1 * f1 + epsilon * epsilon) + (n1 + n2 + 1) * f2 / (f2 * f2 + epsilon * epsilon) - (n1 - n2) * f3 / (f3 * f3 + epsilon * epsilon) + (n1 - n2) * f4 / (f4 * f4 + epsilon * epsilon)) *
|
||||
fc3_normal_squared[i * num_band + j];
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
gp1 = triplets[i][1];
|
||||
gp2 = triplets[i][2];
|
||||
if (temperature > 0) {
|
||||
shift += sum_real_self_energy_at_band(
|
||||
num_band,
|
||||
fc3_normal_squared->data +
|
||||
i * num_band0 * num_band * num_band +
|
||||
band_index * num_band * num_band,
|
||||
fpoint, frequencies + gp1 * num_band,
|
||||
frequencies + gp2 * num_band, epsilon, temperature,
|
||||
cutoff_frequency) *
|
||||
triplet_weights[i] * unit_conversion_factor;
|
||||
} else {
|
||||
shift +=
|
||||
sum_real_self_energy_at_band_0K(
|
||||
num_band,
|
||||
fc3_normal_squared->data +
|
||||
i * num_band0 * num_band * num_band +
|
||||
band_index * num_band * num_band,
|
||||
fpoint, frequencies + gp1 * num_band,
|
||||
frequencies + gp2 * num_band, epsilon, cutoff_frequency) *
|
||||
triplet_weights[i] * unit_conversion_factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return shift;
|
||||
return shift;
|
||||
}
|
||||
|
||||
static double sum_real_self_energy_at_band_0K(const long num_band,
|
||||
const double *fc3_normal_squared,
|
||||
const double fpoint,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const double epsilon,
|
||||
const double cutoff_frequency)
|
||||
{
|
||||
long i, j;
|
||||
double f1, f2, shift;
|
||||
static double sum_real_self_energy_at_band(
|
||||
const long num_band, const double *fc3_normal_squared, const double fpoint,
|
||||
const double *freqs1, const double *freqs2, const double epsilon,
|
||||
const double temperature, const double cutoff_frequency) {
|
||||
long i, j;
|
||||
double n1, n2, f1, f2, f3, f4, shift;
|
||||
/* double sum; */
|
||||
|
||||
shift = 0;
|
||||
for (i = 0; i < num_band; i++)
|
||||
{
|
||||
if (freqs1[i] > cutoff_frequency)
|
||||
{
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
if (freqs2[j] > cutoff_frequency)
|
||||
{
|
||||
f1 = fpoint + freqs1[i] + freqs2[j];
|
||||
f2 = fpoint - freqs1[i] - freqs2[j];
|
||||
shift += (-1 * f1 / (f1 * f1 + epsilon * epsilon) + 1 * f2 / (f2 * f2 + epsilon * epsilon)) *
|
||||
fc3_normal_squared[i * num_band + j];
|
||||
shift = 0;
|
||||
for (i = 0; i < num_band; i++) {
|
||||
if (freqs1[i] > cutoff_frequency) {
|
||||
n1 = phonoc_bose_einstein(freqs1[i], temperature);
|
||||
for (j = 0; j < num_band; j++) {
|
||||
if (freqs2[j] > cutoff_frequency) {
|
||||
n2 = phonoc_bose_einstein(freqs2[j], temperature);
|
||||
f1 = fpoint + freqs1[i] + freqs2[j];
|
||||
f2 = fpoint - freqs1[i] - freqs2[j];
|
||||
f3 = fpoint - freqs1[i] + freqs2[j];
|
||||
f4 = fpoint + freqs1[i] - freqs2[j];
|
||||
|
||||
/* sum = 0;
|
||||
* if (fabs(f1) > epsilon) {
|
||||
* sum -= (n1 + n2 + 1) / f1;
|
||||
* }
|
||||
* if (fabs(f2) > epsilon) {
|
||||
* sum += (n1 + n2 + 1) / f2;
|
||||
* }
|
||||
* if (fabs(f3) > epsilon) {
|
||||
* sum -= (n1 - n2) / f3;
|
||||
* }
|
||||
* if (fabs(f4) > epsilon) {
|
||||
* sum += (n1 - n2) / f4;
|
||||
* }
|
||||
* shift += sum * fc3_normal_squared[i * num_band + j]; */
|
||||
|
||||
shift +=
|
||||
(-(n1 + n2 + 1) * f1 / (f1 * f1 + epsilon * epsilon) +
|
||||
(n1 + n2 + 1) * f2 / (f2 * f2 + epsilon * epsilon) -
|
||||
(n1 - n2) * f3 / (f3 * f3 + epsilon * epsilon) +
|
||||
(n1 - n2) * f4 / (f4 * f4 + epsilon * epsilon)) *
|
||||
fc3_normal_squared[i * num_band + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return shift;
|
||||
return shift;
|
||||
}
|
||||
|
||||
static double sum_real_self_energy_at_band_0K(
|
||||
const long num_band, const double *fc3_normal_squared, const double fpoint,
|
||||
const double *freqs1, const double *freqs2, const double epsilon,
|
||||
const double cutoff_frequency) {
|
||||
long i, j;
|
||||
double f1, f2, shift;
|
||||
|
||||
shift = 0;
|
||||
for (i = 0; i < num_band; i++) {
|
||||
if (freqs1[i] > cutoff_frequency) {
|
||||
for (j = 0; j < num_band; j++) {
|
||||
if (freqs2[j] > cutoff_frequency) {
|
||||
f1 = fpoint + freqs1[i] + freqs2[j];
|
||||
f2 = fpoint - freqs1[i] - freqs2[j];
|
||||
shift += (-1 * f1 / (f1 * f1 + epsilon * epsilon) +
|
||||
1 * f2 / (f2 * f2 + epsilon * epsilon)) *
|
||||
fc3_normal_squared[i * num_band + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return shift;
|
||||
}
|
||||
|
|
|
@ -39,25 +39,15 @@
|
|||
|
||||
#endif
|
||||
|
||||
void rse_get_real_self_energy_at_bands(double *real_self_energy,
|
||||
const Darray *fc3_normal_squared,
|
||||
const long *band_indices,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
void rse_get_real_self_energy_at_bands(
|
||||
double *real_self_energy, const Darray *fc3_normal_squared,
|
||||
const long *band_indices, const double *frequencies,
|
||||
const long (*triplets)[3], const long *triplet_weights,
|
||||
const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
void rse_get_real_self_energy_at_frequency_point(
|
||||
double *real_self_energy,
|
||||
const double frequency_point,
|
||||
const Darray *fc3_normal_squared,
|
||||
const long *band_indices,
|
||||
const double *frequencies,
|
||||
const long (*triplets)[3],
|
||||
const long *triplet_weights,
|
||||
const double epsilon,
|
||||
const double temperature,
|
||||
const double unit_conversion_factor,
|
||||
const double cutoff_frequency);
|
||||
double *real_self_energy, const double frequency_point,
|
||||
const Darray *fc3_normal_squared, const long *band_indices,
|
||||
const double *frequencies, const long (*triplets)[3],
|
||||
const long *triplet_weights, const double epsilon, const double temperature,
|
||||
const double unit_conversion_factor, const double cutoff_frequency);
|
||||
|
|
|
@ -32,337 +32,241 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "real_to_reciprocal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_array.h"
|
||||
#include "phonoc_const.h"
|
||||
#include "real_to_reciprocal.h"
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
static void
|
||||
real_to_reciprocal_single_thread(lapack_complex_double *fc3_reciprocal,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map,
|
||||
const long *s2p_map);
|
||||
static void
|
||||
real_to_reciprocal_openmp(lapack_complex_double *fc3_reciprocal,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map,
|
||||
const long *s2p_map);
|
||||
static void real_to_reciprocal_elements(lapack_complex_double *fc3_rec_elem,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s,
|
||||
const long *s2p,
|
||||
const long pi0,
|
||||
const long pi1,
|
||||
const long pi2);
|
||||
static void real_to_reciprocal_single_thread(
|
||||
lapack_complex_double *fc3_reciprocal, const double q_vecs[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const long *p2s_map, const long *s2p_map);
|
||||
static void real_to_reciprocal_openmp(
|
||||
lapack_complex_double *fc3_reciprocal, const double q_vecs[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const long *p2s_map, const long *s2p_map);
|
||||
static void real_to_reciprocal_elements(
|
||||
lapack_complex_double *fc3_rec_elem, const double q_vecs[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2], const long *p2s,
|
||||
const long *s2p, const long pi0, const long pi1, const long pi2);
|
||||
static lapack_complex_double get_phase_factor(const double q[3][3],
|
||||
const long qi,
|
||||
const double (*svecs)[3],
|
||||
const long multi[2]);
|
||||
static lapack_complex_double
|
||||
get_pre_phase_factor(const long i_patom,
|
||||
const double q_vecs[3][3],
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map);
|
||||
static lapack_complex_double get_pre_phase_factor(const long i_patom,
|
||||
const double q_vecs[3][3],
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map);
|
||||
|
||||
/* fc3_reciprocal[num_patom, num_patom, num_patom, 3, 3, 3] */
|
||||
void r2r_real_to_reciprocal(lapack_complex_double *fc3_reciprocal,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const double q_vecs[3][3], const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long openmp_at_bands)
|
||||
{
|
||||
if (openmp_at_bands)
|
||||
{
|
||||
real_to_reciprocal_openmp(fc3_reciprocal,
|
||||
q_vecs,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
p2s_map,
|
||||
s2p_map);
|
||||
}
|
||||
else
|
||||
{
|
||||
real_to_reciprocal_single_thread(fc3_reciprocal,
|
||||
q_vecs,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
p2s_map,
|
||||
s2p_map);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
real_to_reciprocal_single_thread(lapack_complex_double *fc3_reciprocal,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map,
|
||||
const long *s2p_map)
|
||||
{
|
||||
long i, j, k, l, m, n;
|
||||
long num_patom, num_band;
|
||||
lapack_complex_double pre_phase_factor, fc3_rec_elem[27];
|
||||
|
||||
num_patom = multi_dims[1];
|
||||
num_band = num_patom * 3;
|
||||
|
||||
for (i = 0; i < num_patom; i++)
|
||||
{
|
||||
pre_phase_factor = get_pre_phase_factor(
|
||||
i, q_vecs, svecs, multi_dims, multiplicity, p2s_map);
|
||||
for (j = 0; j < num_patom; j++)
|
||||
{
|
||||
for (k = 0; k < num_patom; k++)
|
||||
{
|
||||
real_to_reciprocal_elements(fc3_rec_elem,
|
||||
q_vecs,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
i, j, k);
|
||||
for (l = 0; l < 3; l++)
|
||||
{
|
||||
for (m = 0; m < 3; m++)
|
||||
{
|
||||
for (n = 0; n < 3; n++)
|
||||
{
|
||||
fc3_reciprocal[(i * 3 + l) * num_band * num_band + (j * 3 + m) * num_band + k * 3 + n] =
|
||||
phonoc_complex_prod(fc3_rec_elem[l * 9 + m * 3 + n], pre_phase_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const long (*multiplicity)[2], const long *p2s_map,
|
||||
const long *s2p_map, const long openmp_at_bands) {
|
||||
if (openmp_at_bands) {
|
||||
real_to_reciprocal_openmp(fc3_reciprocal, q_vecs, fc3, is_compact_fc3,
|
||||
svecs, multi_dims, multiplicity, p2s_map,
|
||||
s2p_map);
|
||||
} else {
|
||||
real_to_reciprocal_single_thread(fc3_reciprocal, q_vecs, fc3,
|
||||
is_compact_fc3, svecs, multi_dims,
|
||||
multiplicity, p2s_map, s2p_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
real_to_reciprocal_openmp(lapack_complex_double *fc3_reciprocal,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map,
|
||||
const long *s2p_map)
|
||||
{
|
||||
long i, j, k, l, m, n, jk;
|
||||
long num_patom, num_band;
|
||||
lapack_complex_double pre_phase_factor, fc3_rec_elem[27];
|
||||
static void real_to_reciprocal_single_thread(
|
||||
lapack_complex_double *fc3_reciprocal, const double q_vecs[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const long *p2s_map, const long *s2p_map) {
|
||||
long i, j, k, l, m, n;
|
||||
long num_patom, num_band;
|
||||
lapack_complex_double pre_phase_factor, fc3_rec_elem[27];
|
||||
|
||||
num_patom = multi_dims[1];
|
||||
num_band = num_patom * 3;
|
||||
num_patom = multi_dims[1];
|
||||
num_band = num_patom * 3;
|
||||
|
||||
for (i = 0; i < num_patom; i++)
|
||||
{
|
||||
pre_phase_factor = get_pre_phase_factor(
|
||||
i, q_vecs, svecs, multi_dims, multiplicity, p2s_map);
|
||||
for (i = 0; i < num_patom; i++) {
|
||||
pre_phase_factor = get_pre_phase_factor(i, q_vecs, svecs, multi_dims,
|
||||
multiplicity, p2s_map);
|
||||
for (j = 0; j < num_patom; j++) {
|
||||
for (k = 0; k < num_patom; k++) {
|
||||
real_to_reciprocal_elements(
|
||||
fc3_rec_elem, q_vecs, fc3, is_compact_fc3, svecs,
|
||||
multi_dims, multiplicity, p2s_map, s2p_map, i, j, k);
|
||||
for (l = 0; l < 3; l++) {
|
||||
for (m = 0; m < 3; m++) {
|
||||
for (n = 0; n < 3; n++) {
|
||||
fc3_reciprocal[(i * 3 + l) * num_band * num_band +
|
||||
(j * 3 + m) * num_band + k * 3 + n] =
|
||||
phonoc_complex_prod(
|
||||
fc3_rec_elem[l * 9 + m * 3 + n],
|
||||
pre_phase_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void real_to_reciprocal_openmp(
|
||||
lapack_complex_double *fc3_reciprocal, const double q_vecs[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2],
|
||||
const long *p2s_map, const long *s2p_map) {
|
||||
long i, j, k, l, m, n, jk;
|
||||
long num_patom, num_band;
|
||||
lapack_complex_double pre_phase_factor, fc3_rec_elem[27];
|
||||
|
||||
num_patom = multi_dims[1];
|
||||
num_band = num_patom * 3;
|
||||
|
||||
for (i = 0; i < num_patom; i++) {
|
||||
pre_phase_factor = get_pre_phase_factor(i, q_vecs, svecs, multi_dims,
|
||||
multiplicity, p2s_map);
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, k, l, m, n, fc3_rec_elem)
|
||||
#endif
|
||||
for (jk = 0; jk < num_patom * num_patom; jk++)
|
||||
{
|
||||
j = jk / num_patom;
|
||||
k = jk % num_patom;
|
||||
real_to_reciprocal_elements(fc3_rec_elem,
|
||||
q_vecs,
|
||||
fc3,
|
||||
is_compact_fc3,
|
||||
svecs,
|
||||
multi_dims,
|
||||
multiplicity,
|
||||
p2s_map,
|
||||
s2p_map,
|
||||
i, j, k);
|
||||
for (l = 0; l < 3; l++)
|
||||
{
|
||||
for (m = 0; m < 3; m++)
|
||||
{
|
||||
for (n = 0; n < 3; n++)
|
||||
{
|
||||
fc3_reciprocal[(i * 3 + l) * num_band * num_band + (j * 3 + m) * num_band + k * 3 + n] =
|
||||
phonoc_complex_prod(fc3_rec_elem[l * 9 + m * 3 + n], pre_phase_factor);
|
||||
}
|
||||
for (jk = 0; jk < num_patom * num_patom; jk++) {
|
||||
j = jk / num_patom;
|
||||
k = jk % num_patom;
|
||||
real_to_reciprocal_elements(
|
||||
fc3_rec_elem, q_vecs, fc3, is_compact_fc3, svecs, multi_dims,
|
||||
multiplicity, p2s_map, s2p_map, i, j, k);
|
||||
for (l = 0; l < 3; l++) {
|
||||
for (m = 0; m < 3; m++) {
|
||||
for (n = 0; n < 3; n++) {
|
||||
fc3_reciprocal[(i * 3 + l) * num_band * num_band +
|
||||
(j * 3 + m) * num_band + k * 3 + n] =
|
||||
phonoc_complex_prod(fc3_rec_elem[l * 9 + m * 3 + n],
|
||||
pre_phase_factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void real_to_reciprocal_elements(lapack_complex_double *fc3_rec_elem,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s,
|
||||
const long *s2p,
|
||||
const long pi0,
|
||||
const long pi1,
|
||||
const long pi2)
|
||||
{
|
||||
long i, j, k, l;
|
||||
long num_satom, adrs_shift, adrs_vec1, adrs_vec2;
|
||||
lapack_complex_double phase_factor, phase_factor1, phase_factor2;
|
||||
double fc3_rec_real[27], fc3_rec_imag[27];
|
||||
static void real_to_reciprocal_elements(
|
||||
lapack_complex_double *fc3_rec_elem, const double q_vecs[3][3],
|
||||
const double *fc3, const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2], const long (*multiplicity)[2], const long *p2s,
|
||||
const long *s2p, const long pi0, const long pi1, const long pi2) {
|
||||
long i, j, k, l;
|
||||
long num_satom, adrs_shift, adrs_vec1, adrs_vec2;
|
||||
lapack_complex_double phase_factor, phase_factor1, phase_factor2;
|
||||
double fc3_rec_real[27], fc3_rec_imag[27];
|
||||
|
||||
for (i = 0; i < 27; i++)
|
||||
{
|
||||
fc3_rec_real[i] = 0;
|
||||
fc3_rec_imag[i] = 0;
|
||||
}
|
||||
|
||||
num_satom = multi_dims[0];
|
||||
|
||||
if (is_compact_fc3)
|
||||
{
|
||||
i = pi0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = p2s[pi0];
|
||||
}
|
||||
|
||||
for (j = 0; j < num_satom; j++)
|
||||
{
|
||||
if (s2p[j] != p2s[pi1])
|
||||
{
|
||||
continue;
|
||||
for (i = 0; i < 27; i++) {
|
||||
fc3_rec_real[i] = 0;
|
||||
fc3_rec_imag[i] = 0;
|
||||
}
|
||||
|
||||
adrs_vec1 = j * multi_dims[1] + pi0;
|
||||
phase_factor1 = get_phase_factor(q_vecs,
|
||||
1,
|
||||
svecs,
|
||||
multiplicity[adrs_vec1]);
|
||||
for (k = 0; k < num_satom; k++)
|
||||
{
|
||||
if (s2p[k] != p2s[pi2])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
adrs_vec2 = k * multi_dims[1] + pi0;
|
||||
phase_factor2 = get_phase_factor(q_vecs,
|
||||
2,
|
||||
svecs,
|
||||
multiplicity[adrs_vec2]);
|
||||
adrs_shift = i * 27 * num_satom * num_satom + j * 27 * num_satom + k * 27;
|
||||
phase_factor = phonoc_complex_prod(phase_factor1, phase_factor2);
|
||||
for (l = 0; l < 27; l++)
|
||||
{
|
||||
fc3_rec_real[l] +=
|
||||
lapack_complex_double_real(phase_factor) * fc3[adrs_shift + l];
|
||||
fc3_rec_imag[l] +=
|
||||
lapack_complex_double_imag(phase_factor) * fc3[adrs_shift + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
num_satom = multi_dims[0];
|
||||
|
||||
for (i = 0; i < 27; i++)
|
||||
{
|
||||
fc3_rec_elem[i] =
|
||||
lapack_make_complex_double(fc3_rec_real[i], fc3_rec_imag[i]);
|
||||
}
|
||||
if (is_compact_fc3) {
|
||||
i = pi0;
|
||||
} else {
|
||||
i = p2s[pi0];
|
||||
}
|
||||
|
||||
for (j = 0; j < num_satom; j++) {
|
||||
if (s2p[j] != p2s[pi1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
adrs_vec1 = j * multi_dims[1] + pi0;
|
||||
phase_factor1 =
|
||||
get_phase_factor(q_vecs, 1, svecs, multiplicity[adrs_vec1]);
|
||||
for (k = 0; k < num_satom; k++) {
|
||||
if (s2p[k] != p2s[pi2]) {
|
||||
continue;
|
||||
}
|
||||
adrs_vec2 = k * multi_dims[1] + pi0;
|
||||
phase_factor2 =
|
||||
get_phase_factor(q_vecs, 2, svecs, multiplicity[adrs_vec2]);
|
||||
adrs_shift =
|
||||
i * 27 * num_satom * num_satom + j * 27 * num_satom + k * 27;
|
||||
phase_factor = phonoc_complex_prod(phase_factor1, phase_factor2);
|
||||
for (l = 0; l < 27; l++) {
|
||||
fc3_rec_real[l] += lapack_complex_double_real(phase_factor) *
|
||||
fc3[adrs_shift + l];
|
||||
fc3_rec_imag[l] += lapack_complex_double_imag(phase_factor) *
|
||||
fc3[adrs_shift + l];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 27; i++) {
|
||||
fc3_rec_elem[i] =
|
||||
lapack_make_complex_double(fc3_rec_real[i], fc3_rec_imag[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static lapack_complex_double
|
||||
get_pre_phase_factor(const long i_patom,
|
||||
const double q_vecs[3][3],
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map)
|
||||
{
|
||||
long i, j, svecs_adrs;
|
||||
double pre_phase, sum_real, sum_imag;
|
||||
lapack_complex_double pre_phase_factor;
|
||||
static lapack_complex_double get_pre_phase_factor(const long i_patom,
|
||||
const double q_vecs[3][3],
|
||||
const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map) {
|
||||
long i, j, svecs_adrs;
|
||||
double pre_phase, sum_real, sum_imag;
|
||||
lapack_complex_double pre_phase_factor;
|
||||
|
||||
svecs_adrs = p2s_map[i_patom] * multi_dims[1];
|
||||
sum_real = 0;
|
||||
sum_imag = 0;
|
||||
for (i = 0; i < multiplicity[svecs_adrs][0]; i++)
|
||||
{
|
||||
pre_phase = 0;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
pre_phase += svecs[multiplicity[svecs_adrs][1] + i][j] *
|
||||
(q_vecs[0][j] + q_vecs[1][j] + q_vecs[2][j]);
|
||||
svecs_adrs = p2s_map[i_patom] * multi_dims[1];
|
||||
sum_real = 0;
|
||||
sum_imag = 0;
|
||||
for (i = 0; i < multiplicity[svecs_adrs][0]; i++) {
|
||||
pre_phase = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
pre_phase += svecs[multiplicity[svecs_adrs][1] + i][j] *
|
||||
(q_vecs[0][j] + q_vecs[1][j] + q_vecs[2][j]);
|
||||
}
|
||||
pre_phase *= M_2PI;
|
||||
sum_real += cos(pre_phase);
|
||||
sum_imag += sin(pre_phase);
|
||||
}
|
||||
pre_phase *= M_2PI;
|
||||
sum_real += cos(pre_phase);
|
||||
sum_imag += sin(pre_phase);
|
||||
}
|
||||
|
||||
sum_real /= multiplicity[svecs_adrs][0];
|
||||
sum_imag /= multiplicity[svecs_adrs][0];
|
||||
pre_phase_factor = lapack_make_complex_double(sum_real, sum_imag);
|
||||
return pre_phase_factor;
|
||||
sum_real /= multiplicity[svecs_adrs][0];
|
||||
sum_imag /= multiplicity[svecs_adrs][0];
|
||||
pre_phase_factor = lapack_make_complex_double(sum_real, sum_imag);
|
||||
return pre_phase_factor;
|
||||
}
|
||||
|
||||
static lapack_complex_double get_phase_factor(const double q[3][3],
|
||||
const long qi,
|
||||
const double (*svecs)[3],
|
||||
const long multi[2])
|
||||
{
|
||||
long i, j;
|
||||
double sum_real, sum_imag, phase;
|
||||
const long multi[2]) {
|
||||
long i, j;
|
||||
double sum_real, sum_imag, phase;
|
||||
|
||||
sum_real = 0;
|
||||
sum_imag = 0;
|
||||
for (i = 0; i < multi[0]; i++)
|
||||
{
|
||||
phase = 0;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
phase += q[qi][j] * svecs[multi[1] + i][j];
|
||||
sum_real = 0;
|
||||
sum_imag = 0;
|
||||
for (i = 0; i < multi[0]; i++) {
|
||||
phase = 0;
|
||||
for (j = 0; j < 3; j++) {
|
||||
phase += q[qi][j] * svecs[multi[1] + i][j];
|
||||
}
|
||||
phase *= M_2PI;
|
||||
sum_real += cos(phase);
|
||||
sum_imag += sin(phase);
|
||||
}
|
||||
phase *= M_2PI;
|
||||
sum_real += cos(phase);
|
||||
sum_imag += sin(phase);
|
||||
}
|
||||
sum_real /= multi[0];
|
||||
sum_imag /= multi[0];
|
||||
sum_real /= multi[0];
|
||||
sum_imag /= multi[0];
|
||||
|
||||
return lapack_make_complex_double(sum_real, sum_imag);
|
||||
return lapack_make_complex_double(sum_real, sum_imag);
|
||||
}
|
||||
|
|
|
@ -35,17 +35,13 @@
|
|||
#ifndef __real_to_reciprocal_H__
|
||||
#define __real_to_reciprocal_H__
|
||||
|
||||
#include "phonoc_array.h"
|
||||
#include "lapack_wrapper.h"
|
||||
#include "phonoc_array.h"
|
||||
|
||||
void r2r_real_to_reciprocal(lapack_complex_double *fc3_reciprocal,
|
||||
const double q_vecs[3][3],
|
||||
const double *fc3,
|
||||
const long is_compact_fc3,
|
||||
const double (*svecs)[3],
|
||||
const double q_vecs[3][3], const double *fc3,
|
||||
const long is_compact_fc3, const double (*svecs)[3],
|
||||
const long multi_dims[2],
|
||||
const long (*multiplicity)[2],
|
||||
const long *p2s_map,
|
||||
const long *s2p_map,
|
||||
const long openmp_at_bands);
|
||||
const long (*multiplicity)[2], const long *p2s_map,
|
||||
const long *s2p_map, const long openmp_at_bands);
|
||||
#endif
|
||||
|
|
|
@ -32,14 +32,16 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "reciprocal_to_normal.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
#ifdef MEASURE_R2N
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
static double get_fc3_sum(const lapack_complex_double *e0,
|
||||
|
@ -48,144 +50,125 @@ static double get_fc3_sum(const lapack_complex_double *e0,
|
|||
const lapack_complex_double *fc3_reciprocal,
|
||||
const long num_band);
|
||||
|
||||
void reciprocal_to_normal_squared(double *fc3_normal_squared,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const lapack_complex_double *fc3_reciprocal,
|
||||
const double *freqs0,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2,
|
||||
const double *masses,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const double cutoff_frequency,
|
||||
const long openmp_at_bands)
|
||||
{
|
||||
long i, j, k, num_atom;
|
||||
double real, imag;
|
||||
double *inv_sqrt_masses;
|
||||
lapack_complex_double *e0, *e1, *e2;
|
||||
void reciprocal_to_normal_squared(
|
||||
double *fc3_normal_squared, const long (*g_pos)[4], const long num_g_pos,
|
||||
const lapack_complex_double *fc3_reciprocal, const double *freqs0,
|
||||
const double *freqs1, const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2, const double *masses,
|
||||
const long *band_indices, const long num_band,
|
||||
const double cutoff_frequency, const long openmp_at_bands) {
|
||||
long i, j, k, num_atom;
|
||||
double real, imag;
|
||||
double *inv_sqrt_masses;
|
||||
lapack_complex_double *e0, *e1, *e2;
|
||||
|
||||
/* Transpose eigenvectors for the better data alignment in memory. */
|
||||
/* Memory space for three eigenvector matrices is allocated at once */
|
||||
/* to make it contiguous. */
|
||||
e0 = (lapack_complex_double *)
|
||||
malloc(sizeof(lapack_complex_double) * 3 * num_band * num_band);
|
||||
e1 = e0 + num_band * num_band;
|
||||
e2 = e1 + num_band * num_band;
|
||||
/* Transpose eigenvectors for the better data alignment in memory. */
|
||||
/* Memory space for three eigenvector matrices is allocated at once */
|
||||
/* to make it contiguous. */
|
||||
e0 = (lapack_complex_double *)malloc(sizeof(lapack_complex_double) * 3 *
|
||||
num_band * num_band);
|
||||
e1 = e0 + num_band * num_band;
|
||||
e2 = e1 + num_band * num_band;
|
||||
|
||||
for (i = 0; i < num_band; i++)
|
||||
{
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
e0[j * num_band + i] = eigvecs0[i * num_band + j];
|
||||
e1[j * num_band + i] = eigvecs1[i * num_band + j];
|
||||
e2[j * num_band + i] = eigvecs2[i * num_band + j];
|
||||
for (i = 0; i < num_band; i++) {
|
||||
for (j = 0; j < num_band; j++) {
|
||||
e0[j * num_band + i] = eigvecs0[i * num_band + j];
|
||||
e1[j * num_band + i] = eigvecs1[i * num_band + j];
|
||||
e2[j * num_band + i] = eigvecs2[i * num_band + j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Inverse sqrt mass is multipled with eigenvectors to reduce number of */
|
||||
/* operations in get_fc3_sum. Three eigenvector matrices are looped by */
|
||||
/* first loop leveraging contiguous memory layout of [e0, e1, e2]. */
|
||||
num_atom = num_band / 3;
|
||||
inv_sqrt_masses = (double *)malloc(sizeof(double) * num_atom);
|
||||
for (i = 0; i < num_atom; i++)
|
||||
{
|
||||
inv_sqrt_masses[i] = 1.0 / sqrt(masses[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 3 * num_band; i++)
|
||||
{
|
||||
for (j = 0; j < num_atom; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
real = lapack_complex_double_real(e0[i * num_band + j * 3 + k]);
|
||||
imag = lapack_complex_double_imag(e0[i * num_band + j * 3 + k]);
|
||||
e0[i * num_band + j * 3 + k] = lapack_make_complex_double(real * inv_sqrt_masses[j], imag * inv_sqrt_masses[j]);
|
||||
}
|
||||
/* Inverse sqrt mass is multipled with eigenvectors to reduce number of */
|
||||
/* operations in get_fc3_sum. Three eigenvector matrices are looped by */
|
||||
/* first loop leveraging contiguous memory layout of [e0, e1, e2]. */
|
||||
num_atom = num_band / 3;
|
||||
inv_sqrt_masses = (double *)malloc(sizeof(double) * num_atom);
|
||||
for (i = 0; i < num_atom; i++) {
|
||||
inv_sqrt_masses[i] = 1.0 / sqrt(masses[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(inv_sqrt_masses);
|
||||
inv_sqrt_masses = NULL;
|
||||
for (i = 0; i < 3 * num_band; i++) {
|
||||
for (j = 0; j < num_atom; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
real = lapack_complex_double_real(e0[i * num_band + j * 3 + k]);
|
||||
imag = lapack_complex_double_imag(e0[i * num_band + j * 3 + k]);
|
||||
e0[i * num_band + j * 3 + k] = lapack_make_complex_double(
|
||||
real * inv_sqrt_masses[j], imag * inv_sqrt_masses[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(inv_sqrt_masses);
|
||||
inv_sqrt_masses = NULL;
|
||||
|
||||
#ifdef MEASURE_R2N
|
||||
double loopTotalCPUTime,
|
||||
loopTotalWallTime;
|
||||
time_t loopStartWallTime;
|
||||
clock_t loopStartCPUTime;
|
||||
double loopTotalCPUTime, loopTotalWallTime;
|
||||
time_t loopStartWallTime;
|
||||
clock_t loopStartCPUTime;
|
||||
#endif
|
||||
|
||||
#ifdef MEASURE_R2N
|
||||
loopStartWallTime = time(NULL);
|
||||
loopStartCPUTime = clock();
|
||||
loopStartWallTime = time(NULL);
|
||||
loopStartCPUTime = clock();
|
||||
#endif
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for if (openmp_at_bands)
|
||||
#endif
|
||||
for (i = 0; i < num_g_pos; i++)
|
||||
{
|
||||
if (freqs0[band_indices[g_pos[i][0]]] > cutoff_frequency &&
|
||||
freqs1[g_pos[i][1]] > cutoff_frequency &&
|
||||
freqs2[g_pos[i][2]] > cutoff_frequency)
|
||||
{
|
||||
fc3_normal_squared[g_pos[i][3]] =
|
||||
get_fc3_sum(e0 + band_indices[g_pos[i][0]] * num_band,
|
||||
e1 + g_pos[i][1] * num_band,
|
||||
e2 + g_pos[i][2] * num_band,
|
||||
fc3_reciprocal,
|
||||
num_band) /
|
||||
(freqs0[band_indices[g_pos[i][0]]] * freqs1[g_pos[i][1]] * freqs2[g_pos[i][2]]);
|
||||
for (i = 0; i < num_g_pos; i++) {
|
||||
if (freqs0[band_indices[g_pos[i][0]]] > cutoff_frequency &&
|
||||
freqs1[g_pos[i][1]] > cutoff_frequency &&
|
||||
freqs2[g_pos[i][2]] > cutoff_frequency) {
|
||||
fc3_normal_squared[g_pos[i][3]] =
|
||||
get_fc3_sum(e0 + band_indices[g_pos[i][0]] * num_band,
|
||||
e1 + g_pos[i][1] * num_band,
|
||||
e2 + g_pos[i][2] * num_band, fc3_reciprocal,
|
||||
num_band) /
|
||||
(freqs0[band_indices[g_pos[i][0]]] * freqs1[g_pos[i][1]] *
|
||||
freqs2[g_pos[i][2]]);
|
||||
} else {
|
||||
fc3_normal_squared[g_pos[i][3]] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fc3_normal_squared[g_pos[i][3]] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MEASURE_R2N
|
||||
loopTotalCPUTime = (double)(clock() - loopStartCPUTime) / CLOCKS_PER_SEC;
|
||||
loopTotalWallTime = difftime(time(NULL), loopStartWallTime);
|
||||
printf(" %1.3fs (%1.3fs CPU)\n", loopTotalWallTime, loopTotalCPUTime);
|
||||
loopTotalCPUTime = (double)(clock() - loopStartCPUTime) / CLOCKS_PER_SEC;
|
||||
loopTotalWallTime = difftime(time(NULL), loopStartWallTime);
|
||||
printf(" %1.3fs (%1.3fs CPU)\n", loopTotalWallTime, loopTotalCPUTime);
|
||||
#endif
|
||||
|
||||
free(e0);
|
||||
e0 = NULL;
|
||||
e1 = NULL;
|
||||
e2 = NULL;
|
||||
free(e0);
|
||||
e0 = NULL;
|
||||
e1 = NULL;
|
||||
e2 = NULL;
|
||||
}
|
||||
|
||||
static double get_fc3_sum(const lapack_complex_double *e0,
|
||||
const lapack_complex_double *e1,
|
||||
const lapack_complex_double *e2,
|
||||
const lapack_complex_double *fc3_reciprocal,
|
||||
const long num_band)
|
||||
{
|
||||
long i, j, k;
|
||||
double sum_real, sum_imag;
|
||||
lapack_complex_double e_01, e_012, e_012_fc3;
|
||||
const long num_band) {
|
||||
long i, j, k;
|
||||
double sum_real, sum_imag;
|
||||
lapack_complex_double e_01, e_012, e_012_fc3;
|
||||
|
||||
sum_real = 0;
|
||||
sum_imag = 0;
|
||||
sum_real = 0;
|
||||
sum_imag = 0;
|
||||
|
||||
for (i = 0; i < num_band; i++)
|
||||
{
|
||||
for (j = 0; j < num_band; j++)
|
||||
{
|
||||
e_01 = phonoc_complex_prod(e0[i], e1[j]);
|
||||
for (k = 0; k < num_band; k++)
|
||||
{
|
||||
e_012 = phonoc_complex_prod(e_01, e2[k]);
|
||||
e_012_fc3 = phonoc_complex_prod(e_012, fc3_reciprocal[i * num_band * num_band + j * num_band + k]);
|
||||
sum_real += lapack_complex_double_real(e_012_fc3);
|
||||
sum_imag += lapack_complex_double_imag(e_012_fc3);
|
||||
}
|
||||
for (i = 0; i < num_band; i++) {
|
||||
for (j = 0; j < num_band; j++) {
|
||||
e_01 = phonoc_complex_prod(e0[i], e1[j]);
|
||||
for (k = 0; k < num_band; k++) {
|
||||
e_012 = phonoc_complex_prod(e_01, e2[k]);
|
||||
e_012_fc3 = phonoc_complex_prod(
|
||||
e_012,
|
||||
fc3_reciprocal[i * num_band * num_band + j * num_band + k]);
|
||||
sum_real += lapack_complex_double_real(e_012_fc3);
|
||||
sum_imag += lapack_complex_double_imag(e_012_fc3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (sum_real * sum_real + sum_imag * sum_imag);
|
||||
return (sum_real * sum_real + sum_imag * sum_imag);
|
||||
}
|
||||
|
|
|
@ -37,20 +37,14 @@
|
|||
|
||||
#include "lapack_wrapper.h"
|
||||
|
||||
void reciprocal_to_normal_squared(double *fc3_normal_squared,
|
||||
const long (*g_pos)[4],
|
||||
const long num_g_pos,
|
||||
const lapack_complex_double *fc3_reciprocal,
|
||||
const double *freqs0,
|
||||
const double *freqs1,
|
||||
const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2,
|
||||
const double *masses,
|
||||
const long *band_indices,
|
||||
const long num_band,
|
||||
const double cutoff_frequency,
|
||||
const long openmp_at_bands);
|
||||
void reciprocal_to_normal_squared(
|
||||
double *fc3_normal_squared, const long (*g_pos)[4], const long num_g_pos,
|
||||
const lapack_complex_double *fc3_reciprocal, const double *freqs0,
|
||||
const double *freqs1, const double *freqs2,
|
||||
const lapack_complex_double *eigvecs0,
|
||||
const lapack_complex_double *eigvecs1,
|
||||
const lapack_complex_double *eigvecs2, const double *masses,
|
||||
const long *band_indices, const long num_band,
|
||||
const double cutoff_frequency, const long openmp_at_bands);
|
||||
|
||||
#endif
|
||||
|
|
736
c/snf3x3.c
736
c/snf3x3.c
|
@ -20,21 +20,21 @@ static void zero_second_column(long L[3][3], SNF3x3CONST long A[3][3]);
|
|||
static void second_finalize(long L[3][3], SNF3x3CONST long A[3][3]);
|
||||
static void finalize(long A[3][3], long P[3][3], long Q[3][3]);
|
||||
static void finalize_sort(long A[3][3], long P[3][3], long Q[3][3]);
|
||||
static void finalize_disturb(long A[3][3], long Q[3][3], const int i, const int j);
|
||||
static void finalize_disturb(long A[3][3], long Q[3][3], const int i,
|
||||
const int j);
|
||||
static void disturb_rows(long L[3][3], const int i, const int j);
|
||||
static void swap_diag_elems(long A[3][3], long P[3][3], long Q[3][3], const int i, const int j);
|
||||
static void swap_diag_elems(long A[3][3], long P[3][3], long Q[3][3],
|
||||
const int i, const int j);
|
||||
static void make_diagA_positive(long A[3][3], long P[3][3]);
|
||||
static void flip_PQ(long P[3][3], long Q[3][3]);
|
||||
static void swap_rows(long L[3][3], const int i, const int j);
|
||||
static void set_zero(long L[3][3],
|
||||
const int i, const int j, const long a, const long b,
|
||||
const long r, const long s, const long t);
|
||||
static void set_zero(long L[3][3], const int i, const int j, const long a,
|
||||
const long b, const long r, const long s, const long t);
|
||||
static void extended_gcd(long retvals[3], const long a, const long b);
|
||||
static void extended_gcd_step(long vals[6]);
|
||||
static void flip_sign_row(long L[3][3], const int i);
|
||||
static void transpose(long m[3][3]);
|
||||
static void matmul(long m[3][3],
|
||||
SNF3x3CONST long a[3][3],
|
||||
static void matmul(long m[3][3], SNF3x3CONST long a[3][3],
|
||||
SNF3x3CONST long b[3][3]);
|
||||
static long det(SNF3x3CONST long m[3][3]);
|
||||
|
||||
|
@ -51,487 +51,421 @@ static long det(SNF3x3CONST long m[3][3]);
|
|||
* static void test_second_one_loop(void);
|
||||
* static void test_second(void); */
|
||||
|
||||
int snf3x3(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
int i;
|
||||
initialize_PQ(P, Q);
|
||||
int snf3x3(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
int i;
|
||||
initialize_PQ(P, Q);
|
||||
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
if (first(A, P, Q))
|
||||
{
|
||||
if (second(A, P, Q))
|
||||
{
|
||||
finalize(A, P, Q);
|
||||
transpose(Q);
|
||||
goto succeeded;
|
||||
}
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (first(A, P, Q)) {
|
||||
if (second(A, P, Q)) {
|
||||
finalize(A, P, Q);
|
||||
transpose(Q);
|
||||
goto succeeded;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
succeeded:
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void initialize_PQ(long P[3][3], long Q[3][3])
|
||||
{
|
||||
int i, j;
|
||||
static void initialize_PQ(long P[3][3], long Q[3][3]) {
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
if (i == j)
|
||||
{
|
||||
P[i][j] = 1;
|
||||
Q[i][j] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
P[i][j] = 0;
|
||||
Q[i][j] = 0;
|
||||
}
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (i == j) {
|
||||
P[i][j] = 1;
|
||||
Q[i][j] = 1;
|
||||
} else {
|
||||
P[i][j] = 0;
|
||||
Q[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int first(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
long L[3][3];
|
||||
static int first(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
long L[3][3];
|
||||
|
||||
first_one_loop(A, P, Q);
|
||||
first_one_loop(A, P, Q);
|
||||
|
||||
/* rows and columns are all zero except for the pivot */
|
||||
if ((A[1][0] == 0) && (A[2][0] == 0))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
/* rows and columns are all zero except for the pivot */
|
||||
if ((A[1][0] == 0) && (A[2][0] == 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* columns of the pivot are assumed zero because of first_one_loop. */
|
||||
/* rows of the pivot are non-zero, but divisible by the pivot. */
|
||||
/* first_finalize makes the rows be zero. */
|
||||
if ((A[1][0] % A[0][0] == 0) && (A[2][0] % A[0][0] == 0))
|
||||
{
|
||||
first_finalize(L, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
/* columns of the pivot are assumed zero because of first_one_loop. */
|
||||
/* rows of the pivot are non-zero, but divisible by the pivot. */
|
||||
/* first_finalize makes the rows be zero. */
|
||||
if ((A[1][0] % A[0][0] == 0) && (A[2][0] % A[0][0] == 0)) {
|
||||
first_finalize(L, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void first_one_loop(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
first_column(A, P);
|
||||
transpose(A);
|
||||
first_column(A, Q);
|
||||
transpose(A);
|
||||
static void first_one_loop(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
first_column(A, P);
|
||||
transpose(A);
|
||||
first_column(A, Q);
|
||||
transpose(A);
|
||||
}
|
||||
|
||||
static void first_column(long A[3][3], long P[3][3])
|
||||
{
|
||||
int i;
|
||||
long L[3][3];
|
||||
static void first_column(long A[3][3], long P[3][3]) {
|
||||
int i;
|
||||
long L[3][3];
|
||||
|
||||
i = search_first_pivot(A);
|
||||
if (i > 0)
|
||||
{
|
||||
swap_rows(L, 0, i);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
if (i < 0)
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
i = search_first_pivot(A);
|
||||
if (i > 0) {
|
||||
swap_rows(L, 0, i);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
if (i < 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (A[1][0] != 0)
|
||||
{
|
||||
zero_first_column(L, 1, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
if (A[2][0] != 0)
|
||||
{
|
||||
zero_first_column(L, 2, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
if (A[1][0] != 0) {
|
||||
zero_first_column(L, 1, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
if (A[2][0] != 0) {
|
||||
zero_first_column(L, 2, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
|
||||
err:;
|
||||
}
|
||||
|
||||
static void zero_first_column(long L[3][3], const int j,
|
||||
SNF3x3CONST long A[3][3])
|
||||
{
|
||||
long vals[3];
|
||||
SNF3x3CONST long A[3][3]) {
|
||||
long vals[3];
|
||||
|
||||
extended_gcd(vals, A[0][0], A[j][0]);
|
||||
set_zero(L, 0, j, A[0][0], A[j][0], vals[0], vals[1], vals[2]);
|
||||
extended_gcd(vals, A[0][0], A[j][0]);
|
||||
set_zero(L, 0, j, A[0][0], A[j][0], vals[0], vals[1], vals[2]);
|
||||
}
|
||||
|
||||
static int search_first_pivot(SNF3x3CONST long A[3][3])
|
||||
{
|
||||
int i;
|
||||
static int search_first_pivot(SNF3x3CONST long A[3][3]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (A[i][0] != 0)
|
||||
{
|
||||
return i;
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (A[i][0] != 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void first_finalize(long L[3][3], SNF3x3CONST long A[3][3])
|
||||
{
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = -A[1][0] / A[0][0];
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = -A[2][0] / A[0][0];
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
static void first_finalize(long L[3][3], SNF3x3CONST long A[3][3]) {
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = -A[1][0] / A[0][0];
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = -A[2][0] / A[0][0];
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
}
|
||||
|
||||
static int second(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
long L[3][3];
|
||||
static int second(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
long L[3][3];
|
||||
|
||||
second_one_loop(A, P, Q);
|
||||
second_one_loop(A, P, Q);
|
||||
|
||||
if (A[2][1] == 0)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (A[2][1] == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (A[2][1] % A[1][1] == 0)
|
||||
{
|
||||
second_finalize(L, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
return 1;
|
||||
}
|
||||
if (A[2][1] % A[1][1] == 0) {
|
||||
second_finalize(L, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void second_one_loop(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
second_column(A, P);
|
||||
transpose(A);
|
||||
second_column(A, Q);
|
||||
transpose(A);
|
||||
}
|
||||
|
||||
static void second_column(long A[3][3], long P[3][3])
|
||||
{
|
||||
long L[3][3];
|
||||
|
||||
if ((A[1][1] == 0) && (A[2][1] != 0))
|
||||
{
|
||||
swap_rows(L, 1, 2);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
|
||||
if (A[2][1] != 0)
|
||||
{
|
||||
zero_second_column(L, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
}
|
||||
|
||||
static void zero_second_column(long L[3][3], SNF3x3CONST long A[3][3])
|
||||
{
|
||||
long vals[3];
|
||||
|
||||
extended_gcd(vals, A[1][1], A[2][1]);
|
||||
set_zero(L, 1, 2, A[1][1], A[2][1], vals[0], vals[1], vals[2]);
|
||||
}
|
||||
|
||||
static void second_finalize(long L[3][3], SNF3x3CONST long A[3][3])
|
||||
{
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = -A[2][1] / A[1][1];
|
||||
L[2][2] = 1;
|
||||
}
|
||||
|
||||
static void finalize(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
make_diagA_positive(A, P);
|
||||
|
||||
finalize_sort(A, P, Q);
|
||||
finalize_disturb(A, Q, 0, 1);
|
||||
first(A, P, Q);
|
||||
finalize_sort(A, P, Q);
|
||||
finalize_disturb(A, Q, 1, 2);
|
||||
second(A, P, Q);
|
||||
flip_PQ(P, Q);
|
||||
}
|
||||
|
||||
static void finalize_sort(long A[3][3], long P[3][3], long Q[3][3])
|
||||
{
|
||||
if (A[0][0] > A[1][1])
|
||||
{
|
||||
swap_diag_elems(A, P, Q, 0, 1);
|
||||
}
|
||||
if (A[1][1] > A[2][2])
|
||||
{
|
||||
swap_diag_elems(A, P, Q, 1, 2);
|
||||
}
|
||||
if (A[0][0] > A[1][1])
|
||||
{
|
||||
swap_diag_elems(A, P, Q, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void finalize_disturb(long A[3][3], long Q[3][3], const int i, const int j)
|
||||
{
|
||||
long L[3][3];
|
||||
|
||||
if (A[j][j] % A[i][i] != 0)
|
||||
{
|
||||
static void second_one_loop(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
second_column(A, P);
|
||||
transpose(A);
|
||||
disturb_rows(L, i, j);
|
||||
second_column(A, Q);
|
||||
transpose(A);
|
||||
}
|
||||
|
||||
static void second_column(long A[3][3], long P[3][3]) {
|
||||
long L[3][3];
|
||||
|
||||
if ((A[1][1] == 0) && (A[2][1] != 0)) {
|
||||
swap_rows(L, 1, 2);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
|
||||
if (A[2][1] != 0) {
|
||||
zero_second_column(L, A);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
}
|
||||
|
||||
static void zero_second_column(long L[3][3], SNF3x3CONST long A[3][3]) {
|
||||
long vals[3];
|
||||
|
||||
extended_gcd(vals, A[1][1], A[2][1]);
|
||||
set_zero(L, 1, 2, A[1][1], A[2][1], vals[0], vals[1], vals[2]);
|
||||
}
|
||||
|
||||
static void second_finalize(long L[3][3], SNF3x3CONST long A[3][3]) {
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = -A[2][1] / A[1][1];
|
||||
L[2][2] = 1;
|
||||
}
|
||||
|
||||
static void finalize(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
make_diagA_positive(A, P);
|
||||
|
||||
finalize_sort(A, P, Q);
|
||||
finalize_disturb(A, Q, 0, 1);
|
||||
first(A, P, Q);
|
||||
finalize_sort(A, P, Q);
|
||||
finalize_disturb(A, Q, 1, 2);
|
||||
second(A, P, Q);
|
||||
flip_PQ(P, Q);
|
||||
}
|
||||
|
||||
static void finalize_sort(long A[3][3], long P[3][3], long Q[3][3]) {
|
||||
if (A[0][0] > A[1][1]) {
|
||||
swap_diag_elems(A, P, Q, 0, 1);
|
||||
}
|
||||
if (A[1][1] > A[2][2]) {
|
||||
swap_diag_elems(A, P, Q, 1, 2);
|
||||
}
|
||||
if (A[0][0] > A[1][1]) {
|
||||
swap_diag_elems(A, P, Q, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void finalize_disturb(long A[3][3], long Q[3][3], const int i,
|
||||
const int j) {
|
||||
long L[3][3];
|
||||
|
||||
if (A[j][j] % A[i][i] != 0) {
|
||||
transpose(A);
|
||||
disturb_rows(L, i, j);
|
||||
matmul(A, L, A);
|
||||
matmul(Q, L, Q);
|
||||
transpose(A);
|
||||
}
|
||||
}
|
||||
|
||||
static void disturb_rows(long L[3][3], const int i, const int j) {
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[i][i] = 1;
|
||||
L[i][j] = 1;
|
||||
L[j][i] = 0;
|
||||
L[j][j] = 1;
|
||||
}
|
||||
|
||||
static void swap_diag_elems(long A[3][3], long P[3][3], long Q[3][3],
|
||||
const int i, const int j) {
|
||||
long L[3][3];
|
||||
|
||||
swap_rows(L, i, j);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
transpose(A);
|
||||
swap_rows(L, i, j);
|
||||
matmul(A, L, A);
|
||||
matmul(Q, L, Q);
|
||||
transpose(A);
|
||||
}
|
||||
}
|
||||
|
||||
static void disturb_rows(long L[3][3], const int i, const int j)
|
||||
{
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[i][i] = 1;
|
||||
L[i][j] = 1;
|
||||
L[j][i] = 0;
|
||||
L[j][j] = 1;
|
||||
}
|
||||
static void make_diagA_positive(long A[3][3], long P[3][3]) {
|
||||
int i;
|
||||
long L[3][3];
|
||||
|
||||
static void swap_diag_elems(long A[3][3], long P[3][3], long Q[3][3], const int i, const int j)
|
||||
{
|
||||
long L[3][3];
|
||||
|
||||
swap_rows(L, i, j);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
transpose(A);
|
||||
swap_rows(L, i, j);
|
||||
matmul(A, L, A);
|
||||
matmul(Q, L, Q);
|
||||
transpose(A);
|
||||
}
|
||||
|
||||
static void make_diagA_positive(long A[3][3], long P[3][3])
|
||||
{
|
||||
int i;
|
||||
long L[3][3];
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (A[i][i] < 0)
|
||||
{
|
||||
flip_sign_row(L, i);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (A[i][i] < 0) {
|
||||
flip_sign_row(L, i);
|
||||
matmul(A, L, A);
|
||||
matmul(P, L, P);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void flip_PQ(long P[3][3], long Q[3][3])
|
||||
{
|
||||
int i, j;
|
||||
static void flip_PQ(long P[3][3], long Q[3][3]) {
|
||||
int i, j;
|
||||
|
||||
if (det(P) < 0)
|
||||
{
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
P[i][j] *= -1;
|
||||
Q[i][j] *= -1;
|
||||
}
|
||||
if (det(P) < 0) {
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
P[i][j] *= -1;
|
||||
Q[i][j] *= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void swap_rows(long L[3][3], const int r1, const int r2)
|
||||
{
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[r1][r1] = 0;
|
||||
L[r2][r2] = 0;
|
||||
L[r1][r2] = 1;
|
||||
L[r2][r1] = 1;
|
||||
static void swap_rows(long L[3][3], const int r1, const int r2) {
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[r1][r1] = 0;
|
||||
L[r2][r2] = 0;
|
||||
L[r1][r2] = 1;
|
||||
L[r2][r1] = 1;
|
||||
}
|
||||
|
||||
static void set_zero(long L[3][3],
|
||||
const int i, const int j, const long a, const long b,
|
||||
const long r, const long s, const long t)
|
||||
{
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[i][i] = s;
|
||||
L[i][j] = t;
|
||||
L[j][i] = -b / r;
|
||||
L[j][j] = a / r;
|
||||
static void set_zero(long L[3][3], const int i, const int j, const long a,
|
||||
const long b, const long r, const long s, const long t) {
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[i][i] = s;
|
||||
L[i][j] = t;
|
||||
L[j][i] = -b / r;
|
||||
L[j][j] = a / r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended Euclidean algorithm
|
||||
* See https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm
|
||||
*/
|
||||
static void extended_gcd(long retvals[3], const long a, const long b)
|
||||
{
|
||||
int i;
|
||||
long vals[6];
|
||||
static void extended_gcd(long retvals[3], const long a, const long b) {
|
||||
int i;
|
||||
long vals[6];
|
||||
|
||||
vals[0] = a; /* r0 */
|
||||
vals[1] = b; /* r1 */
|
||||
vals[2] = 1; /* s0 */
|
||||
vals[3] = 0; /* s1 */
|
||||
vals[4] = 0; /* t0 */
|
||||
vals[5] = 1; /* t1 */
|
||||
vals[0] = a; /* r0 */
|
||||
vals[1] = b; /* r1 */
|
||||
vals[2] = 1; /* s0 */
|
||||
vals[3] = 0; /* s1 */
|
||||
vals[4] = 0; /* t0 */
|
||||
vals[5] = 1; /* t1 */
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
{
|
||||
extended_gcd_step(vals);
|
||||
if (vals[1] == 0)
|
||||
{
|
||||
break;
|
||||
for (i = 0; i < 1000; i++) {
|
||||
extended_gcd_step(vals);
|
||||
if (vals[1] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retvals[0] = vals[0];
|
||||
retvals[1] = vals[2];
|
||||
retvals[2] = vals[4];
|
||||
retvals[0] = vals[0];
|
||||
retvals[1] = vals[2];
|
||||
retvals[2] = vals[4];
|
||||
|
||||
assert(vals[0] == a * vals[2] + b * vals[4]);
|
||||
assert(vals[0] == a * vals[2] + b * vals[4]);
|
||||
}
|
||||
|
||||
static void extended_gcd_step(long vals[6])
|
||||
{
|
||||
long q, r2, s2, t2;
|
||||
static void extended_gcd_step(long vals[6]) {
|
||||
long q, r2, s2, t2;
|
||||
|
||||
q = vals[0] / vals[1];
|
||||
r2 = vals[0] % vals[1];
|
||||
if (r2 < 0)
|
||||
{
|
||||
if (vals[1] > 0)
|
||||
{
|
||||
r2 += vals[1];
|
||||
q -= 1;
|
||||
q = vals[0] / vals[1];
|
||||
r2 = vals[0] % vals[1];
|
||||
if (r2 < 0) {
|
||||
if (vals[1] > 0) {
|
||||
r2 += vals[1];
|
||||
q -= 1;
|
||||
}
|
||||
if (vals[1] < 0) {
|
||||
r2 -= vals[1];
|
||||
q += 1;
|
||||
}
|
||||
}
|
||||
if (vals[1] < 0)
|
||||
{
|
||||
r2 -= vals[1];
|
||||
q += 1;
|
||||
}
|
||||
}
|
||||
s2 = vals[2] - q * vals[3];
|
||||
t2 = vals[4] - q * vals[5];
|
||||
vals[0] = vals[1];
|
||||
vals[1] = r2;
|
||||
vals[2] = vals[3];
|
||||
vals[3] = s2;
|
||||
vals[4] = vals[5];
|
||||
vals[5] = t2;
|
||||
s2 = vals[2] - q * vals[3];
|
||||
t2 = vals[4] - q * vals[5];
|
||||
vals[0] = vals[1];
|
||||
vals[1] = r2;
|
||||
vals[2] = vals[3];
|
||||
vals[3] = s2;
|
||||
vals[4] = vals[5];
|
||||
vals[5] = t2;
|
||||
}
|
||||
|
||||
static void flip_sign_row(long L[3][3], const int i)
|
||||
{
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[i][i] = -1;
|
||||
static void flip_sign_row(long L[3][3], const int i) {
|
||||
L[0][0] = 1;
|
||||
L[0][1] = 0;
|
||||
L[0][2] = 0;
|
||||
L[1][0] = 0;
|
||||
L[1][1] = 1;
|
||||
L[1][2] = 0;
|
||||
L[2][0] = 0;
|
||||
L[2][1] = 0;
|
||||
L[2][2] = 1;
|
||||
L[i][i] = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrix operation utils
|
||||
*/
|
||||
static void transpose(long m[3][3])
|
||||
{
|
||||
long tmp;
|
||||
int i, j;
|
||||
static void transpose(long m[3][3]) {
|
||||
long tmp;
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = i; j < 3; j++)
|
||||
{
|
||||
tmp = m[i][j];
|
||||
m[i][j] = m[j][i];
|
||||
m[j][i] = tmp;
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = i; j < 3; j++) {
|
||||
tmp = m[i][j];
|
||||
m[i][j] = m[j][i];
|
||||
m[j][i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void matmul(long m[3][3],
|
||||
SNF3x3CONST long a[3][3],
|
||||
SNF3x3CONST long b[3][3])
|
||||
{
|
||||
int i, j;
|
||||
long c[3][3];
|
||||
static void matmul(long m[3][3], SNF3x3CONST long a[3][3],
|
||||
SNF3x3CONST long b[3][3]) {
|
||||
int i, j;
|
||||
long c[3][3];
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
m[i][j] = c[i][j];
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
m[i][j] = c[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static long det(SNF3x3CONST long m[3][3])
|
||||
{
|
||||
return m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) + m[0][1] * (m[1][2] * m[2][0] - m[1][0] * m[2][2]) + m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
|
||||
static long det(SNF3x3CONST long m[3][3]) {
|
||||
return m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) +
|
||||
m[0][1] * (m[1][2] * m[2][0] - m[1][0] * m[2][2]) +
|
||||
m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
|
||||
}
|
||||
|
||||
/* int main()
|
||||
|
|
|
@ -9,7 +9,7 @@ extern "C" {
|
|||
#define SNF3X3_MINOR_VERSION 1
|
||||
#define SNF3X3_MICRO_VERSION 0
|
||||
|
||||
int snf3x3(long A[3][3], long P[3][3], long Q[3][3]);
|
||||
int snf3x3(long A[3][3], long P[3][3], long Q[3][3]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
242
c/triplet.c
242
c/triplet.c
|
@ -34,181 +34,121 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "bzgrid.h"
|
||||
#include "triplet.h"
|
||||
#include "triplet_iw.h"
|
||||
|
||||
#include "bzgrid.h"
|
||||
#include "triplet_grid.h"
|
||||
#include "triplet_iw.h"
|
||||
|
||||
long tpl_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
long tpl_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets)
|
||||
{
|
||||
return tpk_get_BZ_triplets_at_q(triplets,
|
||||
grid_point,
|
||||
bzgrid,
|
||||
map_triplets);
|
||||
const long *map_triplets) {
|
||||
return tpk_get_BZ_triplets_at_q(triplets, grid_point, bzgrid, map_triplets);
|
||||
}
|
||||
|
||||
long tpl_get_triplets_reciprocal_mesh_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long mesh[3],
|
||||
const long is_time_reversal,
|
||||
const long num_rot,
|
||||
const long (*rec_rotations)[3][3],
|
||||
const long swappable)
|
||||
{
|
||||
long num_ir;
|
||||
long tpl_get_triplets_reciprocal_mesh_at_q(
|
||||
long *map_triplets, long *map_q, const long grid_point, const long mesh[3],
|
||||
const long is_time_reversal, const long num_rot,
|
||||
const long (*rec_rotations)[3][3], const long swappable) {
|
||||
long num_ir;
|
||||
|
||||
num_ir = tpk_get_ir_triplets_at_q(map_triplets,
|
||||
map_q,
|
||||
grid_point,
|
||||
mesh,
|
||||
is_time_reversal,
|
||||
rec_rotations,
|
||||
num_rot,
|
||||
swappable);
|
||||
return num_ir;
|
||||
num_ir = tpk_get_ir_triplets_at_q(map_triplets, map_q, grid_point, mesh,
|
||||
is_time_reversal, rec_rotations, num_rot,
|
||||
swappable);
|
||||
return num_ir;
|
||||
}
|
||||
|
||||
void tpl_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_triplets,
|
||||
const long openmp_per_bands)
|
||||
{
|
||||
long i, num_band_prod;
|
||||
long tp_relative_grid_address[2][24][4][3];
|
||||
void tpl_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long relative_grid_address[24][4][3],
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const ConstBZGrid *bzgrid, const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_triplets, const long openmp_per_bands) {
|
||||
long i, num_band_prod;
|
||||
long tp_relative_grid_address[2][24][4][3];
|
||||
|
||||
tpl_set_relative_grid_address(tp_relative_grid_address,
|
||||
relative_grid_address,
|
||||
tp_type);
|
||||
num_band_prod = num_band0 * num_band1 * num_band2;
|
||||
tpl_set_relative_grid_address(tp_relative_grid_address,
|
||||
relative_grid_address, tp_type);
|
||||
num_band_prod = num_band0 * num_band1 * num_band2;
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for if (openmp_per_triplets)
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
tpi_get_integration_weight(iw + i * num_band_prod,
|
||||
iw_zero + i * num_band_prod,
|
||||
frequency_points, /* f0 */
|
||||
num_band0,
|
||||
tp_relative_grid_address,
|
||||
triplets[i],
|
||||
num_triplets,
|
||||
bzgrid,
|
||||
frequencies1, /* f1 */
|
||||
num_band1,
|
||||
frequencies2, /* f2 */
|
||||
num_band2,
|
||||
tp_type,
|
||||
openmp_per_bands);
|
||||
}
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
tpi_get_integration_weight(
|
||||
iw + i * num_band_prod, iw_zero + i * num_band_prod,
|
||||
frequency_points, /* f0 */
|
||||
num_band0, tp_relative_grid_address, triplets[i], num_triplets,
|
||||
bzgrid, frequencies1, /* f1 */
|
||||
num_band1, frequencies2, /* f2 */
|
||||
num_band2, tp_type, openmp_per_bands);
|
||||
}
|
||||
}
|
||||
|
||||
void tpl_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type)
|
||||
{
|
||||
long i, num_band_prod, const_adrs_shift;
|
||||
double cutoff;
|
||||
void tpl_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double sigma_cutoff,
|
||||
const double *frequency_points, const long num_band0,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const double *frequencies, const long num_band, const long tp_type) {
|
||||
long i, num_band_prod, const_adrs_shift;
|
||||
double cutoff;
|
||||
|
||||
cutoff = sigma * sigma_cutoff;
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
const_adrs_shift = num_triplets * num_band0 * num_band * num_band;
|
||||
cutoff = sigma * sigma_cutoff;
|
||||
num_band_prod = num_band0 * num_band * num_band;
|
||||
const_adrs_shift = num_triplets * num_band0 * num_band * num_band;
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (i = 0; i < num_triplets; i++)
|
||||
{
|
||||
tpi_get_integration_weight_with_sigma(
|
||||
iw + i * num_band_prod,
|
||||
iw_zero + i * num_band_prod,
|
||||
sigma,
|
||||
cutoff,
|
||||
frequency_points,
|
||||
num_band0,
|
||||
triplets[i],
|
||||
const_adrs_shift,
|
||||
frequencies,
|
||||
num_band,
|
||||
tp_type,
|
||||
0);
|
||||
}
|
||||
for (i = 0; i < num_triplets; i++) {
|
||||
tpi_get_integration_weight_with_sigma(
|
||||
iw + i * num_band_prod, iw_zero + i * num_band_prod, sigma, cutoff,
|
||||
frequency_points, num_band0, triplets[i], const_adrs_shift,
|
||||
frequencies, num_band, tp_type, 0);
|
||||
}
|
||||
}
|
||||
|
||||
long tpl_is_N(const long triplet[3], const long (*bz_grid_addresses)[3])
|
||||
{
|
||||
long i, j, sum_q, is_N;
|
||||
long tpl_is_N(const long triplet[3], const long (*bz_grid_addresses)[3]) {
|
||||
long i, j, sum_q, is_N;
|
||||
|
||||
is_N = 1;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
sum_q = 0;
|
||||
for (j = 0; j < 3; j++)
|
||||
{ /* 1st, 2nd, 3rd triplet */
|
||||
sum_q += bz_grid_addresses[triplet[j]][i];
|
||||
}
|
||||
if (sum_q)
|
||||
{
|
||||
is_N = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return is_N;
|
||||
}
|
||||
|
||||
void tpl_set_relative_grid_address(
|
||||
long tp_relative_grid_address[2][24][4][3],
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long tp_type)
|
||||
{
|
||||
long i, j, k, l;
|
||||
long signs[2];
|
||||
|
||||
signs[0] = 1;
|
||||
signs[1] = 1;
|
||||
if ((tp_type == 2) || (tp_type == 3))
|
||||
{
|
||||
/* q1+q2+q3=G */
|
||||
/* To set q2+1, q3-1 is needed to keep G */
|
||||
signs[1] = -1;
|
||||
}
|
||||
/* tp_type == 4, q+k_i-k_f=G */
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 24; j++)
|
||||
{
|
||||
for (k = 0; k < 4; k++)
|
||||
{
|
||||
for (l = 0; l < 3; l++)
|
||||
{
|
||||
tp_relative_grid_address[i][j][k][l] =
|
||||
relative_grid_address[j][k][l] * signs[i];
|
||||
is_N = 1;
|
||||
for (i = 0; i < 3; i++) {
|
||||
sum_q = 0;
|
||||
for (j = 0; j < 3; j++) { /* 1st, 2nd, 3rd triplet */
|
||||
sum_q += bz_grid_addresses[triplet[j]][i];
|
||||
}
|
||||
if (sum_q) {
|
||||
is_N = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return is_N;
|
||||
}
|
||||
|
||||
void tpl_set_relative_grid_address(long tp_relative_grid_address[2][24][4][3],
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long tp_type) {
|
||||
long i, j, k, l;
|
||||
long signs[2];
|
||||
|
||||
signs[0] = 1;
|
||||
signs[1] = 1;
|
||||
if ((tp_type == 2) || (tp_type == 3)) {
|
||||
/* q1+q2+q3=G */
|
||||
/* To set q2+1, q3-1 is needed to keep G */
|
||||
signs[1] = -1;
|
||||
}
|
||||
/* tp_type == 4, q+k_i-k_f=G */
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 24; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
for (l = 0; l < 3; l++) {
|
||||
tp_relative_grid_address[i][j][k][l] =
|
||||
relative_grid_address[j][k][l] * signs[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
61
c/triplet.h
61
c/triplet.h
|
@ -38,6 +38,7 @@
|
|||
#define __triplet_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "bzgrid.h"
|
||||
|
||||
/* Irreducible triplets of k-points are searched under conservation of */
|
||||
|
@ -46,55 +47,35 @@
|
|||
/* and map_q[prod(mesh)] are required. rotations are point-group- */
|
||||
/* operations in real space for which duplicate operations are allowed */
|
||||
/* in the input. */
|
||||
long tpl_get_triplets_reciprocal_mesh_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long mesh[3],
|
||||
const long is_time_reversal,
|
||||
const long num_rot,
|
||||
const long (*rec_rotations)[3][3],
|
||||
const long swappable);
|
||||
long tpl_get_triplets_reciprocal_mesh_at_q(
|
||||
long *map_triplets, long *map_q, const long grid_point, const long mesh[3],
|
||||
const long is_time_reversal, const long num_rot,
|
||||
const long (*rec_rotations)[3][3], const long swappable);
|
||||
/* Irreducible grid-point-triplets in BZ are stored. */
|
||||
/* triplets are recovered from grid_point and triplet_weights. */
|
||||
/* BZ boundary is considered in this recovery. Therefore grid addresses */
|
||||
/* are given not by grid_address, but by bz_grid_address. */
|
||||
/* triplets[num_ir_triplets][3] = number of non-zero triplets weights*/
|
||||
/* Number of ir-triplets is returned. */
|
||||
long tpl_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
long tpl_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets);
|
||||
void tpl_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_triplets,
|
||||
const long openmp_per_bands);
|
||||
void tpl_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double sigma_cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long (*triplets)[3],
|
||||
const long num_triplets,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type);
|
||||
void tpl_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long relative_grid_address[24][4][3],
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const ConstBZGrid *bzgrid, const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_triplets, const long openmp_per_bands);
|
||||
void tpl_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double sigma_cutoff,
|
||||
const double *frequency_points, const long num_band0,
|
||||
const long (*triplets)[3], const long num_triplets,
|
||||
const double *frequencies, const long num_band, const long tp_type);
|
||||
|
||||
long tpl_is_N(const long triplet[3], const long (*bz_grid_addresses)[3]);
|
||||
void tpl_set_relative_grid_address(
|
||||
long tp_relative_grid_address[2][24][4][3],
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long tp_type);
|
||||
void tpl_set_relative_grid_address(long tp_relative_grid_address[2][24][4][3],
|
||||
const long relative_grid_address[24][4][3],
|
||||
const long tp_type);
|
||||
|
||||
#endif
|
||||
|
|
819
c/triplet_grid.c
819
c/triplet_grid.c
|
@ -34,33 +34,28 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "triplet_grid.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bzgrid.h"
|
||||
#include "grgrid.h"
|
||||
#include "lagrid.h"
|
||||
#include "triplet.h"
|
||||
#include "triplet_grid.h"
|
||||
|
||||
static long get_ir_triplets_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
static long get_ir_triplets_at_q(long *map_triplets, long *map_q,
|
||||
const long grid_point, const long D_diag[3],
|
||||
const RotMats *rot_reciprocal,
|
||||
const long swappable);
|
||||
static long get_ir_triplets_at_q_perm_q1q2(long *map_triplets,
|
||||
const long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const RotMats *rot_reciprocal_q,
|
||||
const long num_ir_q);
|
||||
static long get_ir_triplets_at_q_noperm(long *map_triplets,
|
||||
const long *map_q,
|
||||
const long D_diag[3]);
|
||||
static long get_ir_triplets_at_q_noperm(long *map_triplets, const long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const RotMats *rot_reciprocal_q);
|
||||
static long get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
const long D_diag[3]);
|
||||
static long get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets);
|
||||
static void get_BZ_triplets_at_q_type1(long (*triplets)[3],
|
||||
|
@ -73,8 +68,7 @@ static void get_BZ_triplets_at_q_type2(long (*triplets)[3],
|
|||
const ConstBZGrid *bzgrid,
|
||||
const long *ir_q1_gps,
|
||||
const long num_ir);
|
||||
static double get_squared_distance(const long G[3],
|
||||
const double LQD_inv[3][3]);
|
||||
static double get_squared_distance(const long G[3], const double LQD_inv[3][3]);
|
||||
static void get_LQD_inv(double LQD_inv[3][3], const ConstBZGrid *bzgrid);
|
||||
static RotMats *get_reciprocal_point_group_with_q(const RotMats *rot_reciprocal,
|
||||
const long D_diag[3],
|
||||
|
@ -84,569 +78,424 @@ static RotMats *get_reciprocal_point_group(const long (*rec_rotations_in)[3][3],
|
|||
const long is_time_reversal,
|
||||
const long is_transpose);
|
||||
|
||||
long tpk_get_ir_triplets_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
long tpk_get_ir_triplets_at_q(long *map_triplets, long *map_q,
|
||||
const long grid_point, const long D_diag[3],
|
||||
const long is_time_reversal,
|
||||
const long (*rec_rotations_in)[3][3],
|
||||
const long num_rot,
|
||||
const long swappable)
|
||||
{
|
||||
long num_ir;
|
||||
RotMats *rotations;
|
||||
const long num_rot, const long swappable) {
|
||||
long num_ir;
|
||||
RotMats *rotations;
|
||||
|
||||
rotations = get_reciprocal_point_group(rec_rotations_in,
|
||||
num_rot,
|
||||
is_time_reversal,
|
||||
0);
|
||||
if (rotations == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
num_ir = get_ir_triplets_at_q(map_triplets,
|
||||
map_q,
|
||||
grid_point,
|
||||
D_diag,
|
||||
rotations,
|
||||
swappable);
|
||||
bzg_free_RotMats(rotations);
|
||||
rotations = NULL;
|
||||
|
||||
return num_ir;
|
||||
}
|
||||
|
||||
long tpk_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets)
|
||||
{
|
||||
return get_BZ_triplets_at_q(triplets,
|
||||
grid_point,
|
||||
bzgrid,
|
||||
map_triplets);
|
||||
}
|
||||
|
||||
static long get_ir_triplets_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const RotMats *rot_reciprocal,
|
||||
const long swappable)
|
||||
{
|
||||
long i, num_ir_q, num_ir_triplets;
|
||||
long PS[3];
|
||||
RotMats *rot_reciprocal_q;
|
||||
|
||||
rot_reciprocal_q = NULL;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
PS[i] = 0;
|
||||
}
|
||||
|
||||
/* Search irreducible q-points (map_q) with a stabilizer. */
|
||||
rot_reciprocal_q = get_reciprocal_point_group_with_q(rot_reciprocal,
|
||||
D_diag,
|
||||
grid_point);
|
||||
|
||||
grg_get_ir_grid_map(map_q,
|
||||
rot_reciprocal_q->mat,
|
||||
rot_reciprocal_q->size,
|
||||
D_diag,
|
||||
PS);
|
||||
num_ir_q = 0;
|
||||
for (i = 0; i < D_diag[0] * D_diag[1] * D_diag[2]; i++)
|
||||
{
|
||||
if (map_q[i] == i)
|
||||
{
|
||||
num_ir_q++;
|
||||
rotations = get_reciprocal_point_group(rec_rotations_in, num_rot,
|
||||
is_time_reversal, 0);
|
||||
if (rotations == NULL) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (swappable)
|
||||
{
|
||||
num_ir_triplets = get_ir_triplets_at_q_perm_q1q2(map_triplets,
|
||||
map_q,
|
||||
grid_point,
|
||||
D_diag,
|
||||
rot_reciprocal_q,
|
||||
num_ir_q);
|
||||
}
|
||||
else
|
||||
{
|
||||
num_ir_triplets = get_ir_triplets_at_q_noperm(map_triplets,
|
||||
map_q,
|
||||
grid_point,
|
||||
D_diag,
|
||||
rot_reciprocal_q);
|
||||
}
|
||||
num_ir = get_ir_triplets_at_q(map_triplets, map_q, grid_point, D_diag,
|
||||
rotations, swappable);
|
||||
bzg_free_RotMats(rotations);
|
||||
rotations = NULL;
|
||||
|
||||
bzg_free_RotMats(rot_reciprocal_q);
|
||||
rot_reciprocal_q = NULL;
|
||||
return num_ir;
|
||||
}
|
||||
|
||||
return num_ir_triplets;
|
||||
long tpk_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets) {
|
||||
return get_BZ_triplets_at_q(triplets, grid_point, bzgrid, map_triplets);
|
||||
}
|
||||
|
||||
static long get_ir_triplets_at_q(long *map_triplets, long *map_q,
|
||||
const long grid_point, const long D_diag[3],
|
||||
const RotMats *rot_reciprocal,
|
||||
const long swappable) {
|
||||
long i, num_ir_q, num_ir_triplets;
|
||||
long PS[3];
|
||||
RotMats *rot_reciprocal_q;
|
||||
|
||||
rot_reciprocal_q = NULL;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
PS[i] = 0;
|
||||
}
|
||||
|
||||
/* Search irreducible q-points (map_q) with a stabilizer. */
|
||||
rot_reciprocal_q =
|
||||
get_reciprocal_point_group_with_q(rot_reciprocal, D_diag, grid_point);
|
||||
|
||||
grg_get_ir_grid_map(map_q, rot_reciprocal_q->mat, rot_reciprocal_q->size,
|
||||
D_diag, PS);
|
||||
num_ir_q = 0;
|
||||
for (i = 0; i < D_diag[0] * D_diag[1] * D_diag[2]; i++) {
|
||||
if (map_q[i] == i) {
|
||||
num_ir_q++;
|
||||
}
|
||||
}
|
||||
|
||||
if (swappable) {
|
||||
num_ir_triplets = get_ir_triplets_at_q_perm_q1q2(map_triplets, map_q,
|
||||
grid_point, D_diag);
|
||||
} else {
|
||||
num_ir_triplets = get_ir_triplets_at_q_noperm(map_triplets, map_q,
|
||||
grid_point, D_diag);
|
||||
}
|
||||
|
||||
bzg_free_RotMats(rot_reciprocal_q);
|
||||
rot_reciprocal_q = NULL;
|
||||
|
||||
return num_ir_triplets;
|
||||
}
|
||||
|
||||
static long get_ir_triplets_at_q_perm_q1q2(long *map_triplets,
|
||||
const long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const RotMats *rot_reciprocal_q,
|
||||
const long num_ir_q)
|
||||
{
|
||||
long i, j, num_grid, num_ir_triplets, ir_gp, count;
|
||||
long adrs0[3], adrs1[3], adrs2[3];
|
||||
long *ir_gps_at_q, *q_2;
|
||||
const long D_diag[3]) {
|
||||
long j, num_grid, num_ir_triplets, gp1, gp2;
|
||||
long adrs0[3], adrs1[3], adrs2[3];
|
||||
|
||||
ir_gps_at_q = NULL;
|
||||
q_2 = NULL;
|
||||
num_ir_triplets = 0;
|
||||
num_ir_triplets = 0;
|
||||
num_grid = D_diag[0] * D_diag[1] * D_diag[2];
|
||||
grg_get_grid_address_from_index(adrs0, grid_point, D_diag);
|
||||
|
||||
num_grid = D_diag[0] * D_diag[1] * D_diag[2];
|
||||
|
||||
if ((q_2 = (long *)malloc(sizeof(long) * num_ir_q)) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
if ((ir_gps_at_q = (long *)malloc(sizeof(long) * num_ir_q)) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
for (i = 0; i < num_grid; i++)
|
||||
{
|
||||
if (map_q[i] == i)
|
||||
{
|
||||
ir_gps_at_q[count] = i;
|
||||
count++;
|
||||
// #ifdef PHPYOPENMP
|
||||
// #pragma omp parallel for private(j, gp2, adrs1, adrs2)
|
||||
// #endif
|
||||
for (gp1 = 0; gp1 < num_grid; gp1++) {
|
||||
if (map_q[gp1] == gp1) {
|
||||
grg_get_grid_address_from_index(adrs1, gp1, D_diag);
|
||||
for (j = 0; j < 3; j++) {
|
||||
adrs2[j] = -adrs0[j] - adrs1[j];
|
||||
}
|
||||
/* If map_q[gp2] is smaller than current gp1, map_q[gp2] should */
|
||||
/* equal to a previous gp1 for which map_triplets is already */
|
||||
/* filled. So the counter is not incremented. */
|
||||
gp2 = grg_get_grid_index(adrs2, D_diag);
|
||||
if (map_q[gp2] < gp1) {
|
||||
map_triplets[gp1] = map_q[gp2];
|
||||
} else {
|
||||
map_triplets[gp1] = gp1;
|
||||
num_ir_triplets++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
grg_get_grid_address_from_index(adrs0, grid_point, D_diag);
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, adrs1, adrs2)
|
||||
#endif
|
||||
for (i = 0; i < num_ir_q; i++)
|
||||
{
|
||||
grg_get_grid_address_from_index(adrs1, ir_gps_at_q[i], D_diag);
|
||||
for (j = 0; j < 3; j++)
|
||||
{ /* q'' */
|
||||
adrs2[j] = -adrs0[j] - adrs1[j];
|
||||
}
|
||||
q_2[i] = grg_get_grid_index(adrs2, D_diag);
|
||||
}
|
||||
|
||||
/* map_q[q_2[i]] is in ir_gps_at_q. */
|
||||
/* If map_q[q_2[i]] < ir_gps_at_q[i], this should be already */
|
||||
/* stored. So the counter is not incremented. */
|
||||
for (i = 0; i < num_ir_q; i++)
|
||||
{
|
||||
ir_gp = ir_gps_at_q[i];
|
||||
if (map_q[q_2[i]] < ir_gp)
|
||||
{
|
||||
map_triplets[ir_gp] = map_q[q_2[i]];
|
||||
}
|
||||
else
|
||||
{
|
||||
map_triplets[ir_gp] = ir_gp;
|
||||
num_ir_triplets++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill unfilled elements of map_triplets. */
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (i = 0; i < num_grid; i++)
|
||||
{
|
||||
map_triplets[i] = map_triplets[map_q[i]];
|
||||
}
|
||||
for (gp1 = 0; gp1 < num_grid; gp1++) {
|
||||
if (map_q[gp1] != gp1) {
|
||||
/* map_q[gp1] is one of ir-gp1, so it is already filled. */
|
||||
map_triplets[gp1] = map_triplets[map_q[gp1]];
|
||||
}
|
||||
}
|
||||
|
||||
ret:
|
||||
if (q_2)
|
||||
{
|
||||
free(q_2);
|
||||
q_2 = NULL;
|
||||
}
|
||||
if (ir_gps_at_q)
|
||||
{
|
||||
free(ir_gps_at_q);
|
||||
ir_gps_at_q = NULL;
|
||||
}
|
||||
return num_ir_triplets;
|
||||
return num_ir_triplets;
|
||||
}
|
||||
|
||||
static long get_ir_triplets_at_q_noperm(long *map_triplets,
|
||||
const long *map_q,
|
||||
static long get_ir_triplets_at_q_noperm(long *map_triplets, const long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
const RotMats *rot_reciprocal_q)
|
||||
{
|
||||
long i, num_grid, num_ir_triplets;
|
||||
const long D_diag[3]) {
|
||||
long gp1, num_grid, num_ir_triplets;
|
||||
|
||||
num_ir_triplets = 0;
|
||||
num_grid = D_diag[0] * D_diag[1] * D_diag[2];
|
||||
num_ir_triplets = 0;
|
||||
num_grid = D_diag[0] * D_diag[1] * D_diag[2];
|
||||
|
||||
for (i = 0; i < num_grid; i++)
|
||||
{
|
||||
if (map_q[i] == i)
|
||||
{
|
||||
map_triplets[i] = i;
|
||||
num_ir_triplets++;
|
||||
for (gp1 = 0; gp1 < num_grid; gp1++) {
|
||||
if (map_q[gp1] == gp1) {
|
||||
map_triplets[gp1] = gp1;
|
||||
num_ir_triplets++;
|
||||
} else {
|
||||
map_triplets[gp1] = map_triplets[map_q[gp1]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
map_triplets[i] = map_triplets[map_q[i]];
|
||||
}
|
||||
}
|
||||
|
||||
return num_ir_triplets;
|
||||
return num_ir_triplets;
|
||||
}
|
||||
|
||||
static long get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
static long get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets)
|
||||
{
|
||||
long i, num_ir;
|
||||
long *ir_q1_gps;
|
||||
const long *map_triplets) {
|
||||
long gp1, num_ir;
|
||||
long *ir_q1_gps;
|
||||
|
||||
ir_q1_gps = NULL;
|
||||
num_ir = 0;
|
||||
ir_q1_gps = NULL;
|
||||
num_ir = 0;
|
||||
|
||||
if ((ir_q1_gps = (long *)malloc(sizeof(long) * bzgrid->size)) == NULL)
|
||||
{
|
||||
warning_print("Memory could not be allocated.");
|
||||
goto ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < bzgrid->size; i++)
|
||||
{
|
||||
if (map_triplets[i] == i)
|
||||
{
|
||||
ir_q1_gps[num_ir] = i;
|
||||
num_ir++;
|
||||
if ((ir_q1_gps = (long *)malloc(sizeof(long) * bzgrid->size)) == NULL) {
|
||||
warning_print("Memory could not be allocated.");
|
||||
goto ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (bzgrid->type == 1)
|
||||
{
|
||||
get_BZ_triplets_at_q_type1(triplets,
|
||||
grid_point,
|
||||
bzgrid,
|
||||
ir_q1_gps,
|
||||
num_ir);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_BZ_triplets_at_q_type2(triplets,
|
||||
grid_point,
|
||||
bzgrid,
|
||||
ir_q1_gps,
|
||||
num_ir);
|
||||
}
|
||||
for (gp1 = 0; gp1 < bzgrid->size; gp1++) {
|
||||
if (map_triplets[gp1] == gp1) {
|
||||
ir_q1_gps[num_ir] = gp1;
|
||||
num_ir++;
|
||||
}
|
||||
}
|
||||
|
||||
free(ir_q1_gps);
|
||||
ir_q1_gps = NULL;
|
||||
if (bzgrid->type == 1) {
|
||||
get_BZ_triplets_at_q_type1(triplets, grid_point, bzgrid, ir_q1_gps,
|
||||
num_ir);
|
||||
} else {
|
||||
get_BZ_triplets_at_q_type2(triplets, grid_point, bzgrid, ir_q1_gps,
|
||||
num_ir);
|
||||
}
|
||||
|
||||
free(ir_q1_gps);
|
||||
ir_q1_gps = NULL;
|
||||
|
||||
ret:
|
||||
return num_ir;
|
||||
return num_ir;
|
||||
}
|
||||
|
||||
static void get_BZ_triplets_at_q_type1(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *ir_q1_gps,
|
||||
const long num_ir)
|
||||
{
|
||||
long i, j, gp2, num_gp, num_bzgp, bz0, bz1, bz2;
|
||||
long bzgp[3], G[3];
|
||||
long bz_adrs0[3], bz_adrs1[3], bz_adrs2[3];
|
||||
const long *gp_map;
|
||||
const long(*bz_adrs)[3];
|
||||
double d2, min_d2, tolerance;
|
||||
double LQD_inv[3][3];
|
||||
const long num_ir) {
|
||||
long i, j, gp2, num_gp, num_bzgp, bz0, bz1, bz2;
|
||||
long bzgp[3], G[3];
|
||||
long bz_adrs0[3], bz_adrs1[3], bz_adrs2[3];
|
||||
const long *gp_map;
|
||||
const long(*bz_adrs)[3];
|
||||
double d2, min_d2, tolerance;
|
||||
double LQD_inv[3][3];
|
||||
|
||||
gp_map = bzgrid->gp_map;
|
||||
bz_adrs = bzgrid->addresses;
|
||||
get_LQD_inv(LQD_inv, bzgrid);
|
||||
/* This tolerance is used to be consistent to BZ reduction in bzgrid. */
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction((BZGrid *)bzgrid);
|
||||
gp_map = bzgrid->gp_map;
|
||||
bz_adrs = bzgrid->addresses;
|
||||
get_LQD_inv(LQD_inv, bzgrid);
|
||||
/* This tolerance is used to be consistent to BZ reduction in bzgrid. */
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction((BZGrid *)bzgrid);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
bz_adrs0[i] = bz_adrs[grid_point][i];
|
||||
}
|
||||
num_gp = bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
num_bzgp = num_gp * 8;
|
||||
for (i = 0; i < 3; i++) {
|
||||
bz_adrs0[i] = bz_adrs[grid_point][i];
|
||||
}
|
||||
num_gp = bzgrid->D_diag[0] * bzgrid->D_diag[1] * bzgrid->D_diag[2];
|
||||
num_bzgp = num_gp * 8;
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, gp2, bzgp, G, bz_adrs1, bz_adrs2, d2, min_d2, bz0, bz1, bz2)
|
||||
#pragma omp parallel for private(j, gp2, bzgp, G, bz_adrs1, bz_adrs2, d2, \
|
||||
min_d2, bz0, bz1, bz2)
|
||||
#endif
|
||||
for (i = 0; i < num_ir; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bz_adrs1[j] = bz_adrs[ir_q1_gps[i]][j];
|
||||
bz_adrs2[j] = -bz_adrs0[j] - bz_adrs1[j];
|
||||
}
|
||||
gp2 = grg_get_grid_index(bz_adrs2, bzgrid->D_diag);
|
||||
/* Negative value is the signal to initialize min_d2 later. */
|
||||
min_d2 = -1;
|
||||
for (bz0 = 0;
|
||||
bz0 < gp_map[num_bzgp + grid_point + 1] - gp_map[num_bzgp + grid_point] + 1;
|
||||
bz0++)
|
||||
{
|
||||
if (bz0 == 0)
|
||||
{
|
||||
bzgp[0] = grid_point;
|
||||
}
|
||||
else
|
||||
{
|
||||
bzgp[0] = num_gp + gp_map[num_bzgp + grid_point] + bz0 - 1;
|
||||
}
|
||||
for (bz1 = 0;
|
||||
bz1 < gp_map[num_bzgp + ir_q1_gps[i] + 1] - gp_map[num_bzgp + ir_q1_gps[i]] + 1;
|
||||
bz1++)
|
||||
{
|
||||
if (bz1 == 0)
|
||||
{
|
||||
bzgp[1] = ir_q1_gps[i];
|
||||
for (i = 0; i < num_ir; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
bz_adrs1[j] = bz_adrs[ir_q1_gps[i]][j];
|
||||
bz_adrs2[j] = -bz_adrs0[j] - bz_adrs1[j];
|
||||
}
|
||||
else
|
||||
{
|
||||
bzgp[1] = num_gp + gp_map[num_bzgp + ir_q1_gps[i]] + bz1 - 1;
|
||||
}
|
||||
for (bz2 = 0;
|
||||
bz2 < gp_map[num_bzgp + gp2 + 1] - gp_map[num_bzgp + gp2] + 1;
|
||||
bz2++)
|
||||
{
|
||||
if (bz2 == 0)
|
||||
{
|
||||
bzgp[2] = gp2;
|
||||
}
|
||||
else
|
||||
{
|
||||
bzgp[2] = num_gp + gp_map[num_bzgp + gp2] + bz2 - 1;
|
||||
}
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
G[j] = bz_adrs[bzgp[0]][j] + bz_adrs[bzgp[1]][j] + bz_adrs[bzgp[2]][j];
|
||||
}
|
||||
if (G[0] == 0 && G[1] == 0 && G[2] == 0)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
triplets[i][j] = bzgp[j];
|
||||
gp2 = grg_get_grid_index(bz_adrs2, bzgrid->D_diag);
|
||||
/* Negative value is the signal to initialize min_d2 later. */
|
||||
min_d2 = -1;
|
||||
for (bz0 = 0; bz0 < gp_map[num_bzgp + grid_point + 1] -
|
||||
gp_map[num_bzgp + grid_point] + 1;
|
||||
bz0++) {
|
||||
if (bz0 == 0) {
|
||||
bzgp[0] = grid_point;
|
||||
} else {
|
||||
bzgp[0] = num_gp + gp_map[num_bzgp + grid_point] + bz0 - 1;
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
d2 = get_squared_distance(G, LQD_inv);
|
||||
if (d2 < min_d2 - tolerance || min_d2 < 0)
|
||||
{
|
||||
min_d2 = d2;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
triplets[i][j] = bzgp[j];
|
||||
for (bz1 = 0; bz1 < gp_map[num_bzgp + ir_q1_gps[i] + 1] -
|
||||
gp_map[num_bzgp + ir_q1_gps[i]] + 1;
|
||||
bz1++) {
|
||||
if (bz1 == 0) {
|
||||
bzgp[1] = ir_q1_gps[i];
|
||||
} else {
|
||||
bzgp[1] =
|
||||
num_gp + gp_map[num_bzgp + ir_q1_gps[i]] + bz1 - 1;
|
||||
}
|
||||
for (bz2 = 0; bz2 < gp_map[num_bzgp + gp2 + 1] -
|
||||
gp_map[num_bzgp + gp2] + 1;
|
||||
bz2++) {
|
||||
if (bz2 == 0) {
|
||||
bzgp[2] = gp2;
|
||||
} else {
|
||||
bzgp[2] = num_gp + gp_map[num_bzgp + gp2] + bz2 - 1;
|
||||
}
|
||||
for (j = 0; j < 3; j++) {
|
||||
G[j] = bz_adrs[bzgp[0]][j] + bz_adrs[bzgp[1]][j] +
|
||||
bz_adrs[bzgp[2]][j];
|
||||
}
|
||||
if (G[0] == 0 && G[1] == 0 && G[2] == 0) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
triplets[i][j] = bzgp[j];
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
d2 = get_squared_distance(G, LQD_inv);
|
||||
if (d2 < min_d2 - tolerance || min_d2 < 0) {
|
||||
min_d2 = d2;
|
||||
for (j = 0; j < 3; j++) {
|
||||
triplets[i][j] = bzgp[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
found:;
|
||||
}
|
||||
found:;
|
||||
}
|
||||
}
|
||||
|
||||
static void get_BZ_triplets_at_q_type2(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *ir_q1_gps,
|
||||
const long num_ir)
|
||||
{
|
||||
long i, j, gp0, gp2;
|
||||
long bzgp[3], G[3];
|
||||
long bz_adrs0[3], bz_adrs1[3], bz_adrs2[3];
|
||||
const long *gp_map;
|
||||
const long(*bz_adrs)[3];
|
||||
double d2, min_d2, tolerance;
|
||||
double LQD_inv[3][3];
|
||||
const long num_ir) {
|
||||
long i, j, gp0, gp2;
|
||||
long bzgp[3], G[3];
|
||||
long bz_adrs0[3], bz_adrs1[3], bz_adrs2[3];
|
||||
const long *gp_map;
|
||||
const long(*bz_adrs)[3];
|
||||
double d2, min_d2, tolerance;
|
||||
double LQD_inv[3][3];
|
||||
|
||||
gp_map = bzgrid->gp_map;
|
||||
bz_adrs = bzgrid->addresses;
|
||||
get_LQD_inv(LQD_inv, bzgrid);
|
||||
/* This tolerance is used to be consistent to BZ reduction in bzgrid. */
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction((BZGrid *)bzgrid);
|
||||
gp_map = bzgrid->gp_map;
|
||||
bz_adrs = bzgrid->addresses;
|
||||
get_LQD_inv(LQD_inv, bzgrid);
|
||||
/* This tolerance is used to be consistent to BZ reduction in bzgrid. */
|
||||
tolerance = bzg_get_tolerance_for_BZ_reduction((BZGrid *)bzgrid);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
bz_adrs0[i] = bz_adrs[grid_point][i];
|
||||
}
|
||||
gp0 = grg_get_grid_index(bz_adrs0, bzgrid->D_diag);
|
||||
for (i = 0; i < 3; i++) {
|
||||
bz_adrs0[i] = bz_adrs[grid_point][i];
|
||||
}
|
||||
gp0 = grg_get_grid_index(bz_adrs0, bzgrid->D_diag);
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, gp2, bzgp, G, bz_adrs1, bz_adrs2, d2, min_d2)
|
||||
#pragma omp parallel for private(j, gp2, bzgp, G, bz_adrs1, bz_adrs2, d2, \
|
||||
min_d2)
|
||||
#endif
|
||||
for (i = 0; i < num_ir; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bz_adrs1[j] = bz_adrs[gp_map[ir_q1_gps[i]]][j];
|
||||
bz_adrs2[j] = -bz_adrs0[j] - bz_adrs1[j];
|
||||
}
|
||||
gp2 = grg_get_grid_index(bz_adrs2, bzgrid->D_diag);
|
||||
/* Negative value is the signal to initialize min_d2 later. */
|
||||
min_d2 = -1;
|
||||
for (bzgp[0] = gp_map[gp0]; bzgp[0] < gp_map[gp0 + 1]; bzgp[0]++)
|
||||
{
|
||||
for (bzgp[1] = gp_map[ir_q1_gps[i]];
|
||||
bzgp[1] < gp_map[ir_q1_gps[i] + 1]; bzgp[1]++)
|
||||
{
|
||||
for (bzgp[2] = gp_map[gp2]; bzgp[2] < gp_map[gp2 + 1]; bzgp[2]++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
G[j] = bz_adrs[bzgp[0]][j] + bz_adrs[bzgp[1]][j] + bz_adrs[bzgp[2]][j];
|
||||
}
|
||||
if (G[0] == 0 && G[1] == 0 && G[2] == 0)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
triplets[i][j] = bzgp[j];
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
d2 = get_squared_distance(G, LQD_inv);
|
||||
if (d2 < min_d2 - tolerance || min_d2 < 0)
|
||||
{
|
||||
min_d2 = d2;
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
triplets[i][j] = bzgp[j];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < num_ir; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
bz_adrs1[j] = bz_adrs[gp_map[ir_q1_gps[i]]][j];
|
||||
bz_adrs2[j] = -bz_adrs0[j] - bz_adrs1[j];
|
||||
}
|
||||
}
|
||||
gp2 = grg_get_grid_index(bz_adrs2, bzgrid->D_diag);
|
||||
/* Negative value is the signal to initialize min_d2 later. */
|
||||
min_d2 = -1;
|
||||
for (bzgp[0] = gp_map[gp0]; bzgp[0] < gp_map[gp0 + 1]; bzgp[0]++) {
|
||||
for (bzgp[1] = gp_map[ir_q1_gps[i]];
|
||||
bzgp[1] < gp_map[ir_q1_gps[i] + 1]; bzgp[1]++) {
|
||||
for (bzgp[2] = gp_map[gp2]; bzgp[2] < gp_map[gp2 + 1];
|
||||
bzgp[2]++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
G[j] = bz_adrs[bzgp[0]][j] + bz_adrs[bzgp[1]][j] +
|
||||
bz_adrs[bzgp[2]][j];
|
||||
}
|
||||
if (G[0] == 0 && G[1] == 0 && G[2] == 0) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
triplets[i][j] = bzgp[j];
|
||||
}
|
||||
goto found;
|
||||
}
|
||||
d2 = get_squared_distance(G, LQD_inv);
|
||||
if (d2 < min_d2 - tolerance || min_d2 < 0) {
|
||||
min_d2 = d2;
|
||||
for (j = 0; j < 3; j++) {
|
||||
triplets[i][j] = bzgp[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
found:;
|
||||
}
|
||||
found:;
|
||||
}
|
||||
}
|
||||
|
||||
static double get_squared_distance(const long G[3],
|
||||
const double LQD_inv[3][3])
|
||||
{
|
||||
double d, d2;
|
||||
long i;
|
||||
const double LQD_inv[3][3]) {
|
||||
double d, d2;
|
||||
long i;
|
||||
|
||||
d2 = 0;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
d = LQD_inv[i][0] * G[0] + LQD_inv[i][1] * G[1] + LQD_inv[i][2] * G[2];
|
||||
d2 += d * d;
|
||||
}
|
||||
d2 = 0;
|
||||
for (i = 0; i < 3; i++) {
|
||||
d = LQD_inv[i][0] * G[0] + LQD_inv[i][1] * G[1] + LQD_inv[i][2] * G[2];
|
||||
d2 += d * d;
|
||||
}
|
||||
|
||||
return d2;
|
||||
return d2;
|
||||
}
|
||||
|
||||
static void get_LQD_inv(double LQD_inv[3][3], const ConstBZGrid *bzgrid)
|
||||
{
|
||||
long i, j, k;
|
||||
static void get_LQD_inv(double LQD_inv[3][3], const ConstBZGrid *bzgrid) {
|
||||
long i, j, k;
|
||||
|
||||
/* LQD^-1 */
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
for (k = 0; k < 3; k++)
|
||||
{
|
||||
LQD_inv[i][k] = bzgrid->reclat[i][j] * bzgrid->Q[j][k] / bzgrid->D_diag[k];
|
||||
}
|
||||
/* LQD^-1 */
|
||||
for (i = 0; i < 3; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (k = 0; k < 3; k++) {
|
||||
LQD_inv[i][k] =
|
||||
bzgrid->reclat[i][j] * bzgrid->Q[j][k] / bzgrid->D_diag[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return NULL if failed */
|
||||
static RotMats *get_reciprocal_point_group_with_q(const RotMats *rot_reciprocal,
|
||||
const long D_diag[3],
|
||||
const long grid_point)
|
||||
{
|
||||
long i, num_rot, gp_rot;
|
||||
long *ir_rot;
|
||||
long adrs[3], adrs_rot[3];
|
||||
RotMats *rot_reciprocal_q;
|
||||
const long grid_point) {
|
||||
long i, num_rot, gp_rot;
|
||||
long *ir_rot;
|
||||
long adrs[3], adrs_rot[3];
|
||||
RotMats *rot_reciprocal_q;
|
||||
|
||||
ir_rot = NULL;
|
||||
rot_reciprocal_q = NULL;
|
||||
num_rot = 0;
|
||||
ir_rot = NULL;
|
||||
rot_reciprocal_q = NULL;
|
||||
num_rot = 0;
|
||||
|
||||
grg_get_grid_address_from_index(adrs, grid_point, D_diag);
|
||||
grg_get_grid_address_from_index(adrs, grid_point, D_diag);
|
||||
|
||||
if ((ir_rot = (long *)malloc(sizeof(long) * rot_reciprocal->size)) == NULL)
|
||||
{
|
||||
warning_print("Memory of ir_rot could not be allocated.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rot_reciprocal->size; i++)
|
||||
{
|
||||
ir_rot[i] = -1;
|
||||
}
|
||||
for (i = 0; i < rot_reciprocal->size; i++)
|
||||
{
|
||||
lagmat_multiply_matrix_vector_l3(adrs_rot, rot_reciprocal->mat[i], adrs);
|
||||
gp_rot = grg_get_grid_index(adrs_rot, D_diag);
|
||||
|
||||
if (gp_rot == grid_point)
|
||||
{
|
||||
ir_rot[num_rot] = i;
|
||||
num_rot++;
|
||||
if ((ir_rot = (long *)malloc(sizeof(long) * rot_reciprocal->size)) ==
|
||||
NULL) {
|
||||
warning_print("Memory of ir_rot could not be allocated.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((rot_reciprocal_q = bzg_alloc_RotMats(num_rot)) != NULL)
|
||||
{
|
||||
for (i = 0; i < num_rot; i++)
|
||||
{
|
||||
lagmat_copy_matrix_l3(rot_reciprocal_q->mat[i],
|
||||
rot_reciprocal->mat[ir_rot[i]]);
|
||||
for (i = 0; i < rot_reciprocal->size; i++) {
|
||||
ir_rot[i] = -1;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < rot_reciprocal->size; i++) {
|
||||
lagmat_multiply_matrix_vector_l3(adrs_rot, rot_reciprocal->mat[i],
|
||||
adrs);
|
||||
gp_rot = grg_get_grid_index(adrs_rot, D_diag);
|
||||
|
||||
free(ir_rot);
|
||||
ir_rot = NULL;
|
||||
if (gp_rot == grid_point) {
|
||||
ir_rot[num_rot] = i;
|
||||
num_rot++;
|
||||
}
|
||||
}
|
||||
|
||||
return rot_reciprocal_q;
|
||||
if ((rot_reciprocal_q = bzg_alloc_RotMats(num_rot)) != NULL) {
|
||||
for (i = 0; i < num_rot; i++) {
|
||||
lagmat_copy_matrix_l3(rot_reciprocal_q->mat[i],
|
||||
rot_reciprocal->mat[ir_rot[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
free(ir_rot);
|
||||
ir_rot = NULL;
|
||||
|
||||
return rot_reciprocal_q;
|
||||
}
|
||||
|
||||
static RotMats *get_reciprocal_point_group(const long (*rec_rotations_in)[3][3],
|
||||
const long num_rot,
|
||||
const long is_time_reversal,
|
||||
const long is_transpose)
|
||||
{
|
||||
long i, num_rot_out;
|
||||
long rec_rotations_out[48][3][3];
|
||||
RotMats *rec_rotations;
|
||||
const long is_transpose) {
|
||||
long i, num_rot_out;
|
||||
long rec_rotations_out[48][3][3];
|
||||
RotMats *rec_rotations;
|
||||
|
||||
num_rot_out = grg_get_reciprocal_point_group(rec_rotations_out,
|
||||
rec_rotations_in,
|
||||
num_rot,
|
||||
is_time_reversal,
|
||||
is_transpose);
|
||||
if (num_rot_out == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
num_rot_out =
|
||||
grg_get_reciprocal_point_group(rec_rotations_out, rec_rotations_in,
|
||||
num_rot, is_time_reversal, is_transpose);
|
||||
if (num_rot_out == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rec_rotations = bzg_alloc_RotMats(num_rot_out);
|
||||
for (i = 0; i < num_rot_out; i++)
|
||||
{
|
||||
lagmat_copy_matrix_l3(rec_rotations->mat[i], rec_rotations_out[i]);
|
||||
}
|
||||
rec_rotations = bzg_alloc_RotMats(num_rot_out);
|
||||
for (i = 0; i < num_rot_out; i++) {
|
||||
lagmat_copy_matrix_l3(rec_rotations->mat[i], rec_rotations_out[i]);
|
||||
}
|
||||
|
||||
return rec_rotations;
|
||||
return rec_rotations;
|
||||
}
|
||||
|
|
|
@ -37,18 +37,15 @@
|
|||
#ifndef __triplet_grid_H__
|
||||
#define __triplet_grid_H__
|
||||
|
||||
#include "bzgrid.h"
|
||||
#include "lagrid.h"
|
||||
|
||||
long tpk_get_ir_triplets_at_q(long *map_triplets,
|
||||
long *map_q,
|
||||
const long grid_point,
|
||||
const long D_diag[3],
|
||||
long tpk_get_ir_triplets_at_q(long *map_triplets, long *map_q,
|
||||
const long grid_point, const long D_diag[3],
|
||||
const long is_time_reversal,
|
||||
const long (*rec_rotations_in)[3][3],
|
||||
const long num_rot,
|
||||
const long swappable);
|
||||
long tpk_get_BZ_triplets_at_q(long (*triplets)[3],
|
||||
const long grid_point,
|
||||
const long num_rot, const long swappable);
|
||||
long tpk_get_BZ_triplets_at_q(long (*triplets)[3], const long grid_point,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const long *map_triplets);
|
||||
|
||||
|
|
566
c/triplet_iw.c
566
c/triplet_iw.c
|
@ -32,270 +32,208 @@
|
|||
/* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
|
||||
/* POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "triplet_iw.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "grgrid.h"
|
||||
#include "phonoc_utils.h"
|
||||
#include "triplet.h"
|
||||
#include "triplet_iw.h"
|
||||
#include "tetrahedron_method.h"
|
||||
#include "triplet.h"
|
||||
|
||||
static void set_freq_vertices(double freq_vertices[3][24][4],
|
||||
const double *frequencies1,
|
||||
const double *frequencies2,
|
||||
const long vertices[2][24][4],
|
||||
const long num_band1,
|
||||
const long num_band2,
|
||||
const long b1,
|
||||
const long b2,
|
||||
const long tp_type);
|
||||
static long set_g(double g[3],
|
||||
const double f0,
|
||||
const double freq_vertices[3][24][4],
|
||||
const long max_i);
|
||||
const long num_band1, const long num_band2,
|
||||
const long b1, const long b2, const long tp_type);
|
||||
static long set_g(double g[3], const double f0,
|
||||
const double freq_vertices[3][24][4], const long max_i);
|
||||
static void get_triplet_tetrahedra_vertices(
|
||||
long vertices[2][24][4],
|
||||
const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplet[3],
|
||||
const ConstBZGrid *bzgrid);
|
||||
static void
|
||||
get_neighboring_grid_points_type1(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid);
|
||||
static void
|
||||
get_neighboring_grid_points_type2(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid);
|
||||
long vertices[2][24][4], const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplet[3], const ConstBZGrid *bzgrid);
|
||||
static void get_neighboring_grid_points_type1(
|
||||
long *neighboring_grid_points, const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address, const ConstBZGrid *bzgrid);
|
||||
static void get_neighboring_grid_points_type2(
|
||||
long *neighboring_grid_points, const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address, const ConstBZGrid *bzgrid);
|
||||
|
||||
void tpi_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplets[3],
|
||||
const long num_triplets,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_bands)
|
||||
{
|
||||
long max_i, j, b1, b2, b12, num_band_prod, adrs_shift;
|
||||
long vertices[2][24][4];
|
||||
double g[3];
|
||||
double freq_vertices[3][24][4];
|
||||
void tpi_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplets[3], const long num_triplets, const ConstBZGrid *bzgrid,
|
||||
const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_bands) {
|
||||
long max_i, j, b1, b2, b12, num_band_prod, adrs_shift;
|
||||
long vertices[2][24][4];
|
||||
double g[3];
|
||||
double freq_vertices[3][24][4];
|
||||
|
||||
get_triplet_tetrahedra_vertices(vertices,
|
||||
tp_relative_grid_address,
|
||||
triplets,
|
||||
bzgrid);
|
||||
get_triplet_tetrahedra_vertices(vertices, tp_relative_grid_address,
|
||||
triplets, bzgrid);
|
||||
|
||||
num_band_prod = num_triplets * num_band0 * num_band1 * num_band2;
|
||||
num_band_prod = num_triplets * num_band0 * num_band1 * num_band2;
|
||||
|
||||
/* tp_type: Type of integration weights stored */
|
||||
/* */
|
||||
/* g0 -> \delta(f0 - (-f1 + f2)) */
|
||||
/* g1 -> \delta(f0 - (f1 - f2)) */
|
||||
/* g2 -> \delta(f0 - (f1 + f2)) */
|
||||
/* */
|
||||
/* tp_type = 2: (g[2], g[0] - g[1]) mainly for ph-ph */
|
||||
/* tp_type = 3: (g[2], g[0] - g[1], g[0] + g[1] + g[2]) mainly for ph-ph */
|
||||
/* tp_type = 4: (g[0]) mainly for el-ph phonon decay, */
|
||||
/* f0: ph, f1: el_i, f2: el_f */
|
||||
/* tp_type: Type of integration weights stored */
|
||||
/* */
|
||||
/* g0 -> \delta(f0 - (-f1 + f2)) */
|
||||
/* g1 -> \delta(f0 - (f1 - f2)) */
|
||||
/* g2 -> \delta(f0 - (f1 + f2)) */
|
||||
/* */
|
||||
/* tp_type = 2: (g[2], g[0] - g[1]) mainly for ph-ph */
|
||||
/* tp_type = 3: (g[2], g[0] - g[1], g[0] + g[1] + g[2]) mainly for ph-ph */
|
||||
/* tp_type = 4: (g[0]) mainly for el-ph phonon decay, */
|
||||
/* f0: ph, f1: el_i, f2: el_f */
|
||||
|
||||
if ((tp_type == 2) || (tp_type == 3))
|
||||
{
|
||||
max_i = 3;
|
||||
}
|
||||
if (tp_type == 4)
|
||||
{
|
||||
max_i = 1;
|
||||
}
|
||||
if ((tp_type == 2) || (tp_type == 3)) {
|
||||
max_i = 3;
|
||||
}
|
||||
if (tp_type == 4) {
|
||||
max_i = 1;
|
||||
}
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, b1, b2, adrs_shift, g, freq_vertices) if (openmp_per_bands)
|
||||
#pragma omp parallel for private(j, b1, b2, adrs_shift, g, \
|
||||
freq_vertices) if (openmp_per_bands)
|
||||
#endif
|
||||
for (b12 = 0; b12 < num_band1 * num_band2; b12++)
|
||||
{
|
||||
b1 = b12 / num_band2;
|
||||
b2 = b12 % num_band2;
|
||||
set_freq_vertices(freq_vertices, frequencies1, frequencies2,
|
||||
vertices, num_band1, num_band2, b1, b2, tp_type);
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
adrs_shift = j * num_band1 * num_band2 + b1 * num_band2 + b2;
|
||||
iw_zero[adrs_shift] = set_g(g, frequency_points[j], freq_vertices, max_i);
|
||||
if (tp_type == 2)
|
||||
{
|
||||
iw[adrs_shift] = g[2];
|
||||
adrs_shift += num_band_prod;
|
||||
iw[adrs_shift] = g[0] - g[1];
|
||||
}
|
||||
if (tp_type == 3)
|
||||
{
|
||||
iw[adrs_shift] = g[2];
|
||||
adrs_shift += num_band_prod;
|
||||
iw[adrs_shift] = g[0] - g[1];
|
||||
adrs_shift += num_band_prod;
|
||||
iw[adrs_shift] = g[0] + g[1] + g[2];
|
||||
}
|
||||
if (tp_type == 4)
|
||||
{
|
||||
iw[adrs_shift] = g[0];
|
||||
}
|
||||
for (b12 = 0; b12 < num_band1 * num_band2; b12++) {
|
||||
b1 = b12 / num_band2;
|
||||
b2 = b12 % num_band2;
|
||||
set_freq_vertices(freq_vertices, frequencies1, frequencies2, vertices,
|
||||
num_band1, num_band2, b1, b2, tp_type);
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
adrs_shift = j * num_band1 * num_band2 + b1 * num_band2 + b2;
|
||||
iw_zero[adrs_shift] =
|
||||
set_g(g, frequency_points[j], freq_vertices, max_i);
|
||||
if (tp_type == 2) {
|
||||
iw[adrs_shift] = g[2];
|
||||
adrs_shift += num_band_prod;
|
||||
iw[adrs_shift] = g[0] - g[1];
|
||||
}
|
||||
if (tp_type == 3) {
|
||||
iw[adrs_shift] = g[2];
|
||||
adrs_shift += num_band_prod;
|
||||
iw[adrs_shift] = g[0] - g[1];
|
||||
adrs_shift += num_band_prod;
|
||||
iw[adrs_shift] = g[0] + g[1] + g[2];
|
||||
}
|
||||
if (tp_type == 4) {
|
||||
iw[adrs_shift] = g[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tpi_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long triplet[3],
|
||||
const long const_adrs_shift,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type,
|
||||
const long openmp_per_bands)
|
||||
{
|
||||
long j, b12, b1, b2, adrs_shift;
|
||||
double f0, f1, f2, g0, g1, g2;
|
||||
void tpi_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double cutoff,
|
||||
const double *frequency_points, const long num_band0, const long triplet[3],
|
||||
const long const_adrs_shift, const double *frequencies, const long num_band,
|
||||
const long tp_type, const long openmp_per_bands) {
|
||||
long j, b12, b1, b2, adrs_shift;
|
||||
double f0, f1, f2, g0, g1, g2;
|
||||
|
||||
#ifdef PHPYOPENMP
|
||||
#pragma omp parallel for private(j, b1, b2, f0, f1, f2, g0, g1, g2, adrs_shift) if (openmp_per_bands)
|
||||
#pragma omp parallel for private(j, b1, b2, f0, f1, f2, g0, g1, g2, \
|
||||
adrs_shift) if (openmp_per_bands)
|
||||
#endif
|
||||
for (b12 = 0; b12 < num_band * num_band; b12++)
|
||||
{
|
||||
b1 = b12 / num_band;
|
||||
b2 = b12 % num_band;
|
||||
f1 = frequencies[triplet[1] * num_band + b1];
|
||||
f2 = frequencies[triplet[2] * num_band + b2];
|
||||
for (j = 0; j < num_band0; j++)
|
||||
{
|
||||
f0 = frequency_points[j];
|
||||
adrs_shift = j * num_band * num_band + b1 * num_band + b2;
|
||||
for (b12 = 0; b12 < num_band * num_band; b12++) {
|
||||
b1 = b12 / num_band;
|
||||
b2 = b12 % num_band;
|
||||
f1 = frequencies[triplet[1] * num_band + b1];
|
||||
f2 = frequencies[triplet[2] * num_band + b2];
|
||||
for (j = 0; j < num_band0; j++) {
|
||||
f0 = frequency_points[j];
|
||||
adrs_shift = j * num_band * num_band + b1 * num_band + b2;
|
||||
|
||||
if ((tp_type == 2) || (tp_type == 3))
|
||||
{
|
||||
if (cutoff > 0 &&
|
||||
fabs(f0 + f1 - f2) > cutoff &&
|
||||
fabs(f0 - f1 + f2) > cutoff &&
|
||||
fabs(f0 - f1 - f2) > cutoff)
|
||||
{
|
||||
iw_zero[adrs_shift] = 1;
|
||||
g0 = 0;
|
||||
g1 = 0;
|
||||
g2 = 0;
|
||||
if ((tp_type == 2) || (tp_type == 3)) {
|
||||
if (cutoff > 0 && fabs(f0 + f1 - f2) > cutoff &&
|
||||
fabs(f0 - f1 + f2) > cutoff &&
|
||||
fabs(f0 - f1 - f2) > cutoff) {
|
||||
iw_zero[adrs_shift] = 1;
|
||||
g0 = 0;
|
||||
g1 = 0;
|
||||
g2 = 0;
|
||||
} else {
|
||||
iw_zero[adrs_shift] = 0;
|
||||
g0 = phonoc_gaussian(f0 + f1 - f2, sigma);
|
||||
g1 = phonoc_gaussian(f0 - f1 + f2, sigma);
|
||||
g2 = phonoc_gaussian(f0 - f1 - f2, sigma);
|
||||
}
|
||||
if (tp_type == 2) {
|
||||
iw[adrs_shift] = g2;
|
||||
adrs_shift += const_adrs_shift;
|
||||
iw[adrs_shift] = g0 - g1;
|
||||
}
|
||||
if (tp_type == 3) {
|
||||
iw[adrs_shift] = g2;
|
||||
adrs_shift += const_adrs_shift;
|
||||
iw[adrs_shift] = g0 - g1;
|
||||
adrs_shift += const_adrs_shift;
|
||||
iw[adrs_shift] = g0 + g1 + g2;
|
||||
}
|
||||
}
|
||||
if (tp_type == 4) {
|
||||
if (cutoff > 0 && fabs(f0 + f1 - f2) > cutoff) {
|
||||
iw_zero[adrs_shift] = 1;
|
||||
iw[adrs_shift] = 0;
|
||||
} else {
|
||||
iw_zero[adrs_shift] = 0;
|
||||
iw[adrs_shift] = phonoc_gaussian(f0 + f1 - f2, sigma);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iw_zero[adrs_shift] = 0;
|
||||
g0 = phonoc_gaussian(f0 + f1 - f2, sigma);
|
||||
g1 = phonoc_gaussian(f0 - f1 + f2, sigma);
|
||||
g2 = phonoc_gaussian(f0 - f1 - f2, sigma);
|
||||
}
|
||||
if (tp_type == 2)
|
||||
{
|
||||
iw[adrs_shift] = g2;
|
||||
adrs_shift += const_adrs_shift;
|
||||
iw[adrs_shift] = g0 - g1;
|
||||
}
|
||||
if (tp_type == 3)
|
||||
{
|
||||
iw[adrs_shift] = g2;
|
||||
adrs_shift += const_adrs_shift;
|
||||
iw[adrs_shift] = g0 - g1;
|
||||
adrs_shift += const_adrs_shift;
|
||||
iw[adrs_shift] = g0 + g1 + g2;
|
||||
}
|
||||
}
|
||||
if (tp_type == 4)
|
||||
{
|
||||
if (cutoff > 0 && fabs(f0 + f1 - f2) > cutoff)
|
||||
{
|
||||
iw_zero[adrs_shift] = 1;
|
||||
iw[adrs_shift] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
iw_zero[adrs_shift] = 0;
|
||||
iw[adrs_shift] = phonoc_gaussian(f0 + f1 - f2, sigma);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tpi_get_neighboring_grid_points(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid)
|
||||
{
|
||||
if (bzgrid->type == 1)
|
||||
{
|
||||
get_neighboring_grid_points_type1(neighboring_grid_points,
|
||||
grid_point,
|
||||
relative_grid_address,
|
||||
num_relative_grid_address,
|
||||
bzgrid);
|
||||
}
|
||||
else
|
||||
{
|
||||
get_neighboring_grid_points_type2(neighboring_grid_points,
|
||||
grid_point,
|
||||
relative_grid_address,
|
||||
num_relative_grid_address,
|
||||
bzgrid);
|
||||
}
|
||||
const ConstBZGrid *bzgrid) {
|
||||
if (bzgrid->type == 1) {
|
||||
get_neighboring_grid_points_type1(neighboring_grid_points, grid_point,
|
||||
relative_grid_address,
|
||||
num_relative_grid_address, bzgrid);
|
||||
} else {
|
||||
get_neighboring_grid_points_type2(neighboring_grid_points, grid_point,
|
||||
relative_grid_address,
|
||||
num_relative_grid_address, bzgrid);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_freq_vertices(double freq_vertices[3][24][4],
|
||||
const double *frequencies1,
|
||||
const double *frequencies2,
|
||||
const long vertices[2][24][4],
|
||||
const long num_band1,
|
||||
const long num_band2,
|
||||
const long b1,
|
||||
const long b2,
|
||||
const long tp_type)
|
||||
{
|
||||
long i, j;
|
||||
double f1, f2;
|
||||
const long num_band1, const long num_band2,
|
||||
const long b1, const long b2,
|
||||
const long tp_type) {
|
||||
long i, j;
|
||||
double f1, f2;
|
||||
|
||||
for (i = 0; i < 24; i++)
|
||||
{
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
f1 = frequencies1[vertices[0][i][j] * num_band1 + b1];
|
||||
f2 = frequencies2[vertices[1][i][j] * num_band2 + b2];
|
||||
if ((tp_type == 2) || (tp_type == 3))
|
||||
{
|
||||
if (f1 < 0)
|
||||
{
|
||||
f1 = 0;
|
||||
for (i = 0; i < 24; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
f1 = frequencies1[vertices[0][i][j] * num_band1 + b1];
|
||||
f2 = frequencies2[vertices[1][i][j] * num_band2 + b2];
|
||||
if ((tp_type == 2) || (tp_type == 3)) {
|
||||
if (f1 < 0) {
|
||||
f1 = 0;
|
||||
}
|
||||
if (f2 < 0) {
|
||||
f2 = 0;
|
||||
}
|
||||
freq_vertices[0][i][j] = -f1 + f2;
|
||||
freq_vertices[1][i][j] = f1 - f2;
|
||||
freq_vertices[2][i][j] = f1 + f2;
|
||||
} else {
|
||||
freq_vertices[0][i][j] = -f1 + f2;
|
||||
}
|
||||
}
|
||||
if (f2 < 0)
|
||||
{
|
||||
f2 = 0;
|
||||
}
|
||||
freq_vertices[0][i][j] = -f1 + f2;
|
||||
freq_vertices[1][i][j] = f1 - f2;
|
||||
freq_vertices[2][i][j] = f1 + f2;
|
||||
}
|
||||
else
|
||||
{
|
||||
freq_vertices[0][i][j] = -f1 + f2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Integration weight g is calculated. */
|
||||
|
@ -307,113 +245,87 @@ static void set_freq_vertices(double freq_vertices[3][24][4],
|
|||
/* iw_zero=1 information can be used to omit to compute particles */
|
||||
/* interaction strength that is often heaviest part in throughout */
|
||||
/* calculation. */
|
||||
static long set_g(double g[3],
|
||||
const double f0,
|
||||
const double freq_vertices[3][24][4],
|
||||
const long max_i)
|
||||
{
|
||||
long i, iw_zero;
|
||||
static long set_g(double g[3], const double f0,
|
||||
const double freq_vertices[3][24][4], const long max_i) {
|
||||
long i, iw_zero;
|
||||
|
||||
iw_zero = 1;
|
||||
iw_zero = 1;
|
||||
|
||||
for (i = 0; i < max_i; i++)
|
||||
{
|
||||
if (thm_in_tetrahedra(f0, freq_vertices[i]))
|
||||
{
|
||||
g[i] = thm_get_integration_weight(f0, freq_vertices[i], 'I');
|
||||
iw_zero = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return iw_zero;
|
||||
}
|
||||
|
||||
static void get_triplet_tetrahedra_vertices(long vertices[2][24][4],
|
||||
const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplet[3],
|
||||
const ConstBZGrid *bzgrid)
|
||||
{
|
||||
long i, j;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
for (j = 0; j < 24; j++)
|
||||
{
|
||||
tpi_get_neighboring_grid_points(vertices[i][j],
|
||||
triplet[i + 1],
|
||||
tp_relative_grid_address[i][j],
|
||||
4,
|
||||
bzgrid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_neighboring_grid_points_type1(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid)
|
||||
{
|
||||
long bzmesh[3], bz_address[3];
|
||||
long i, j, bz_gp, prod_bz_mesh;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
bzmesh[i] = bzgrid->D_diag[i] * 2;
|
||||
}
|
||||
prod_bz_mesh = bzmesh[0] * bzmesh[1] * bzmesh[2];
|
||||
for (i = 0; i < num_relative_grid_address; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bz_address[j] = bzgrid->addresses[grid_point][j] + relative_grid_address[i][j];
|
||||
}
|
||||
bz_gp = bzgrid->gp_map[grg_get_grid_index(bz_address, bzmesh)];
|
||||
if (bz_gp == prod_bz_mesh)
|
||||
{
|
||||
neighboring_grid_points[i] =
|
||||
grg_get_grid_index(bz_address, bzgrid->D_diag);
|
||||
}
|
||||
else
|
||||
{
|
||||
neighboring_grid_points[i] = bz_gp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
get_neighboring_grid_points_type2(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid)
|
||||
{
|
||||
long bz_address[3];
|
||||
long i, j, gp;
|
||||
|
||||
for (i = 0; i < num_relative_grid_address; i++)
|
||||
{
|
||||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
bz_address[j] = bzgrid->addresses[grid_point][j] + relative_grid_address[i][j];
|
||||
}
|
||||
gp = grg_get_grid_index(bz_address, bzgrid->D_diag);
|
||||
neighboring_grid_points[i] = bzgrid->gp_map[gp];
|
||||
if (bzgrid->gp_map[gp + 1] - bzgrid->gp_map[gp] > 1)
|
||||
{
|
||||
for (j = bzgrid->gp_map[gp]; j < bzgrid->gp_map[gp + 1]; j++)
|
||||
{
|
||||
if (bz_address[0] == bzgrid->addresses[j][0] && bz_address[1] == bzgrid->addresses[j][1] && bz_address[2] == bzgrid->addresses[j][2])
|
||||
{
|
||||
neighboring_grid_points[i] = j;
|
||||
break;
|
||||
for (i = 0; i < max_i; i++) {
|
||||
if (thm_in_tetrahedra(f0, freq_vertices[i])) {
|
||||
g[i] = thm_get_integration_weight(f0, freq_vertices[i], 'I');
|
||||
iw_zero = 0;
|
||||
} else {
|
||||
g[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return iw_zero;
|
||||
}
|
||||
|
||||
static void get_triplet_tetrahedra_vertices(
|
||||
long vertices[2][24][4], const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplet[3], const ConstBZGrid *bzgrid) {
|
||||
long i, j;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
for (j = 0; j < 24; j++) {
|
||||
tpi_get_neighboring_grid_points(vertices[i][j], triplet[i + 1],
|
||||
tp_relative_grid_address[i][j], 4,
|
||||
bzgrid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void get_neighboring_grid_points_type1(
|
||||
long *neighboring_grid_points, const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address, const ConstBZGrid *bzgrid) {
|
||||
long bzmesh[3], bz_address[3];
|
||||
long i, j, bz_gp, prod_bz_mesh;
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
bzmesh[i] = bzgrid->D_diag[i] * 2;
|
||||
}
|
||||
prod_bz_mesh = bzmesh[0] * bzmesh[1] * bzmesh[2];
|
||||
for (i = 0; i < num_relative_grid_address; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
bz_address[j] =
|
||||
bzgrid->addresses[grid_point][j] + relative_grid_address[i][j];
|
||||
}
|
||||
bz_gp = bzgrid->gp_map[grg_get_grid_index(bz_address, bzmesh)];
|
||||
if (bz_gp == prod_bz_mesh) {
|
||||
neighboring_grid_points[i] =
|
||||
grg_get_grid_index(bz_address, bzgrid->D_diag);
|
||||
} else {
|
||||
neighboring_grid_points[i] = bz_gp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void get_neighboring_grid_points_type2(
|
||||
long *neighboring_grid_points, const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address, const ConstBZGrid *bzgrid) {
|
||||
long bz_address[3];
|
||||
long i, j, gp;
|
||||
|
||||
for (i = 0; i < num_relative_grid_address; i++) {
|
||||
for (j = 0; j < 3; j++) {
|
||||
bz_address[j] =
|
||||
bzgrid->addresses[grid_point][j] + relative_grid_address[i][j];
|
||||
}
|
||||
gp = grg_get_grid_index(bz_address, bzgrid->D_diag);
|
||||
neighboring_grid_points[i] = bzgrid->gp_map[gp];
|
||||
if (bzgrid->gp_map[gp + 1] - bzgrid->gp_map[gp] > 1) {
|
||||
for (j = bzgrid->gp_map[gp]; j < bzgrid->gp_map[gp + 1]; j++) {
|
||||
if (bz_address[0] == bzgrid->addresses[j][0] &&
|
||||
bz_address[1] == bzgrid->addresses[j][1] &&
|
||||
bz_address[2] == bzgrid->addresses[j][2]) {
|
||||
neighboring_grid_points[i] = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,38 +35,24 @@
|
|||
#ifndef __triplet_iw_H__
|
||||
#define __triplet_iw_H__
|
||||
|
||||
void
|
||||
tpi_get_integration_weight(double *iw,
|
||||
char *iw_zero,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplets[3],
|
||||
const long num_triplets,
|
||||
const ConstBZGrid *bzgrid,
|
||||
const double *frequencies1,
|
||||
const long num_band1,
|
||||
const double *frequencies2,
|
||||
const long num_band2,
|
||||
const long tp_type,
|
||||
const long openmp_per_bands);
|
||||
void tpi_get_integration_weight_with_sigma(double *iw,
|
||||
char *iw_zero,
|
||||
const double sigma,
|
||||
const double cutoff,
|
||||
const double *frequency_points,
|
||||
const long num_band0,
|
||||
const long triplet[3],
|
||||
const long const_adrs_shift,
|
||||
const double *frequencies,
|
||||
const long num_band,
|
||||
const long tp_type,
|
||||
const long openmp_per_bands);
|
||||
void
|
||||
tpi_get_neighboring_grid_points(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid);
|
||||
#include "bzgrid.h"
|
||||
|
||||
void tpi_get_integration_weight(
|
||||
double *iw, char *iw_zero, const double *frequency_points,
|
||||
const long num_band0, const long tp_relative_grid_address[2][24][4][3],
|
||||
const long triplets[3], const long num_triplets, const ConstBZGrid *bzgrid,
|
||||
const double *frequencies1, const long num_band1,
|
||||
const double *frequencies2, const long num_band2, const long tp_type,
|
||||
const long openmp_per_bands);
|
||||
void tpi_get_integration_weight_with_sigma(
|
||||
double *iw, char *iw_zero, const double sigma, const double cutoff,
|
||||
const double *frequency_points, const long num_band0, const long triplet[3],
|
||||
const long const_adrs_shift, const double *frequencies, const long num_band,
|
||||
const long tp_type, const long openmp_per_bands);
|
||||
void tpi_get_neighboring_grid_points(long *neighboring_grid_points,
|
||||
const long grid_point,
|
||||
const long (*relative_grid_address)[3],
|
||||
const long num_relative_grid_address,
|
||||
const ConstBZGrid *bzgrid);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2530,6 +2530,7 @@ class Phono3py:
|
|||
def _set_mesh_numbers(self, mesh):
|
||||
# initialization related to mesh
|
||||
self._interaction = None
|
||||
|
||||
self._bz_grid = BZGrid(
|
||||
mesh,
|
||||
lattice=self._primitive.cell,
|
||||
|
|
|
@ -608,15 +608,16 @@ def get_grid_points_by_rotations(
|
|||
bz_grid : BZGrid
|
||||
Data structure to represent BZ grid.
|
||||
reciprocal_rotations : array_like or None, optional
|
||||
Rotation matrices {R} with respect to reciprocal basis vectors.
|
||||
Defined by q'=Rq.
|
||||
Rotation matrices {R} with respect to basis vectors of GR-grid.
|
||||
Defined by g'=Rg, where g is the grid point address represented by
|
||||
three integers in BZ-grid.
|
||||
dtype='int_', shape=(rotations, 3, 3)
|
||||
with_surface : Bool, optional
|
||||
This parameter affects to how to treat grid points on BZ surface.
|
||||
When False, rotated BZ surface points are moved to representative
|
||||
ones among translationally equivalent points to hold one-to-one
|
||||
correspondence to GR grid points. With True, BZ grid point indices
|
||||
having the rotated grid addresses are returned. Default is False.
|
||||
having the rotated grid addresses are returned. Default is False.
|
||||
|
||||
Returns
|
||||
-------
|
||||
|
|
|
@ -181,55 +181,129 @@ class CollisionMatrix(ImagSelfEnergy):
|
|||
)
|
||||
|
||||
def _run_py_collision_matrix(self):
|
||||
r"""Sum over rotations, and q-points and bands for third phonons.
|
||||
|
||||
\Omega' = \sum_R' R' \Omega_{kp,R'k'p'}
|
||||
|
||||
pp_strength.shape = (num_triplets, num_band0, num_band, num_band)
|
||||
|
||||
"""
|
||||
num_band0 = self._pp_strength.shape[1]
|
||||
num_band = self._pp_strength.shape[2]
|
||||
gp2tp_map = self._get_gp2tp_map()
|
||||
gp2tp, tp2s, swapped = self._get_gp2tp_map()
|
||||
for i in range(self._num_ir_grid_points):
|
||||
r_gps = self._rot_grid_points[i]
|
||||
for r, r_gp in zip(self._rotations_cartesian, r_gps):
|
||||
ti = gp2tp_map[self._triplets_map_at_q[r_gp]]
|
||||
inv_sinh = self._get_inv_sinh(r_gp, gp2tp_map)
|
||||
for j, k in list(np.ndindex((num_band0, num_band))):
|
||||
collision = (
|
||||
self._pp_strength[ti, j, k] * inv_sinh * self._g[2, ti, j, k]
|
||||
).sum()
|
||||
inv_sinh = self._get_inv_sinh(tp2s[r_gp])
|
||||
ti = gp2tp[r_gp]
|
||||
for j, k in np.ndindex((num_band0, num_band)):
|
||||
if swapped[r_gp]:
|
||||
collision = (
|
||||
self._pp_strength[ti, j, :, k]
|
||||
* inv_sinh
|
||||
* self._g[2, ti, j, :, k]
|
||||
).sum()
|
||||
else:
|
||||
collision = (
|
||||
self._pp_strength[ti, j, k]
|
||||
* inv_sinh
|
||||
* self._g[2, ti, j, k]
|
||||
).sum()
|
||||
collision *= self._unit_conversion
|
||||
self._collision_matrix[j, :, i, k, :] += collision * r
|
||||
|
||||
def _run_py_reducible_collision_matrix(self):
|
||||
r"""Sum over q-points and bands of third phonons.
|
||||
|
||||
This corresponds to the second term of right hand side of
|
||||
\Omega_{q0p0, q1p1} in Chaput's paper.
|
||||
|
||||
pp_strength.shape = (num_triplets, num_band0, num_band, num_band)
|
||||
|
||||
"""
|
||||
num_mesh_points = np.prod(self._pp.mesh_numbers)
|
||||
num_band0 = self._pp_strength.shape[1]
|
||||
num_band = self._pp_strength.shape[2]
|
||||
gp2tp_map = self._get_gp2tp_map()
|
||||
|
||||
for i in range(num_mesh_points):
|
||||
ti = gp2tp_map[self._triplets_map_at_q[i]]
|
||||
inv_sinh = self._get_inv_sinh(i, gp2tp_map)
|
||||
for j, k in list(np.ndindex((num_band0, num_band))):
|
||||
collision = (
|
||||
self._pp_strength[ti, j, k] * inv_sinh * self._g[2, ti, j, k]
|
||||
).sum()
|
||||
gp2tp, tp2s, swapped = self._get_gp2tp_map()
|
||||
for gp1 in range(num_mesh_points):
|
||||
inv_sinh = self._get_inv_sinh(tp2s[gp1])
|
||||
ti = gp2tp[gp1]
|
||||
for j, k in np.ndindex((num_band0, num_band)):
|
||||
if swapped[gp1]:
|
||||
collision = (
|
||||
self._pp_strength[ti, j, :, k]
|
||||
* inv_sinh
|
||||
* self._g[2, ti, j, :, k]
|
||||
).sum()
|
||||
else:
|
||||
collision = (
|
||||
self._pp_strength[ti, j, k] * inv_sinh * self._g[2, ti, j, k]
|
||||
).sum()
|
||||
collision *= self._unit_conversion
|
||||
self._collision_matrix[j, i, k] += collision
|
||||
self._collision_matrix[j, gp1, k] += collision
|
||||
|
||||
def _get_gp2tp_map(self):
|
||||
gp2tp_map = {}
|
||||
count = 0
|
||||
for i, j in enumerate(self._triplets_map_at_q):
|
||||
if i == j:
|
||||
gp2tp_map[i] = count
|
||||
count += 1
|
||||
"""Return mapping table from grid point index to triplet index.
|
||||
|
||||
return gp2tp_map
|
||||
triplets_map_at_q contains index mapping of q1 in (q0, q1, q2) to
|
||||
independet q1 under q0+q1+q2=G with a fixed q0.
|
||||
|
||||
def _get_inv_sinh(self, gp, gp2tp_map):
|
||||
ti = gp2tp_map[self._triplets_map_at_q[gp]]
|
||||
tp = self._triplets_at_q[ti]
|
||||
if self._triplets_map_at_q[gp] == self._ir_map_at_q[gp]:
|
||||
gp2 = tp[2]
|
||||
else:
|
||||
gp2 = tp[1]
|
||||
freqs = self._frequencies[gp2]
|
||||
Note
|
||||
----
|
||||
map_q[gp1] <= gp1.:
|
||||
Symmetry relation of grid poi nts with a stabilizer q0.
|
||||
map_triplets[gp1] <= gp1 :
|
||||
map_q[gp1] == gp1 : map_q[gp2] if map_q[gp2] < gp1 otherwise gp1.
|
||||
map_q[gp1] != gp1 : map_triplets[map_q[gp1]]
|
||||
|
||||
|
||||
|
||||
As a rule
|
||||
1. map_triplets[gp1] == gp1 : [gp0, gp1, gp2]
|
||||
2. map_triplets[gp1] != gp1 : [gp0, map_q[gp2], gp1'],
|
||||
map_triplets[gp1] == map_q[gp2]
|
||||
|
||||
"""
|
||||
map_triplets = self._triplets_map_at_q
|
||||
map_q = self._ir_map_at_q
|
||||
gp2tp = -np.ones(len(map_triplets), dtype="int_")
|
||||
tp2s = -np.ones(len(map_triplets), dtype="int_")
|
||||
swapped = np.zeros(len(map_triplets), dtype="bytes")
|
||||
num_tps = 0
|
||||
|
||||
bzg2grg = self._pp.bz_grid.bzg2grg
|
||||
|
||||
for gp1, tp_gp1 in enumerate(map_triplets):
|
||||
if map_q[gp1] == gp1:
|
||||
if gp1 == tp_gp1:
|
||||
gp2tp[gp1] = num_tps
|
||||
tp2s[gp1] = self._triplets_at_q[num_tps][2]
|
||||
assert bzg2grg[self._triplets_at_q[num_tps][1]] == gp1
|
||||
num_tps += 1
|
||||
else: # q1 <--> q2 swap if swappable.
|
||||
gp2tp[gp1] = gp2tp[tp_gp1]
|
||||
tp2s[gp1] = self._triplets_at_q[gp2tp[gp1]][1]
|
||||
swapped[gp1] = 1
|
||||
assert map_q[bzg2grg[self._triplets_at_q[gp2tp[gp1]][2]]] == gp1
|
||||
else: # q1 is not in ir-q1s.
|
||||
gp2tp[gp1] = gp2tp[map_q[gp1]]
|
||||
tp2s[gp1] = tp2s[map_q[gp1]]
|
||||
swapped[gp1] = swapped[map_q[gp1]]
|
||||
|
||||
# Alternative implementation of tp2s
|
||||
# grg2bzg = self._pp.bz_grid.grg2bzg
|
||||
# addresses = self._pp.bz_grid.addresses
|
||||
# q0 = addresses[self._triplets_at_q[0][0]]
|
||||
# q1 = addresses[grg2bzg[gp1]]
|
||||
# q2 = -q0 - q1
|
||||
# gp2 = get_grid_point_from_address(q2, self._pp.bz_grid.D_diag)
|
||||
# tp2s[gp1] = self._pp.bz_grid.grg2bzg[gp2]
|
||||
|
||||
return gp2tp, tp2s, swapped
|
||||
|
||||
def _get_inv_sinh(self, gp):
|
||||
"""Return sinh term for bands at a q-point."""
|
||||
freqs = self._frequencies[gp]
|
||||
sinh = np.where(
|
||||
freqs > self._cutoff_frequency,
|
||||
np.sinh(freqs * THzToEv / (2 * Kb * self._temperature)),
|
||||
|
|
|
@ -264,10 +264,6 @@ class Conductivity(ConductivityBase):
|
|||
self._grid_point_count += 1
|
||||
return self._grid_point_count - 1
|
||||
|
||||
def next(self):
|
||||
"""For backward compatibility."""
|
||||
return self.__next__()
|
||||
|
||||
@property
|
||||
def mesh_numbers(self):
|
||||
"""Return mesh numbers of GR-grid."""
|
||||
|
|
|
@ -58,7 +58,7 @@ from phono3py.phonon3.interaction import Interaction
|
|||
from phono3py.phonon.grid import get_grid_points_by_rotations
|
||||
|
||||
|
||||
class Conductivity_LBTE(Conductivity):
|
||||
class ConductivityLBTE(Conductivity):
|
||||
"""Lattice thermal conductivity calculation by direct solution."""
|
||||
|
||||
def __init__(
|
||||
|
@ -164,7 +164,11 @@ class Conductivity_LBTE(Conductivity):
|
|||
self._allocate_values()
|
||||
|
||||
def set_kappa_at_sigmas(self):
|
||||
"""Calculate lattice thermal conductivity from collision matrix."""
|
||||
"""Calculate lattice thermal conductivity from collision matrix.
|
||||
|
||||
This method is called after all elements of collision matrix are filled.
|
||||
|
||||
"""
|
||||
if len(self._grid_points) != len(self._ir_grid_points):
|
||||
print("Collision matrix is not well created.")
|
||||
import sys
|
||||
|
@ -491,22 +495,26 @@ class Conductivity_LBTE(Conductivity):
|
|||
self._pp.bz_grid.grg2bzg[i], self._pp.bz_grid
|
||||
)
|
||||
]
|
||||
self._expand_collisions(ir_gr_grid_points, rot_grid_points)
|
||||
self._expand_reducible_collisions(ir_gr_grid_points, rot_grid_points)
|
||||
self._expand_local_values(ir_gr_grid_points, rot_grid_points)
|
||||
self._combine_reducible_collisions()
|
||||
weights = np.ones(np.prod(self._pp.mesh_numbers), dtype="int_")
|
||||
self._symmetrize_collision_matrix()
|
||||
else:
|
||||
self._combine_collisions()
|
||||
weights = self._get_weights()
|
||||
for i, w_i in enumerate(weights):
|
||||
for j, w_j in enumerate(weights):
|
||||
self._collision_matrix[:, :, i, :, :, j, :, :] *= w_i * w_j
|
||||
weights = self._multiply_weights_to_collisions()
|
||||
self._average_collision_matrix_by_degeneracy()
|
||||
self._symmetrize_collision_matrix()
|
||||
|
||||
return weights
|
||||
|
||||
def _multiply_weights_to_collisions(self):
|
||||
weights = self._get_weights()
|
||||
for i, w_i in enumerate(weights):
|
||||
for j, w_j in enumerate(weights):
|
||||
self._collision_matrix[:, :, i, :, :, j, :, :] *= w_i * w_j
|
||||
return weights
|
||||
|
||||
def _set_kappa_at_sigmas(self, weights):
|
||||
"""Calculate thermal conductivity from collision matrix."""
|
||||
for j, sigma in enumerate(self._sigmas):
|
||||
|
@ -556,7 +564,7 @@ class Conductivity_LBTE(Conductivity):
|
|||
def _combine_collisions(self):
|
||||
"""Include diagonal elements into collision matrix."""
|
||||
num_band = len(self._pp.primitive) * 3
|
||||
for j, k in list(np.ndindex((len(self._sigmas), len(self._temperatures)))):
|
||||
for j, k in np.ndindex((len(self._sigmas), len(self._temperatures))):
|
||||
for i, ir_gp in enumerate(self._ir_grid_points):
|
||||
for r, r_gp in zip(self._rotations_cartesian, self._rot_grid_points[i]):
|
||||
if ir_gp != r_gp:
|
||||
|
@ -573,13 +581,13 @@ class Conductivity_LBTE(Conductivity):
|
|||
num_band = len(self._pp.primitive) * 3
|
||||
num_mesh_points = np.prod(self._pp.mesh_numbers)
|
||||
|
||||
for j, k in list(np.ndindex((len(self._sigmas), len(self._temperatures)))):
|
||||
for j, k in np.ndindex((len(self._sigmas), len(self._temperatures))):
|
||||
for i in range(num_mesh_points):
|
||||
main_diagonal = self._get_main_diagonal(i, j, k)
|
||||
for ll in range(num_band):
|
||||
self._collision_matrix[j, k, i, ll, i, ll] += main_diagonal[ll]
|
||||
|
||||
def _expand_collisions(self, ir_gr_grid_points, rot_grid_points):
|
||||
def _expand_reducible_collisions(self, ir_gr_grid_points, rot_grid_points):
|
||||
"""Fill elements of full collision matrix by symmetry."""
|
||||
start = time.time()
|
||||
if self._log_level:
|
||||
|
@ -866,12 +874,16 @@ class Conductivity_LBTE(Conductivity):
|
|||
(Y / 2).reshape(num_grid_points, num_band * 3).T / weights
|
||||
).T.reshape(self._f_vectors.shape)
|
||||
|
||||
def _get_eigvals_pinv(self, i_sigma, i_temp):
|
||||
def _get_eigvals_pinv(self, i_sigma, i_temp, take_abs=True):
|
||||
"""Return inverse eigenvalues of eigenvalues > epsilon."""
|
||||
w = self._collision_eigenvalues[i_sigma, i_temp]
|
||||
e = np.zeros_like(w)
|
||||
for ll, val in enumerate(w):
|
||||
if abs(val) > self._pinv_cutoff:
|
||||
if take_abs:
|
||||
_val = abs(val)
|
||||
else:
|
||||
_val = val
|
||||
if _val > self._pinv_cutoff:
|
||||
e[ll] = 1 / val
|
||||
return e
|
||||
|
||||
|
@ -1291,7 +1303,7 @@ def get_thermal_conductivity_LBTE(
|
|||
else:
|
||||
temps = _temperatures
|
||||
|
||||
lbte = Conductivity_LBTE(
|
||||
lbte = ConductivityLBTE(
|
||||
interaction,
|
||||
grid_points=grid_points,
|
||||
temperatures=temps,
|
||||
|
@ -1333,6 +1345,7 @@ def get_thermal_conductivity_LBTE(
|
|||
text = (" %.1f " * len(temps_read)) % tuple(temps_read)
|
||||
print("Temperature: " + text)
|
||||
|
||||
# This computes pieces of collision matrix sequentially.
|
||||
for i in lbte:
|
||||
if write_pp:
|
||||
_write_pp(
|
||||
|
@ -1363,6 +1376,7 @@ def get_thermal_conductivity_LBTE(
|
|||
|
||||
if grid_points is None and all_bands_exist(interaction):
|
||||
lbte.set_kappa_at_sigmas()
|
||||
|
||||
if write_kappa:
|
||||
_write_kappa(
|
||||
lbte,
|
||||
|
@ -1379,17 +1393,17 @@ def get_thermal_conductivity_LBTE(
|
|||
|
||||
|
||||
def _write_collision(
|
||||
lbte,
|
||||
interaction,
|
||||
lbte: ConductivityLBTE,
|
||||
interaction: Interaction,
|
||||
i=None,
|
||||
is_reducible_collision_matrix=False,
|
||||
is_one_gp_colmat=False,
|
||||
filename=None,
|
||||
):
|
||||
grid_points = lbte.get_grid_points()
|
||||
grid_points = lbte.grid_points
|
||||
temperatures = lbte.temperatures
|
||||
sigmas = lbte.get_sigmas()
|
||||
sigma_cutoff = lbte.get_sigma_cutoff_width()
|
||||
sigmas = lbte.sigmas
|
||||
sigma_cutoff = lbte.sigma_cutoff_width
|
||||
gamma = lbte.gamma
|
||||
gamma_isotope = lbte.gamma_isotope
|
||||
collision_matrix = lbte.collision_matrix
|
||||
|
@ -1459,7 +1473,7 @@ def _write_collision(
|
|||
|
||||
|
||||
def _write_kappa(
|
||||
lbte,
|
||||
lbte: ConductivityLBTE,
|
||||
volume,
|
||||
is_reducible_collision_matrix=False,
|
||||
write_LBTE_solution=False,
|
||||
|
|
|
@ -53,7 +53,7 @@ from phono3py.phonon3.triplets import get_all_triplets
|
|||
from phono3py.phonon.grid import get_grid_points_by_rotations
|
||||
|
||||
|
||||
class Conductivity_RTA(Conductivity):
|
||||
class ConductivityRTA(Conductivity):
|
||||
"""Lattice thermal conductivity calculation with RTA."""
|
||||
|
||||
def __init__(
|
||||
|
@ -609,7 +609,7 @@ def get_thermal_conductivity_RTA(
|
|||
"-------------------- Lattice thermal conducitivity (RTA) "
|
||||
"--------------------"
|
||||
)
|
||||
br = Conductivity_RTA(
|
||||
br = ConductivityRTA(
|
||||
interaction,
|
||||
grid_points=grid_points,
|
||||
temperatures=_temperatures,
|
||||
|
|
|
@ -297,8 +297,8 @@ def get_smallest_vector_of_atom_pair(
|
|||
|
||||
|
||||
def _get_orbits(atom_index, cell, site_symmetry, symprec=1e-5):
|
||||
lattice = cell.get_cell().T
|
||||
positions = cell.get_scaled_positions()
|
||||
lattice = cell.cell.T
|
||||
positions = cell.scaled_positions
|
||||
center = positions[atom_index]
|
||||
|
||||
# orbits[num_atoms, num_site_sym]
|
||||
|
|
|
@ -351,9 +351,9 @@ def _get_constrained_fc2(
|
|||
'forces': []}, ...]
|
||||
|
||||
"""
|
||||
lattice = supercell.get_cell().T
|
||||
positions = supercell.get_scaled_positions()
|
||||
num_atom = supercell.get_number_of_atoms()
|
||||
lattice = supercell.cell.T
|
||||
positions = supercell.scaled_positions
|
||||
num_atom = len(supercell)
|
||||
|
||||
fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype="double")
|
||||
atom_list = np.unique([x["number"] for x in dataset_second_atoms])
|
||||
|
@ -427,14 +427,14 @@ def _solve_fc3(
|
|||
print(" [%2d %2d %2d]\n" % tuple(v[2]))
|
||||
sys.stdout.flush()
|
||||
|
||||
lattice = supercell.get_cell().T
|
||||
lattice = supercell.cell.T
|
||||
site_sym_cart = np.array(
|
||||
[similarity_transformation(lattice, sym) for sym in site_symmetry],
|
||||
dtype="double",
|
||||
order="C",
|
||||
)
|
||||
num_atom = supercell.get_number_of_atoms()
|
||||
positions = supercell.get_scaled_positions()
|
||||
num_atom = len(supercell)
|
||||
positions = supercell.scaled_positions
|
||||
pos_center = positions[first_atom_num].copy()
|
||||
positions -= pos_center
|
||||
|
||||
|
@ -655,7 +655,7 @@ def _get_fc3_least_atoms(
|
|||
else:
|
||||
direction = np.dot(
|
||||
dataset_first_atom["displacement"],
|
||||
np.linalg.inv(supercell.get_cell()),
|
||||
np.linalg.inv(supercell.cell),
|
||||
)
|
||||
reduced_site_sym = get_reduced_site_symmetry(
|
||||
site_symmetry, direction, symprec
|
||||
|
|
|
@ -499,7 +499,7 @@ class Interaction:
|
|||
weights_at_q,
|
||||
triplets_map_at_q,
|
||||
ir_map_at_q,
|
||||
) = get_triplets_at_q(grid_point, self._bz_grid)
|
||||
) = get_triplets_at_q(grid_point, self._bz_grid, swappable=True)
|
||||
|
||||
# Special treatment of symmetry is applied when q_direction is
|
||||
# used.
|
||||
|
|
|
@ -131,8 +131,8 @@ def get_nosym_triplets_at_q(grid_point, bz_grid: BZGrid):
|
|||
|
||||
"""
|
||||
map_triplets = np.arange(np.prod(bz_grid.D_diag), dtype="int_")
|
||||
map_q = np.arange(np.prod(bz_grid.D_diag), dtype="int_")
|
||||
triplets_at_q, weights = _get_BZ_triplets_at_q(grid_point, bz_grid, map_triplets)
|
||||
map_q = map_triplets.copy()
|
||||
|
||||
return triplets_at_q, weights, map_triplets, map_q
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ def plot_one_file(ax, args):
|
|||
|
||||
def plot_more(ax, coleigs, temperatures, args):
|
||||
t_index = get_t_index(temperatures[0], args)
|
||||
y = [v[t_index] for v in coleigs]
|
||||
y = [np.abs(v[t_index]) for v in coleigs]
|
||||
ax.semilogy(np.transpose(y), ".", markersize=5)
|
||||
ax.set_xlim(0, len(y[0]))
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
"""Tests for direct solution of LBTE."""
|
||||
import numpy as np
|
||||
|
||||
si_pbesol_kappa_LBTE = [111.802, 111.802, 111.802, 0, 0, 0]
|
||||
si_pbesol_kappa_LBTE_redcol = [61.3504328, 61.3504328, 61.3504328, 0, 0, 0]
|
||||
from phono3py.api_phono3py import Phono3py
|
||||
|
||||
si_pbesol_kappa_LBTE = [111.117, 111.117, 111.117, 0, 0, 0]
|
||||
si_pbesol_kappa_LBTE_redcol = [63.019, 63.019, 63.019, 0, 0, 0]
|
||||
|
||||
|
||||
def test_kappa_LBTE(si_pbesol):
|
||||
def test_kappa_LBTE(si_pbesol: Phono3py):
|
||||
"""Test for symmetry reduced collision matrix."""
|
||||
si_pbesol.mesh_numbers = [9, 9, 9]
|
||||
si_pbesol.init_phph_interaction()
|
||||
|
@ -19,7 +21,7 @@ def test_kappa_LBTE(si_pbesol):
|
|||
np.testing.assert_allclose(si_pbesol_kappa_LBTE, kappa, atol=0.5)
|
||||
|
||||
|
||||
def test_kappa_LBTE_full_colmat(si_pbesol):
|
||||
def test_kappa_LBTE_full_colmat(si_pbesol: Phono3py):
|
||||
"""Test for full collision matrix."""
|
||||
si_pbesol.mesh_numbers = [5, 5, 5]
|
||||
si_pbesol.init_phph_interaction()
|
||||
|
|
Loading…
Reference in New Issue