Merge branch 'master' into rcb-tiled-tri

This commit is contained in:
Axel Kohlmeyer
2020-07-29 20:37:28 -04:00
20 changed files with 5412 additions and 4908 deletions

View File

@ -916,6 +916,7 @@ void CommTiled::borders()
// swap atoms with other procs using pack_border(), unpack_border()
// use Waitall() instead of Waitany() because calls to unpack_border()
// must increment per-atom arrays in ascending order
// For the same reason, sendself unpacks must occur after recvother unpacks
if (ghost_velocity) {
if (recvother[iswap]) {
@ -931,13 +932,6 @@ void CommTiled::borders()
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][m],0,world);
}
}
if (sendself[iswap]) {
avec->pack_border_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
buf_send,pbc_flag[iswap][nsend],
pbc[iswap][nsend]);
avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
buf_send);
}
if (recvother[iswap]) {
MPI_Waitall(nrecv,requests,MPI_STATUS_IGNORE);
for (m = 0; m < nrecv; m++)
@ -945,6 +939,13 @@ void CommTiled::borders()
&buf_recv[size_border*
forward_recv_offset[iswap][m]]);
}
if (sendself[iswap]) {
avec->pack_border_vel(sendnum[iswap][nsend],sendlist[iswap][nsend],
buf_send,pbc_flag[iswap][nsend],
pbc[iswap][nsend]);
avec->unpack_border_vel(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
buf_send);
}
} else {
if (recvother[iswap]) {
@ -960,12 +961,6 @@ void CommTiled::borders()
MPI_Send(buf_send,n,MPI_DOUBLE,sendproc[iswap][m],0,world);
}
}
if (sendself[iswap]) {
avec->pack_border(sendnum[iswap][nsend],sendlist[iswap][nsend],
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
avec->unpack_border(recvnum[iswap][nsend],firstrecv[iswap][nsend],
buf_send);
}
if (recvother[iswap]) {
MPI_Waitall(nrecv,requests,MPI_STATUS_IGNORE);
for (m = 0; m < nrecv; m++)
@ -973,6 +968,12 @@ void CommTiled::borders()
&buf_recv[size_border*
forward_recv_offset[iswap][m]]);
}
if (sendself[iswap]) {
avec->pack_border(sendnum[iswap][nsend],sendlist[iswap][nsend],
buf_send,pbc_flag[iswap][nsend],pbc[iswap][nsend]);
avec->unpack_border(recvnum[iswap][nrecv],firstrecv[iswap][nrecv],
buf_send);
}
}
// increment ghost atoms

View File

@ -1,30 +1,37 @@
.SUFFIXES : .o .cpp
# compiler and flags
CC = g++ -Wall
LINK = $(CC)
CC = g++ -Wno-unused-result
LINK = $(CC) -static
CFLAGS = -O3 $(DEBUG) $(UFLAG)
#
OFLAGS = -O3 $(DEBUG)
INC = $(LPKINC) $(TCINC) $(SPGINC)
LIB = $(LPKLIB) $(TCLIB) $(SPGLIB)
#
INC = $(LPKINC) $(TCINC) $(SPGINC) $(FFTINC)
LIB = $(LPKLIB) $(TCLIB) $(SPGLIB) $(FFTLIB)
# cLapack library needed
LPKINC =
LPKLIB =-llapack
#
#
# spglib 1.8.2, used to get the irreducible q-points
# if UFLAG is not set, spglib won't be used.
LPKINC = -I/opt/clapack/3.2.1/include
LPKLIB = -L/opt/clapack/3.2.1/lib -lclapack -lblas -lf2c -lm
# UFLAG = -DUseSPG
# SPGINC = -I/opt/libs/spglib/1.8.2/include
# SPGLIB = -L/opt/libs/spglib/1.8.2/lib -lsymspg
# Tricubic library needed
TCINC = -I/opt/tricubic/1.0/include
TCLIB = -L/opt/tricubic/1.0/lib -ltricubic
# if spglib other than version 1.8.2 is used, please
# modify file phonon.cpp, instruction can be found by searching 1.8.2
# spglib, used to get the irreducible q-points
# if SFLAG is not set, spglib won't be used.
SFLAG = -DUseSPG
SPGINC = -I/opt/spglib/1.9.7/include/spglib
SPGLIB = -L/opt/spglib/1.9.7/lib -lsymspg
# FFTW 3 used to deduce the force constants in real space
# if FFLAG is not set, fftw won't be used.
FFLAG = -DFFTW3
FFTINC = -I/opt/fftw/3.3.7/include
FFTLIB = -L/opt/fftw/3.3.7/lib -lfftw3
# Debug flags
#DEBUG = -g -DDEBUG
# DEBUG = -g -DDEBUG
UFLAG = $(SFLAG) $(FFLAG)
#====================================================================
ROOT = phana
# executable name
@ -44,7 +51,7 @@ clean:
rm -f *.o *~ *.mod ${EXE}
tar:
rm -f ${ROOT}.tar; tar -czvf ${ROOT}.tar.gz *.cpp *.h Makefile README
rm -f ${ROOT}.tar.gz; tar -czvf ${ROOT}.tar.gz *.cpp *.h Makefile README
ver:
@echo "#define VERSION `git log|grep '^commit'|wc -l`" > version.h
@ -58,16 +65,3 @@ ver:
$(CC) $(CFLAGS) -c $<
.cpp.o:
$(CC) $(CFLAGS) $(INC) -c $<
#====================================================================
# dependencies
disp.o: disp.cpp phonon.h dynmat.h memory.h interpolate.h green.h timer.h \
global.h
dynmat.o: dynmat.cpp dynmat.h memory.h interpolate.h version.h global.h
green.o: green.cpp green.h memory.h global.h
interpolate.o: interpolate.cpp interpolate.h memory.h global.h
main.o: main.cpp dynmat.h memory.h interpolate.h phonon.h
memory.o: memory.cpp memory.h
phonon.o: phonon.cpp phonon.h dynmat.h memory.h interpolate.h green.h \
timer.h global.h
timer.o: timer.cpp timer.h

View File

@ -5,9 +5,13 @@
analyse the phonon related information.
#-------------------------------------------------------------------------------
1. Dependencies
The LAPACK library is needed to solve the eigen problems.
http://www.netlib.org/lapack/
Intel MKL can be used as well.
The clapack library is needed to solve the eigen problems,
which could be downloaded from:
http://www.netlib.org/clapack/
The tricubic library is also needed to do tricubic interpolations,
which could now be obtained from:
https://github.com/nbigaouette/libtricubic/
The spglib is optionally needed, enabling one to evaluate the
phonon density of states or vibrational thermal properties
@ -17,6 +21,12 @@
It can be obtained from:
http://spglib.sourceforge.net/
FFTW 3 might also be needed if you would like to interface with
phonopy: necessary input files for phonopy will be prepared so
that you can make use of the functions provided by phonopy.
FFTW 3 can be downloaded from:
http://www.fftw.org
2. Compilation
To compile the code, one needs therefore to install the above
libraries and set the paths correctly in the Makefile.
@ -26,17 +36,16 @@
3. Unit system
The units of the output frequencies by this code is THz for
LAMMPS units "real", "si", "metal", and "cgs"; in these cases,
the frequencies are $\nu$ instead of $\omega$.
LAMMPS units "real", "si", "metal", "cgs", "micro", "nano";
in these cases, the frequencies are $\nu$ instead of $\omega$.
4. Updates
For updates of phana, please check:
http://nes.sjtu.edu.cn/english/research/software.htm
or
https://github.com/lingtikong/phana.git
5. Bug report
If any bug found, please drop a line to: konglt(at)sjtu.edu.cn
#-------------------------------------------------------------------------------
Author: Ling-Ti Kong, konglt(at)sjtu.edu.cn
Oct 2015
May 2020

File diff suppressed because it is too large Load Diff

View File

@ -3,12 +3,10 @@
#include "version.h"
#include "global.h"
extern "C" void zheevd_(char *, char *, long int *, doublecomplex *,
long int *, double *, doublecomplex *,
long int *, double *, long int *, long int *,
long int *, long int *);
// to initialize the class
/* ----------------------------------------------------------------------------
* Class DynMat stores the Dynamic Matrix read from the binary file from
* fix-phonon and incorporates some operations w.r.t the DM.
* ---------------------------------------------------------------------------- */
DynMat::DynMat(int narg, char **arg)
{
attyp = NULL;
@ -69,42 +67,48 @@ DynMat::DynMat(int narg, char **arg)
}
// read header info from the binary file
if ( fread(&sysdim, sizeof(int), 1, fp) != 1) {printf("\nError while reading sysdim from file: %s\n", binfile); fclose(fp); exit(2);}
if ( fread(&nx, sizeof(int), 1, fp) != 1) {printf("\nError while reading nx from file: %s\n", binfile); fclose(fp); exit(2);}
if ( fread(&ny, sizeof(int), 1, fp) != 1) {printf("\nError while reading ny from file: %s\n", binfile); fclose(fp); exit(2);}
if ( fread(&nz, sizeof(int), 1, fp) != 1) {printf("\nError while reading nz from file: %s\n", binfile); fclose(fp); exit(2);}
if ( fread(&nucell, sizeof(int), 1, fp) != 1) {printf("\nError while reading nucell from file: %s\n", binfile); fclose(fp); exit(2);}
if ( fread(&boltz, sizeof(double), 1, fp) != 1) {printf("\nError while reading boltz from file: %s\n", binfile); fclose(fp); exit(2);}
if (fread(&sysdim, sizeof(int), 1, fp) != 1){
printf("\nError while reading sysdim from file: %s\n", binfile);
fclose(fp);
exit(2);
}
if (fread(&nx, sizeof(int), 1, fp) != 1){
printf("\nError while reading nx from file: %s\n", binfile);
fclose(fp);
exit(2);
}
if (fread(&ny, sizeof(int), 1, fp) != 1){
printf("\nError while reading ny from file: %s\n", binfile);
fclose(fp);
exit(2);
}
if (fread(&nz, sizeof(int), 1, fp) != 1){
printf("\nError while reading nz from file: %s\n", binfile);
fclose(fp);
exit(2);
}
if (fread(&nucell, sizeof(int), 1, fp) != 1){
printf("\nError while reading nucell from file: %s\n", binfile);
fclose(fp);
exit(2);
}
if (fread(&boltz, sizeof(double), 1, fp) != 1){
printf("\nError while reading boltz from file: %s\n", binfile);
fclose(fp);
exit(2);
}
fftdim = sysdim*nucell; fftdim2 = fftdim*fftdim;
npt = nx*ny*nz;
fftdim = sysdim * nucell;
fftdim2 = fftdim * fftdim;
npt = nx * ny * nz;
// display info related to the read file
printf("\n"); for (int i = 0; i < 80; ++i) printf("="); printf("\n");
printf("Dynamical matrix is read from file: %s\n", binfile);
printf("The system size in three dimension: %d x %d x %d\n", nx, ny, nz);
printf("Number of atoms per unit cell : %d\n", nucell);
printf("System dimension : %d\n", sysdim);
printf("Boltzmann constant in used units : %g\n", boltz);
for (int i = 0; i < 80; ++i) printf("=");
printf("\n");
ShowInfo();
if (sysdim < 1||sysdim > 3||nx < 1||ny < 1||nz < 1||nucell < 1){
printf("Wrong values read from header of file: %s, please check the binary file!\n", binfile);
fclose(fp); exit(3);
}
funit = new char[4];
strcpy(funit, "THz");
if (boltz == 1.){eml2f = 1.; delete funit; funit = new char[27]; strcpy(funit,"sqrt(epsilon/(m.sigma^2))");}
else if (boltz == 0.0019872067) eml2f = 3.256576161;
else if (boltz == 8.617343e-5) eml2f = 15.63312493;
else if (boltz == 1.3806504e-23) eml2f = 1.;
else if (boltz == 1.3806504e-16) eml2f = 1.591549431e-14;
else {
printf("WARNING: Because of float precision, I cannot get the factor to convert sqrt(E/ML^2)\n");
printf("into THz, instead, I set it to be 1; you should check the unit used by LAMMPS.\n");
eml2f = 1.;
}
Define_Conversion_Factor();
// now to allocate memory for DM
memory = new Memory();
@ -112,7 +116,7 @@ DynMat::DynMat(int narg, char **arg)
memory->create(DM_q, fftdim,fftdim,"DynMat:DM_q");
// read all dynamical matrix info into DM_all
if ( fread(DM_all[0], sizeof(doublecomplex), npt*fftdim2, fp) != size_t(npt*fftdim2)){
if (fread(DM_all[0], sizeof(doublecomplex), npt*fftdim2, fp) != size_t(npt*fftdim2)){
printf("\nError while reading the DM from file: %s\n", binfile);
fclose(fp);
exit(1);
@ -123,11 +127,31 @@ DynMat::DynMat(int narg, char **arg)
memory->create(attyp, nucell, "DynMat:attyp");
memory->create(M_inv_sqrt, nucell, "DynMat:M_inv_sqrt");
if ( (int) fread(&Tmeasure, sizeof(double), 1, fp) != 1 ){printf("\nError while reading temperature from file: %s\n", binfile); fclose(fp); exit(3);}
if ( (int) fread(&basevec[0], sizeof(double), 9, fp) != 9 ){printf("\nError while reading lattice info from file: %s\n", binfile); fclose(fp); exit(3);}
if ( (int) fread(basis[0], sizeof(double), fftdim, fp) != fftdim){printf("\nError while reading basis info from file: %s\n", binfile); fclose(fp); exit(3);}
if ( (int) fread(&attyp[0], sizeof(int), nucell, fp) != nucell){printf("\nError while reading atom types from file: %s\n", binfile); fclose(fp); exit(3);}
if ( (int) fread(&M_inv_sqrt[0], sizeof(double), nucell, fp) != nucell){printf("\nError while reading atomic masses from file: %s\n", binfile); fclose(fp); exit(3);}
if (fread(&Tmeasure, sizeof(double), 1, fp) != 1){
printf("\nError while reading temperature from file: %s\n", binfile);
fclose(fp);
exit(3);
}
if (fread(&basevec[0], sizeof(double), 9, fp) != 9){
printf("\nError while reading lattice info from file: %s\n", binfile);
fclose(fp);
exit(3);
}
if (fread(basis[0], sizeof(double), fftdim, fp) != fftdim){
printf("\nError while reading basis info from file: %s\n", binfile);
fclose(fp);
exit(3);
}
if (fread(&attyp[0], sizeof(int), nucell, fp) != nucell){
printf("\nError while reading atom types from file: %s\n", binfile);
fclose(fp);
exit(3);
}
if (fread(&M_inv_sqrt[0], sizeof(double), nucell, fp) != nucell){
printf("\nError while reading atomic masses from file: %s\n", binfile);
fclose(fp);
exit(3);
}
fclose(fp);
car2dir();
@ -145,7 +169,7 @@ DynMat::DynMat(int narg, char **arg)
int ndim =0;
for (int idim = 0; idim < fftdim; ++idim)
for (int jdim = 0; jdim < fftdim; ++jdim){
double inv_mass = M_inv_sqrt[idim/sysdim]*M_inv_sqrt[jdim/sysdim];
double inv_mass = M_inv_sqrt[idim/sysdim] * M_inv_sqrt[jdim/sysdim];
DM_all[idq][ndim].r *= inv_mass;
DM_all[idq][ndim].i *= inv_mass;
ndim++;
@ -158,7 +182,10 @@ DynMat::DynMat(int narg, char **arg)
return;
}
// to destroy the class
/* ----------------------------------------------------------------------------
* Free the memories used.
* ---------------------------------------------------------------------------- */
DynMat::~DynMat()
{
// destroy all memory allocated
@ -172,7 +199,9 @@ DynMat::~DynMat()
memory->destroy(basis);
memory->destroy(DM_all);
memory->destroy(M_inv_sqrt);
if (memory) delete memory;
delete memory;
return;
}
/* ----------------------------------------------------------------------------
@ -209,7 +238,8 @@ void DynMat::writeDMq(double *q)
}
fprintf(fp,"\n");
fclose(fp);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -217,14 +247,13 @@ return;
* ---------------------------------------------------------------------------- */
void DynMat::writeDMq(double *q, const double qr, FILE *fp)
{
fprintf(fp, "%lg %lg %lg %lg ", q[0], q[1], q[2], qr);
for (int i = 0; i < fftdim; ++i)
for (int j = 0; j < fftdim; ++j) fprintf(fp,"%lg %lg\t", DM_q[i][j].r, DM_q[i][j].i);
fprintf(fp,"\n");
return;
return;
}
/* ----------------------------------------------------------------------------
@ -235,9 +264,9 @@ return;
int DynMat::geteigen(double *egv, int flag)
{
char jobz, uplo;
long int n, lda, lwork, lrwork, *iwork, liwork, info;
integer n, lda, lwork, lrwork, *iwork, liwork, info;
doublecomplex *work;
double *w = &egv[0], *rwork;
doublereal *w = &egv[0], *rwork;
n = fftdim;
if (flag) jobz = 'V';
@ -267,7 +296,7 @@ int DynMat::geteigen(double *egv, int flag)
memory->destroy(rwork);
memory->destroy(iwork);
return info;
return info;
}
/* ----------------------------------------------------------------------------
@ -276,7 +305,8 @@ return info;
void DynMat::getDMq(double *q)
{
interpolate->execute(q, DM_q[0]);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -287,7 +317,7 @@ void DynMat::getDMq(double *q, double *wt)
interpolate->execute(q, DM_q[0]);
if (flag_skip && interpolate->UseGamma ) wt[0] = 0.;
return;
return;
}
/* ----------------------------------------------------------------------------
@ -307,7 +337,7 @@ void DynMat::car2dir()
basis[i][idim] = x[0]*mat[idim] + x[1]*mat[3+idim] + x[2]*mat[6+idim];
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -344,8 +374,7 @@ void DynMat::EnforceASR()
char *ptr = strtok(str," \t\n\r\f");
if (ptr) nasr = atoi(ptr);
if (nasr < 1){
for (int i=0; i<80; i++) printf("=");
printf("\n");
for (int i=0; i<80; i++) printf("="); printf("\n");
return;
}
@ -408,13 +437,12 @@ void DynMat::EnforceASR()
for (int i = 0; i < fftdim; ++i){
printf("%lg ", egvs[i]);
if (i%10 == 9) printf("\n");
if (i == 99){ printf("...... (%d more skipped)", fftdim-100); break;}
if (i == 99){ printf("...... (%d more skiped)", fftdim-100); break;}
}
printf("\n");
for (int i = 0; i < 80; ++i) printf("=");
printf("\n\n");
for (int i = 0; i < 80; ++i) printf("="); printf("\n\n");
return;
return;
}
/* ----------------------------------------------------------------------------
@ -453,7 +481,7 @@ void DynMat::real2rec()
}
printf("\n"); for (int i = 0; i < 80; ++i) printf("="); printf("\n");
return;
return;
}
/* ----------------------------------------------------------------------
@ -464,7 +492,7 @@ return;
* --------------------------------------------------------------------*/
void DynMat::GaussJordan(int n, double *Mat)
{
int i,icol=0,irow=0,j,k,l,ll,idr,idc;
int i,icol,irow,j,k,l,ll,idr,idc;
int *indxc,*indxr,*ipiv;
double big, nmjk;
double dum, pivinv;
@ -542,7 +570,7 @@ void DynMat::GaussJordan(int n, double *Mat)
delete []indxc;
delete []ipiv;
return;
return;
}
/* ----------------------------------------------------------------------------
@ -552,7 +580,7 @@ void DynMat::reset_interp_method()
{
interpolate->set_method();
return;
return;
}
/* ----------------------------------------------------------------------------
@ -591,7 +619,74 @@ void DynMat::ShowVersion()
printf(" )___/ ) _ ( /(__)\\ ) ( /(__)\\ \n");
printf(" (__) (_) (_)(__)(__)(_)\\_)(__)(__)\n");
printf("\nPHonon ANAlyzer for Fix-Phonon, version 2.%02d, compiled on %s.\n", VERSION, __DATE__);
printf("Reference: https://doi.org/10.1016/j.cpc.2011.04.019\n");
return;
return;
}
/* ----------------------------------------------------------------------------
* Private method to define the conversion factor from the DM measured to THZ
* for the phonon frequency and force constants.
* ---------------------------------------------------------------------------- */
void DynMat::Define_Conversion_Factor()
{
funit = new char[4];
strcpy(funit, "THz");
if (fabs(boltz - 1.) <= ZERO){ // LJ Unit
eml2f = eml2fc = 1.;
delete funit;
funit = new char[27];
strcpy(funit,"sqrt(epsilon/(m.sigma^2))");
} else if (fabs(boltz - 0.0019872067) <= ZERO){ // real
eml2f = 3.255487031;
eml2fc = 0.0433641042418;
} else if (fabs(boltz*1.e3 - 8.617343e-2) <= ZERO){ // metal
eml2f = 15.633304237154924;
eml2fc = 1.;
} else if (fabs(boltz*1.e20 - 1.3806504e-3) <= ZERO){ // si
eml2f = 1.591549431e-13;
eml2fc = 0.06241509074460763;
} else if (fabs(boltz*1.e13 - 1.3806504e-3) <= ZERO){ // cgs
eml2f = 1.591549431e-13;
eml2fc = 6.241509074460763e-05;
} else if (fabs(boltz*1.e3 - 3.16681534e-3) <= ZERO){ // electron
eml2f = 154.10792761319672;
eml2fc = 97.1736242922823;
} else if (fabs(boltz*1.e5 - 1.3806504e-3) <= ZERO){ // micro
eml2f = 1.5915494309189532e-07;
eml2fc = 6.241509074460763e-05;
} else if (fabs(boltz - 0.013806504) <= ZERO){ // nano
eml2f = 0.0001591549431;
eml2fc = 6.241509074460763e-05;
} else {
printf("WARNING: Perhaps because of float precision, I cannot get the factor to convert\n");
printf("sqrt(E/ML^2)/(2*pi) into THz, instead, I set it to 1; you should check the unit\nused by LAMMPS.\n");
eml2f = eml2fc = 1.;
}
return;
}
/* ----------------------------------------------------------------------------
* Private method to output the information read
* ---------------------------------------------------------------------------- */
void DynMat::ShowInfo()
{
printf("\n"); for (int i = 0; i < 80; ++i) printf("="); printf("\n");
printf("Dynamical matrix is read from file: %s\n", binfile);
printf("The system size in three dimension: %d x %d x %d\n", nx, ny, nz);
printf("Number of atoms per unit cell : %d\n", nucell);
printf("System dimension : %d\n", sysdim);
printf("Boltzmann constant in used units : %g\n", boltz);
for (int i = 0; i < 80; ++i) printf("="); printf("\n");
return;
}
/* --------------------------------------------------------------------*/

View File

@ -7,8 +7,6 @@
#include "memory.h"
#include "interpolate.h"
using namespace std;
class DynMat {
public:
@ -17,7 +15,7 @@ public:
int nx, ny, nz, nucell;
int sysdim, fftdim;
double eml2f;
double eml2f, eml2fc;
char *funit;
void getDMq(double *);
@ -30,7 +28,9 @@ public:
doublecomplex **DM_q;
int flag_latinfo;
int npt, fftdim2;
double Tmeasure, basevec[9], ibasevec[9];
double *M_inv_sqrt;
double **basis;
int *attyp;
@ -40,14 +40,12 @@ private:
Interpolate *interpolate;
Memory *memory;
int npt, fftdim2;
int nasr;
void EnforceASR();
char *binfile, *dmfile;
double boltz, q[3];
double *M_inv_sqrt;
doublecomplex **DM_all;
@ -56,6 +54,8 @@ private:
void GaussJordan(int, double *);
void help();
void ShowInfo();
void ShowVersion();
void Define_Conversion_Factor();
};
#endif

View File

@ -67,7 +67,7 @@ Green::Green(const int ntm, const int sdim, const int niter, const double min, c
// Get the inverser of the treated hessian by continued fractional method
Recursion();
return;
return;
}
/*------------------------------------------------------------------------------
@ -82,7 +82,7 @@ Green::~Green()
delete memory;
return;
return;
}
/*------------------------------------------------------------------------------
@ -136,11 +136,11 @@ void Green::Lanczos()
delete []v;
delete []w;
return;
return;
}
/*------------------------------------------------------------------------------
* Private method to compute the LDOS via the recursive method for system with
* Private method to compute the LDOS via the recusive method for system with
* many atoms
*----------------------------------------------------------------------------*/
void Green::Recursion()
@ -213,17 +213,18 @@ void Green::Recursion()
delete []xmin;
delete []xmax;
return;
return;
}
/*------------------------------------------------------------------------------
* Private method to compute the LDOS via the recursive method for system with
* Private method to compute the LDOS via the recusive method for system with
* a few atoms (less than NMAX)
*----------------------------------------------------------------------------*/
void Green::recursion()
{
// local variables
std::complex<double> Z, rec_x, rec_x_inv;
std::complex<double> cunit = std::complex<double>(0.,1.);
double w = wmin;
@ -241,8 +242,7 @@ void Green::recursion()
}
w += dw;
}
return;
return;
}
/*------------------------------------------------------------------------------*/

View File

@ -1,125 +1,7 @@
#include "interpolate.h"
#include <math.h>
#include "math.h"
#include "global.h"
///////////////////////
// tricubic library code
static int A[64][64] = {
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{-3, 3, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 2,-2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 9,-9,-9, 9, 0, 0, 0, 0, 6, 3,-6,-3, 0, 0, 0, 0, 6,-6, 3,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{-6, 6, 6,-6, 0, 0, 0, 0,-3,-3, 3, 3, 0, 0, 0, 0,-4, 4,-2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-2,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{-6, 6, 6,-6, 0, 0, 0, 0,-4,-2, 4, 2, 0, 0, 0, 0,-3, 3,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 4,-4,-4, 4, 0, 0, 0, 0, 2, 2,-2,-2, 0, 0, 0, 0, 2,-2, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-9,-9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3,-6,-3, 0, 0, 0, 0, 6,-6, 3,-3, 0, 0, 0, 0, 4, 2, 2, 1, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3,-3, 3, 3, 0, 0, 0, 0,-4, 4,-2, 2, 0, 0, 0, 0,-2,-2,-1,-1, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4,-2, 4, 2, 0, 0, 0, 0,-3, 3,-3, 3, 0, 0, 0, 0,-2,-1,-2,-1, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,-4,-4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,-2,-2, 0, 0, 0, 0, 2,-2, 2,-2, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0},
{-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 9,-9, 0, 0,-9, 9, 0, 0, 6, 3, 0, 0,-6,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-6, 0, 0, 3,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{-6, 6, 0, 0, 6,-6, 0, 0,-3,-3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 4, 0, 0,-2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-2, 0, 0,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-9, 0, 0,-9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0, 0,-6,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-6, 0, 0, 3,-3, 0, 0, 4, 2, 0, 0, 2, 1, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 0, 0, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3,-3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 4, 0, 0,-2, 2, 0, 0,-2,-2, 0, 0,-1,-1, 0, 0},
{ 9, 0,-9, 0,-9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0,-6, 0,-3, 0, 6, 0,-6, 0, 3, 0,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,-9, 0,-9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0,-6, 0,-3, 0, 6, 0,-6, 0, 3, 0,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 2, 0, 1, 0},
{-27,27,27,-27,27,-27,-27,27,-18,-9,18, 9,18, 9,-18,-9,-18,18,-9, 9,18,-18, 9,-9,-18,18,18,-18,-9, 9, 9,-9,-12,-6,-6,-3,12, 6, 6, 3,-12,-6,12, 6,-6,-3, 6, 3,-12,12,-6, 6,-6, 6,-3, 3,-8,-4,-4,-2,-4,-2,-2,-1},
{18,-18,-18,18,-18,18,18,-18, 9, 9,-9,-9,-9,-9, 9, 9,12,-12, 6,-6,-12,12,-6, 6,12,-12,-12,12, 6,-6,-6, 6, 6, 6, 3, 3,-6,-6,-3,-3, 6, 6,-6,-6, 3, 3,-3,-3, 8,-8, 4,-4, 4,-4, 2,-2, 4, 4, 2, 2, 2, 2, 1, 1},
{-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0,-3, 0, 3, 0, 3, 0,-4, 0, 4, 0,-2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-2, 0,-1, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0,-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0,-3, 0, 3, 0, 3, 0,-4, 0, 4, 0,-2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-2, 0,-1, 0,-1, 0},
{18,-18,-18,18,-18,18,18,-18,12, 6,-12,-6,-12,-6,12, 6, 9,-9, 9,-9,-9, 9,-9, 9,12,-12,-12,12, 6,-6,-6, 6, 6, 3, 6, 3,-6,-3,-6,-3, 8, 4,-8,-4, 4, 2,-4,-2, 6,-6, 6,-6, 3,-3, 3,-3, 4, 2, 4, 2, 2, 1, 2, 1},
{-12,12,12,-12,12,-12,-12,12,-6,-6, 6, 6, 6, 6,-6,-6,-6, 6,-6, 6, 6,-6, 6,-6,-8, 8, 8,-8,-4, 4, 4,-4,-3,-3,-3,-3, 3, 3, 3, 3,-4,-4, 4, 4,-2,-2, 2, 2,-4, 4,-4, 4,-2, 2,-2, 2,-2,-2,-2,-2,-1,-1,-1,-1},
{ 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{-6, 6, 0, 0, 6,-6, 0, 0,-4,-2, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 4,-4, 0, 0,-4, 4, 0, 0, 2, 2, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 0, 0, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4,-2, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-3, 3, 0, 0,-2,-1, 0, 0,-2,-1, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,-4, 0, 0,-4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0},
{-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 0,-2, 0, 4, 0, 2, 0,-3, 0, 3, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0,-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 0,-2, 0, 4, 0, 2, 0,-3, 0, 3, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0,-2, 0,-1, 0},
{18,-18,-18,18,-18,18,18,-18,12, 6,-12,-6,-12,-6,12, 6,12,-12, 6,-6,-12,12,-6, 6, 9,-9,-9, 9, 9,-9,-9, 9, 8, 4, 4, 2,-8,-4,-4,-2, 6, 3,-6,-3, 6, 3,-6,-3, 6,-6, 3,-3, 6,-6, 3,-3, 4, 2, 2, 1, 4, 2, 2, 1},
{-12,12,12,-12,12,-12,-12,12,-6,-6, 6, 6, 6, 6,-6,-6,-8, 8,-4, 4, 8,-8, 4,-4,-6, 6, 6,-6,-6, 6, 6,-6,-4,-4,-2,-2, 4, 4, 2, 2,-3,-3, 3, 3,-3,-3, 3, 3,-4, 4,-2, 2,-4, 4,-2, 2,-2,-2,-1,-1,-2,-2,-1,-1},
{ 4, 0,-4, 0,-4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,-2, 0,-2, 0, 2, 0,-2, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,-4, 0,-4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,-2, 0,-2, 0, 2, 0,-2, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0},
{-12,12,12,-12,12,-12,-12,12,-8,-4, 8, 4, 8, 4,-8,-4,-6, 6,-6, 6, 6,-6, 6,-6,-6, 6, 6,-6,-6, 6, 6,-6,-4,-2,-4,-2, 4, 2, 4, 2,-4,-2, 4, 2,-4,-2, 4, 2,-3, 3,-3, 3,-3, 3,-3, 3,-2,-1,-2,-1,-2,-1,-2,-1},
{ 8,-8,-8, 8,-8, 8, 8,-8, 4, 4,-4,-4,-4,-4, 4, 4, 4,-4, 4,-4,-4, 4,-4, 4, 4,-4,-4, 4, 4,-4,-4, 4, 2, 2, 2, 2,-2,-2,-2,-2, 2, 2,-2,-2, 2, 2,-2,-2, 2,-2, 2,-2, 2,-2, 2,-2, 1, 1, 1, 1, 1, 1, 1, 1}};
static int ijk2n(int i, int j, int k) {
return(i+4*j+16*k);
}
/* ---------------------------------------------------------------------------- */
static void tricubic_get_coeff_stacked(double a[64], double x[64]) {
int i,j;
for (i=0;i<64;i++) {
a[i]=(double)(0.0);
for (j=0;j<64;j++) {
a[i]+=A[i][j]*x[j];
}
}
}
static void tricubic_get_coeff(double a[64], double f[8], double dfdx[8], double dfdy[8], double dfdz[8], double d2fdxdy[8], double d2fdxdz[8], double d2fdydz[8], double d3fdxdydz[8]) {
int i;
double x[64];
for (i=0;i<8;i++) {
x[0+i]=f[i];
x[8+i]=dfdx[i];
x[16+i]=dfdy[i];
x[24+i]=dfdz[i];
x[32+i]=d2fdxdy[i];
x[40+i]=d2fdxdz[i];
x[48+i]=d2fdydz[i];
x[56+i]=d3fdxdydz[i];
}
tricubic_get_coeff_stacked(a,x);
}
static double tricubic_eval(double a[64], double x, double y, double z) {
int i,j,k;
double ret=(double)(0.0);
/* TRICUBIC EVAL
This is the short version of tricubic_eval. It is used to compute
the value of the function at a given point (x,y,z). To compute
partial derivatives of f, use the full version with the extra args.
*/
for (i=0;i<4;i++) {
for (j=0;j<4;j++) {
for (k=0;k<4;k++) {
ret+=a[ijk2n(i,j,k)]*pow(x,i)*pow(y,j)*pow(z,k);
}
}
}
return(ret);
}
/* ----------------------------------------------------------------------------
* Constructor used to get info from caller, and prepare other necessary data
* ---------------------------------------------------------------------------- */
@ -138,7 +20,7 @@ Interpolate::Interpolate(int nx, int ny, int nz, int ndm, doublecomplex **DM)
Dfdx = Dfdy = Dfdz = D2fdxdy = D2fdxdz = D2fdydz = D3fdxdydz = NULL;
flag_reset_gamma = flag_allocated_dfs = 0;
return;
return;
}
/* ----------------------------------------------------------------------------
@ -165,7 +47,6 @@ void Interpolate::tricubic_init()
for (int ii = 0; ii < Nx; ++ii)
for (int jj = 0; jj < Ny; ++jj)
for (int kk = 0; kk < Nz; ++kk){
int ip = (ii+1)%Nx, jp = (jj+1)%Ny, kp = (kk+1)%Nz;
int im = (ii-1+Nx)%Nx, jm = (jj-1+Ny)%Ny, km = (kk-1+Nz)%Nz;
@ -216,7 +97,7 @@ void Interpolate::tricubic_init()
}
n++;
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -233,6 +114,8 @@ Interpolate::~Interpolate()
memory->destroy(D2fdydz);
memory->destroy(D3fdxdydz);
delete memory;
return;
}
/* ----------------------------------------------------------------------------
@ -292,8 +175,7 @@ void Interpolate::tricubic(double *qin, doublecomplex *DMq)
tricubic_get_coeff(&a[0],&f[0],&dfdx[0],&dfdy[0],&dfdz[0],&d2fdxdy[0],&d2fdxdz[0],&d2fdydz[0],&d3fdxdydz[0]);
DMq[idim].i = tricubic_eval(&a[0],x,y,z);
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -328,7 +210,7 @@ void Interpolate::trilinear(double *qin, doublecomplex *DMq)
y = q[1] - double(iy);
z = q[2] - double(iz);
//--------------------------------------
//--------------------------------------
vidx[0] = ((ix*Ny)+iy)*Nz + iz;
vidx[1] = ((ixp*Ny)+iy)*Nz + iz;
vidx[2] = ((ix*Ny)+iyp)*Nz + iz;
@ -359,7 +241,7 @@ void Interpolate::trilinear(double *qin, doublecomplex *DMq)
}
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -372,7 +254,8 @@ void Interpolate::execute(double *qin, doublecomplex *DMq)
tricubic(qin, DMq);
else // otherwise: trilinear
trilinear(qin, DMq);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -392,12 +275,11 @@ void Interpolate::set_method()
which =2-im%2;
printf("Your selection: %d\n", which);
for(int i=0; i<80; i++) printf("=");
printf("\n\n");
for(int i=0; i<80; i++) printf("="); printf("\n\n");
if (which == 1) tricubic_init();
return;
return;
}
/* ----------------------------------------------------------------------------
@ -417,11 +299,12 @@ void Interpolate::reset_gamma()
double const one6 = -1./6., two3 = 2./3.;
for (int idim=0; idim<ndim; idim++){
for (int idim=0; idim < ndim; idim++){
data[0][idim].i = 0.;
data[0][idim].r = (data[im2][idim].r + data[ip2][idim].r) * one6
+ (data[im1][idim].r + data[ip1][idim].r) * two3;
}
return;
return;
}
/* ---------------------------------------------------------------------------- */

View File

@ -5,10 +5,12 @@
#include "stdlib.h"
#include "string.h"
#include "memory.h"
#include "tricubic.h"
extern "C" typedef struct { double r, i; } doublecomplex;
using namespace std;
extern "C"{
#include "f2c.h"
#include "clapack.h"
}
class Interpolate{
public:

2776
tools/phonon/kpath.cpp Normal file

File diff suppressed because it is too large Load Diff

32
tools/phonon/kpath.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef UseSPG
#define KPATH_H
#endif
#ifndef KPATH_H
#define KPATH_H
#include "qnodes.h"
#include "dynmat.h"
#include "memory.h"
class kPath{
public:
kPath(DynMat *, QNodes *);
~kPath();
void kpath();
void show_path();
void show_info();
private:
Memory *memory;
DynMat *dynmat;
QNodes *q;
char symbol[11];
int spgnum, sysdim, fftdim, num_atom, *attyp;
double latvec[3][3], **atpos;
};
#endif

View File

@ -10,6 +10,9 @@ extern "C"{
#include "spglib.h"
}
#endif
#ifdef FFTW3
#include "phonopy.h"
#endif
/* ----------------------------------------------------------------------------
* Class Phonon is the main driver to calculate phonon DOS, phonon
@ -42,8 +45,7 @@ Phonon::Phonon(DynMat *dm)
printf("\n");
for (int i = 0; i < 37; ++i) printf("=");
printf(" Menu ");
for (int i = 0; i < 37; ++i) printf("=");
printf("\n");
for (int i = 0; i < 37; ++i) printf("="); printf("\n");
printf(" 1. Phonon DOS evaluation;\n");
printf(" 2. Phonon dispersion curves;\n");
printf(" 3. Dynamical matrix at arbitrary q;\n");
@ -54,6 +56,9 @@ Phonon::Phonon(DynMat *dm)
printf(" 8. Local phonon DOS by RSGF method;\n");
printf(" 9. Freqs and eigenvectors at arbitrary q;\n");
printf(" 10. Show information related to the unit cell;\n");
#ifdef FFTW3
printf(" 11. Write input files for working with phonopy;\n");
#endif
printf(" -1. Reset the interpolation method;\n");
printf(" 0. Exit.\n");
// read user choice
@ -61,8 +66,7 @@ Phonon::Phonon(DynMat *dm)
printf("Your choice [0]: ");
if (count_words(fgets(str,MAXLINE,stdin)) > 0) job = atoi(strtok(str," \t\n\r\f"));
printf("\nYour selection: %d\n", job);
for (int i = 0; i < 80; ++i) printf("=");
printf("\n\n");
for (int i = 0; i < 80; ++i) printf("=");printf("\n\n");
// now to do the job according to user's choice
if (job == 1) pdos();
@ -75,10 +79,16 @@ Phonon::Phonon(DynMat *dm)
else if (job == 8) ldos_rsgf();
else if (job == 9) vecanyq();
else if (job ==10) ShowCell();
#ifdef FFTW3
else if (job == 11){
Phonopy *ph = new Phonopy(dynmat);
delete ph;
}
#endif
else if (job ==-1) dynmat->reset_interp_method();
else break;
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -102,6 +112,8 @@ Phonon::~Phonon()
memory->destroy(atpos);
#endif
delete memory;
return;
}
/* ----------------------------------------------------------------------------
@ -160,9 +172,7 @@ void Phonon::pdos()
printf("Would you like to smooth the phonon dos? (y/n)[n]: ");
if (count_words(fgets(str,MAXLINE,stdin)) > 0){
char *flag = strtok(str," \t\n\r\f");
if (strcmp(flag,"y") == 0 || strcmp(flag,"Y") == 0){
smooth(dos, ndos);
}
if (strcmp(flag,"y") == 0 || strcmp(flag,"Y") == 0) smooth(dos, ndos);
}
// normalize dos to 1
@ -171,7 +181,7 @@ void Phonon::pdos()
// output DOS
writeDOS();
return;
return;
}
/* ----------------------------------------------------------------------------
@ -210,7 +220,7 @@ void Phonon::writeDOS()
fname = NULL;
return;
return;
}
/* ----------------------------------------------------------------------------
@ -243,7 +253,7 @@ void Phonon::writeLDOS()
fclose(fp);
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -272,6 +282,7 @@ void Phonon::ldos_rsgf()
fmin = fmax = egvs[0];
for (int i = 1; i < ndim; ++i){fmin = MIN(fmin, egvs[i]); fmax = MAX(fmax, egvs[i]);}
delete []egvs;
} else {
fmin = 0.; fmax = 20.;
}
@ -374,7 +385,7 @@ void Phonon::ldos_rsgf()
}
memory->destroy(Hessian);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -393,7 +404,7 @@ void Phonon::dmanyq()
dynmat->getDMq(q);
dynmat->writeDMq(q);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -416,11 +427,10 @@ void Phonon::vfanyq()
dynmat->geteigen(egvs, 0);
printf("q-point: [%lg %lg %lg], ", q[0], q[1], q[2]);
printf("vibrational frequencies at this q-point:\n");
for (int i = 0; i < ndim; ++i) printf("%lg ", egvs[i]);
printf("\n\n");
for (int i = 0; i < ndim; ++i) printf("%lg ", egvs[i]); printf("\n\n");
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -466,7 +476,7 @@ void Phonon::vecanyq()
}
fclose(fp);
eigvec = NULL;
return;
return;
}
/* ----------------------------------------------------------------------------
@ -526,7 +536,7 @@ void Phonon::DMdisp()
}
fclose(fp);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -554,7 +564,6 @@ void Phonon::smooth(double *array, const int npt)
tmp[i] = 0.;
for (int jj = -nlag; jj <= nlag; ++jj){
int j = (i+jj+npt)%npt; // assume periodical data
tmp [i] += array[j]*table[abs(jj)];
}
}
@ -563,7 +572,7 @@ void Phonon::smooth(double *array, const int npt)
memory->destroy(tmp);
memory->destroy(table);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -627,7 +636,7 @@ void Phonon::therm()
} while (T > 0.);
fclose(fp);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -742,7 +751,7 @@ void Phonon::local_therm()
}
fclose(fp);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -824,10 +833,12 @@ void Phonon::QMesh()
// display the unit cell info read
printf("\n");for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n");
printf("The basis vectors of the unit cell:\n");
for (int idim = 0; idim < 3; ++idim) printf(" A%d = %lg %lg %lg\n", idim+1, latvec[0][idim], latvec[1][idim], latvec[2][idim]);
for (int idim = 0; idim < 3; ++idim)
printf(" A%d = %lg %lg %lg\n", idim+1, latvec[0][idim], latvec[1][idim], latvec[2][idim]);
printf("Atom(s) in the unit cell:\n");
printf(" No. type sx sy sz\n");
for (int i = 0; i < MIN(num_atom, NUMATOM); ++i) printf(" %d %d %lg %lg %lg\n", i+1, attyp[i], atpos[i][0], atpos[i][1], atpos[i][2]);
for (int i = 0; i < MIN(num_atom, NUMATOM); ++i)
printf(" %d %d %lg %lg %lg\n", i+1, attyp[i], atpos[i][0], atpos[i][1], atpos[i][2]);
if (num_atom > NUMATOM) printf(" ... (%d atoms omitted.)\n", num_atom - NUMATOM);
int mesh[3], shift[3], is_time_reversal = 0;
@ -840,10 +851,6 @@ void Phonon::QMesh()
for (int i = 0; i < num_atom; ++i)
for (int j = 0; j < 3; ++j) pos[i][j] = atpos[i][j];
// if spglib 0.7.1 is used
// nq = spg_get_ir_reciprocal_mesh(grid_point, map, num_grid, mesh, shift, is_time_reversal, latvec, pos, attyp, num_atom, symprec);
// if spglib >= 1.0.3 is used
nq = spg_get_ir_reciprocal_mesh(grid_point, map, mesh, shift, is_time_reversal, latvec, pos, attyp, num_atom, symprec);
@ -878,7 +885,7 @@ void Phonon::QMesh()
#endif
printf("Your new q-mesh size would be: %d x %d x %d => %d points\n", nx,ny,nz,nq);
return;
return;
}
/* ----------------------------------------------------------------------------
@ -993,7 +1000,7 @@ void Phonon::ldos_egv()
// evaluate the local vibrational thermal properties optionally
local_therm();
return;
return;
}
/* ----------------------------------------------------------------------------
@ -1004,8 +1011,7 @@ void Phonon::ShowCell()
printf("\n");
for (int i = 0; i < 30; ++i) printf("=");
printf(" Unit Cell Info ");
for (int i = 0; i < 30; ++i) printf("=");
printf("\n");
for (int i = 0; i < 30; ++i) printf("="); printf("\n");
printf("Number of atoms in the unit cell: %d\n", dynmat->nucell);
printf("Basis vectors of the unit cell:\n");
printf(" %15.8f %15.8f %15.8f\n", dynmat->basevec[0], dynmat->basevec[1], dynmat->basevec[2]);
@ -1021,7 +1027,7 @@ void Phonon::ShowCell()
for (int i = 0; i < 80; ++i) printf("=");
printf("\n");
return;
return;
}
/* ----------------------------------------------------------------------------
@ -1054,7 +1060,7 @@ void Phonon::Normalize()
}
}
return;
return;
}
/* ----------------------------------------------------------------------------
@ -1081,7 +1087,7 @@ void Phonon::ComputeAll()
printf("Done!\n");
time->stop(); time->print(); delete time;
return;
return;
}
/*------------------------------------------------------------------------------
@ -1095,7 +1101,7 @@ int Phonon::count_words(const char *line)
strcpy(copy,line);
char *ptr;
if ((ptr = strchr(copy,'#'))) *ptr = '\0';
if (ptr = strchr(copy,'#')) *ptr = '\0';
if (strtok(copy," \t\n\r\f") == NULL) {
memory->destroy(copy);

320
tools/phonon/phonopy.cpp Normal file
View File

@ -0,0 +1,320 @@
#ifdef FFTW3
#include <map>
#include "phonopy.h"
#include "math.h"
#include "kpath.h"
#include "fftw3.h"
/* ----------------------------------------------------------------------------
* Class Phonopy is designed to interface with phonopy.
* ---------------------------------------------------------------------------- */
Phonopy::Phonopy(DynMat *dynmat)
{
dm = dynmat;
memory = new Memory();
sysdim = dm->sysdim;
fftdim = dm->fftdim;
fftdim2 = fftdim * fftdim;
nucell = dm->nucell;
nx = ny = nz = 5;
write(1);
char str[MAXLINE];
if (count_words(fgets(str,MAXLINE,stdin)) >= 3){
nx = atoi(strtok(str," \t\n\r\f"));
ny = atoi(strtok(NULL," \t\n\r\f"));
nz = atoi(strtok(NULL," \t\n\r\f"));
}
if (dm->nx == 1) nx = 1;
if (dm->ny == 1) ny = 1;
if (dm->nz == 1) nz = 1;
if (nx < 1) nx = 1;
if (ny < 1) ny = 1;
if (nz < 1) nz = 1;
npt = nx * ny * nz;
write(2);
memory->create(mass, nucell, "Phonopy:mass");
for (int i = 0; i < nucell; ++i){
double m = 1./dm->M_inv_sqrt[i];
mass[i] = m * m;
}
memory->create(FC_all, npt, fftdim2, "phonopy:FC_all");
get_my_FC();
phonopy();
return;
}
/* ----------------------------------------------------------------------------
* Deconstructor, free the memory used.
* ---------------------------------------------------------------------------- */
Phonopy::~Phonopy()
{
memory->destroy(mass);
memory->destroy(FC_all);
delete memory;
dm = NULL;
return;
}
/* ----------------------------------------------------------------------------
* Subroutine to write the outputs to screen.
* ---------------------------------------------------------------------------- */
void Phonopy::write(int flag)
{
if (flag == 1){ // basic information
for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n");
printf("Now to prepare the input files for phonopy.\n");
printf("The dimension of your present supercell is : %d x %d x %d.\n", dm->nx, dm->ny, dm->nz);
printf("The size of the force constant matrix will be: %d x %d.\n", dm->npt*3, dm->npt*3);
printf("Please define your desired dimension [5 5 5] : ");
} else if (flag == 2){
printf("\nThe new dimension of the supercell will be : %d x %d x %d.\n", nx, ny, nz);
printf("The size of the force constant matrix is then: %d x %d.\n", npt*3, npt*3);
} else if (flag == 3){
printf("\nNow to prepare the phonopy FORCE_CONSTANTS ..."); fflush(stdout);
} else if (flag == 4){
printf("Done!\nThe force constants information is extracted and written to FORCE_CONSTANTS,\n");
printf("the primitive cell is written to POSCAR.primitive, and the input file for\n");
printf("phonopy band evaluation is written to band.conf.\n");
printf("One should be able to obtain the phonon band structure after correcting\n");
printf("the element names in POSCAR.primitive and band.conf by running\n");
printf("`phonopy --readfc -c POSCAR.primitive -p band.conf`.\n");
for (int ii = 0; ii < 80; ++ii) printf("-");
printf("\n*** Remember to change the element names. ***\n");
#ifdef UseSPG
for (int ii = 0; ii < 80; ++ii) printf("-");
#endif
} else if (flag == 5){
for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n");
}
return;
}
/* ----------------------------------------------------------------------------
* Driver to obtain the force constant matrix
* ---------------------------------------------------------------------------- */
void Phonopy::get_my_FC()
{
double q[3];
int ipt = 0;
for (int ix = 0; ix < nx; ++ix)
for (int iy = 0; iy < ny; ++iy)
for (int iz = 0; iz < nz; ++iz){
q[0] = double(ix)/double(nx);
q[1] = double(iy)/double(ny);
q[2] = double(iz)/double(nz);
dm->getDMq(q);
int ndim = 0;
for (int idim = 0; idim < fftdim; ++idim)
for (int jdim = 0; jdim < fftdim; ++jdim){
FC_all[ipt][ndim] = dm->DM_q[idim][jdim];
double m = sqrt(mass[idim/sysdim] * mass[jdim/sysdim]);
FC_all[ipt][ndim].r *= m;
FC_all[ipt][ndim].i *= m;
++ndim;
}
++ipt;
}
return;
}
/* ----------------------------------------------------------------------------
* Method to write out the force constants and related files for
* postprocessing with phonopy.
* ---------------------------------------------------------------------------- */
void Phonopy::phonopy()
{
// output info
write(3);
fftw_complex *in, *out;
double **fc;
memory->create(in, npt, "phonopy:in");
memory->create(out, npt, "phonopy:in");
memory->create(fc, npt, fftdim2, "phonopy:in");
fftw_plan plan = fftw_plan_dft_3d(nx, ny, nz, in, out, -1, FFTW_ESTIMATE);
double factor = dm->eml2fc / double(npt);
for (int idim = 0; idim < fftdim2; ++idim){
for (int i = 0; i < npt; ++i){
in[i][0] = FC_all[i][idim].r;
in[i][1] = FC_all[i][idim].i;
}
fftw_execute(plan);
for (int i = 0; i < npt; ++i) fc[i][idim] = out[i][0] * factor;
}
fftw_destroy_plan(plan);
memory->destroy(in);
memory->destroy(out);
// in POSCAR, atoms are sorted/aggregated by type, while for LAMMPS there is no such requirment
int type_id[nucell], num_type[nucell], ntype = 0;
for (int i = 0; i < nucell; ++i) num_type[i] = 0;
for (int i = 0; i < nucell; ++i){
int ip = ntype;
for (int j = 0; j < ntype; ++j){
if (dm->attyp[i] == type_id[j]) ip = j;
}
if (ip == ntype) type_id[ntype++] = dm->attyp[i];
num_type[ip]++;
}
std::map<int, int> iu_by_type;
iu_by_type.clear();
int id_new = 0;
for (int i = 0; i < ntype; ++i){
for (int j = 0; j < nucell; ++j){
if (dm->attyp[j] == type_id[i]) iu_by_type[id_new++] = j;
}
}
// write the FORCE_CONSTANTS file
FILE *fp = fopen("FORCE_CONSTANTS", "w");
int natom = npt * nucell;
fprintf(fp, "%d %d\n", natom, natom);
for (int i = 0; i < natom; ++i){
int iu = i / npt;
int iz = (i % npt) / (nx * ny);
int iy = (i % (nx *ny) ) / nx;
int ix = i % nx;
iu = iu_by_type[iu];
for (int j = 0; j < natom; ++j){
int ju = j / npt;
int jz = (j % npt) / (nx * ny);
int jy = (j % (nx *ny) ) / nx;
int jx = j % nx;
int dx = abs(ix - jx);
int dy = abs(iy - jy);
int dz = abs(iz - jz);
int id = (dx * ny + dy) * nz + dz;
ju = iu_by_type[ju];
fprintf(fp, "%d %d\n", i+1, j+1);
for (int idim = iu * sysdim; idim < (iu+1)*sysdim; ++idim){
for (int jdim = ju * sysdim; jdim < (ju+1)*sysdim; ++jdim){
int dd = idim * fftdim + jdim;
fprintf(fp, " %lg", fc[id][dd]);
}
fprintf(fp, "\n");
}
}
}
fclose(fp);
iu_by_type.clear();
memory->destroy(fc);
// write the primitive cell in POSCAR format
fp = fopen("POSCAR.primitive", "w");
fprintf(fp, "Fix-phonon unit cell");
for (int ip = 0; ip < ntype; ++ip) fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[ip]);
fprintf(fp, "\n1.\n");
int ndim = 0;
for (int idim = 0; idim < 3; ++idim){
for (int jdim = 0; jdim < 3; ++jdim) fprintf(fp, "%lg ", dm->basevec[ndim++]);
fprintf(fp, "\n");
}
for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "Elem-%d ", type_id[ip]); fprintf(fp, "\n");
for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "%d ", num_type[ip]);
fprintf(fp, "\nDirect\n");
for (int ip = 0; ip < ntype; ++ip){
for (int i = 0; i < nucell; ++i){
if (dm->attyp[i] == type_id[ip]){
fprintf(fp, "%lg %lg %lg\n", dm->basis[i][0], dm->basis[i][1], dm->basis[i][2]);
}
}
}
fclose(fp);
#ifdef UseSPG
// Get high symmetry k-path
QNodes *q = new QNodes();
kPath *kp = new kPath(dm, q);
kp->kpath();
#endif
// band.conf
fp = fopen("band.conf", "w");
fprintf(fp, "# From Fix-phonon");
for (int ip = 0; ip < ntype; ++ip) fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[ip]);
fprintf(fp, "\n\nATOM_NAME = ");
for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "Elem-%d ", type_id[ip]);
fprintf(fp, "\nDIM = %d %d %d\nBAND = ", nx, ny, nz);
#ifdef UseSPG
int nsect = q->qs.size();
for (int i = 0; i < nsect; ++i){
fprintf(fp, " %lg %lg %lg", q->qs[i][0], q->qs[i][1], q->qs[i][2]);
if (i+1 < nsect){
double dq = 0.;
for (int j = 0; j < 3; ++j) dq += (q->qe[i][j] - q->qs[i+1][j]) * (q->qe[i][j] - q->qs[i+1][j]);
if (dq > ZERO) {
fprintf(fp, " %lg %lg %lg,", q->qe[i][0], q->qe[i][1], q->qe[i][2]);
}
} else if (i+1 == nsect){
fprintf(fp, " %lg %lg %lg\n", q->qe[i][0], q->qe[i][1], q->qe[i][2]);
}
}
#endif
fprintf(fp, "\nBAND_POINTS = 21\nBAND_LABELS =");
#ifdef UseSPG
for (int i = 0; i < q->ndstr.size(); ++i){
std::size_t found = q->ndstr[i].find("{/Symbol G}");
if (found != std::string::npos) q->ndstr[i].replace(found, found+11, "$\\Gamma$");
found = q->ndstr[i].find("/");
if (found != std::string::npos) q->ndstr[i].replace(found, found, " ");
fprintf(fp, " %s", q->ndstr[i].c_str());
}
#endif
fprintf(fp, "\nFORCE_CONSTANTS = READ\nBAND_CONNECTION = .TRUE.\n");
// output info
write(4);
#ifdef UseSPG
kp->show_path();
delete kp;
delete q;
#endif
write(5);
return;
}
/*------------------------------------------------------------------------------
* Method to count # of words in a string, without destroying the string
*----------------------------------------------------------------------------*/
int Phonopy::count_words(const char *line)
{
int n = strlen(line) + 1;
char *copy;
memory->create(copy, n, "count_words:copy");
strcpy(copy,line);
char *ptr;
if (ptr = strchr(copy,'#')) *ptr = '\0';
if (strtok(copy," \t\n\r\f") == NULL) {
memory->destroy(copy);
return 0;
}
n = 1;
while (strtok(NULL," \t\n\r\f")) n++;
memory->destroy(copy);
return n;
}
/*----------------------------------------------------------------------------*/
#endif

36
tools/phonon/phonopy.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef FFTW3
#define PHONOPY_H
#endif
#ifndef PHONOPY_H
#define PHONOPY_H
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "memory.h"
#include "qnodes.h"
#include "dynmat.h"
#include "global.h"
class Phonopy {
public:
Phonopy(DynMat *);
~Phonopy();
private:
Memory *memory;
char str[MAXLINE];
int npt, fftdim2; // local variables
int nx, ny, nz, nucell; // local variables
int sysdim, fftdim; // local variables
double *mass;
doublecomplex **FC_all;
DynMat *dm;
void write(int);
void get_my_FC();
void phonopy();
int count_words(const char *line);
};
#endif

30
tools/phonon/qnodes.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "qnodes.h"
/* ----------------------------------------------------------------------------
* Class QNodes stores the high symmetry k-path nodes for a given lattice.
* The constructor and the deconstructor simply empties the data.
* ---------------------------------------------------------------------------- */
QNodes::QNodes()
{
nodes.clear();
ndstr.clear();
qs.clear();
qe.clear();
nqbin.clear();
return;
}
/* ----------------------------------------------------------------------------
* The constructor and the deconstructor simply empties the data.
* ---------------------------------------------------------------------------- */
QNodes::~QNodes()
{
nodes.clear();
ndstr.clear();
qs.clear();
qe.clear();
nqbin.clear();
return;
}

17
tools/phonon/qnodes.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef QNODES_H
#define QNODES_H
#include <vector>
#include <string>
class QNodes {
public:
QNodes();
~QNodes();
std::vector<double> nodes;
std::vector<std::string> ndstr;
std::vector<double *> qs, qe;
std::vector<int> nqbin;
};
#endif

View File

@ -6,7 +6,8 @@ Timer::Timer()
{
flag = 0;
start();
return;
return;
}
/* -----------------------------------------------------------------------------
@ -16,8 +17,7 @@ void Timer::start()
{
t1 = clock();
flag |= 1;
return;
return;
}
/* -----------------------------------------------------------------------------
@ -29,7 +29,7 @@ void Timer::stop()
t2 = clock();
flag |= 2;
}
return;
return;
}
/* -----------------------------------------------------------------------------
@ -42,7 +42,7 @@ void Timer::print()
cpu_time_used = ((double) (t2 - t1)) / CLOCKS_PER_SEC;
printf("Total CPU time used: %g seconds.\n", cpu_time_used);
return;
return;
}
/* -----------------------------------------------------------------------------

View File

@ -1 +1 @@
#define VERSION 8
#define VERSION 21