From c45b987764b14d56ded431bfd65393e36e764a3d Mon Sep 17 00:00:00 2001 From: sjplimp Date: Mon, 11 Mar 2013 20:53:11 +0000 Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@9636 f3b2605a-c512-4ea7-a41b-209d697bcdaa --- src/Makefile | 3 +- src/USER-PHONON/Install.sh | 13 + src/USER-PHONON/README | 18 + src/USER-PHONON/fix_phonon.cpp | 896 +++++++++++++++++++++++++++++++++ src/USER-PHONON/fix_phonon.h | 185 +++++++ 5 files changed, 1114 insertions(+), 1 deletion(-) create mode 100644 src/USER-PHONON/Install.sh create mode 100644 src/USER-PHONON/README create mode 100644 src/USER-PHONON/fix_phonon.cpp create mode 100644 src/USER-PHONON/fix_phonon.h diff --git a/src/Makefile b/src/Makefile index d994ba4089..51c255b86d 100755 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,8 @@ PACKAGE = asphere body class2 colloid dipole fld gpu granular kim \ rigid shock srd voronoi xtc PACKUSER = user-misc user-atc user-awpmd user-cg-cmm user-colvars \ - user-cuda user-eff user-omp user-molfile user-reaxc user-sph + user-cuda user-eff user-omp user-molfile user-phonon \ + user-reaxc user-sph PACKLIB = gpu kim meam poems reax voronoi \ user-atc user-awpmd user-colvars user-cuda user-molfile diff --git a/src/USER-PHONON/Install.sh b/src/USER-PHONON/Install.sh new file mode 100644 index 0000000000..cb7e943adb --- /dev/null +++ b/src/USER-PHONON/Install.sh @@ -0,0 +1,13 @@ +# Install/unInstall package classes in LAMMPS + +if (test $1 = 1) then + + cp fix_phonon.h .. + cp fix_phonon.cpp .. + +elif (test $1 = 0) then + + rm -f ../fix_phonon.h + rm -f ../fix_phonon.cpp + +fi diff --git a/src/USER-PHONON/README b/src/USER-PHONON/README new file mode 100644 index 0000000000..fe1072e775 --- /dev/null +++ b/src/USER-PHONON/README @@ -0,0 +1,18 @@ +This package contains a method to measure the dynamical matrices, and +consequently the phonon dispersion, directly from molecular dynamics +simulations. It is implemented as a fix phonon command. + +See the doc page for the fix phonon command for detailed usage +instructions. + +The compiling of this package along with LAMMPS requires that the FFT3d +wrappers from the kspace package of LAMMPS be included as well. + +There are example scripts for using this package in +examples/USER/phonon. + +There is an auxiliary post-processing tool for using this package in +tools/phonon. + +The person who created this package is Ling-Ti Kong (konglt at +sjtu.edu.cn). Contact him directly if you have questions. diff --git a/src/USER-PHONON/fix_phonon.cpp b/src/USER-PHONON/fix_phonon.cpp new file mode 100644 index 0000000000..7745933b21 --- /dev/null +++ b/src/USER-PHONON/fix_phonon.cpp @@ -0,0 +1,896 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + Contributing authors: + Ling-Ti Kong + + Contact: + School of Materials Science and Engineering, + Shanghai Jiao Tong University, + 800 Dongchuan Road, Minhang, + Shanghai 200240, CHINA + + konglt@sjtu.edu.cn; konglt@gmail.com +------------------------------------------------------------------------- */ + +#include "atom.h" +#include "compute.h" +#include "domain.h" +#include "error.h" +#include "fix_phonon.h" +#include "fft3d_wrap.h" +#include "force.h" +#include "group.h" +#include "lattice.h" +#include "memory.h" +#include "modify.h" +#include "update.h" +#include "string.h" + +using namespace LAMMPS_NS; +using namespace FixConst; + +#define INVOKED_SCALAR 1 +#define INVOKED_VECTOR 2 +#define MAXLINE 256 + +FixPhonon::FixPhonon(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) +{ + MPI_Comm_rank(world,&me); + MPI_Comm_size(world,&nprocs); + + if (narg < 8) error->all(FLERR,"Illegal fix phonon command: number of arguments < 8"); + + nevery = atoi(arg[3]); // Calculate this fix every n steps! + if (nevery < 1) error->all(FLERR,"Illegal fix phonon command"); + + nfreq = atoi(arg[4]); // frequency to output result + if (nfreq < 1) error->all(FLERR,"Illegal fix phonon command"); + + waitsteps = ATOBIGINT(arg[5]); // Wait this many timesteps before actually measuring + if (waitsteps < 0) error->all(FLERR,"Illegal fix phonon command: waitsteps < 0 !"); + + int n = strlen(arg[6]) + 1; // map file + mapfile = new char[n]; + strcpy(mapfile, arg[6]); + + n = strlen(arg[7]) + 1; // prefix of output + prefix = new char[n]; + strcpy(prefix, arg[7]); + logfile = new char[n+4]; + sprintf(logfile,"%s.log",prefix); + + int sdim = 4; + int iarg = 8; + nasr = 20; + + // other command line options + while (iarg < narg){ + if (strcmp(arg[iarg],"sysdim") == 0){ + if (++iarg >= narg) error->all(FLERR,"Illegal fix phonon command: incomplete command line options."); + sdim = atoi(arg[iarg]); + + } else if (strcmp(arg[iarg],"nasr") == 0){ + if (++iarg >= narg) error->all(FLERR,"Illegal fix phonon command: incomplete command line options."); + nasr = atoi(arg[iarg]); + + } else { + error->all(FLERR,"Illegal fix phonon command: unknown option read!"); + } + iarg++; + } + + // get the dimension of the simulation; 1D is possible by specifying the option of "sysdim 1" + sysdim = domain->dimension; + if (sdim < sysdim) sysdim = sdim; + nasr = MAX(0,nasr); + + // get the total number of atoms in group + nGFatoms = static_cast(group->count(igroup)); + if (nGFatoms<1) error->all(FLERR,"No atom found for fix phonon!"); + + // MPI gatherv related variables + recvcnts = new int[nprocs]; + displs = new int[nprocs]; + + // mapping index + tag2surf.clear(); // clear map info + surf2tag.clear(); + + // get the mapping between lattice indices and atom IDs + readmap(); delete []mapfile; + if (nucell == 1) nasr = MIN(1,nasr); + + // get the mass matrix for dynamic matrix + getmass(); + + // create FFT and allocate memory for FFT + nxlo = 0; + int *nx_loc = new int [nprocs]; + for (int i=0; ismalloc(MAX(1,mynq)*2*sizeof(double),"fix_phonon:fft_data"); + + // allocate variables; MAX(1,... is used because NULL buffer will result in error for MPI + RIloc = memory->create(RIloc,nGFatoms,(sysdim+1),"fix_phonon:RIloc"); + RIall = memory->create(RIall,nGFatoms,(sysdim+1),"fix_phonon:RIall"); + Rsort = memory->create(Rsort,nGFatoms, sysdim, "fix_phonon:Rsort"); + + Rnow = memory->create(Rnow, MAX(1,mynpt),fft_dim,"fix_phonon:Rnow"); + Rsum = memory->create(Rsum, MAX(1,mynpt),fft_dim,"fix_phonon:Rsum"); + + basis = memory->create(basis,nucell, sysdim, "fix_phonon:basis"); + + // because of hermit, only nearly half of q points are stored + Rqnow = memory->create(Rqnow,MAX(1,mynq),fft_dim, "fix_phonon:Rqnow"); + Rqsum = memory->create(Rqsum,MAX(1,mynq),fft_dim2,"fix_phonon:Rqsum"); + Phi_q = memory->create(Phi_q,MAX(1,mynq),fft_dim2,"fix_phonon:Phi_q"); + + if (me == 0) // variable to collect all local Phi to root + Phi_all = memory->create(Phi_all,ntotal,fft_dim2,"fix_phonon:Phi_all"); + else + Phi_all = memory->create(Phi_all,1,1,"fix_phonon:Phi_all"); + + // output some information on the system to log file + if (me == 0){ + flog = fopen(logfile, "w"); + if (flog == NULL) { + char str[MAXLINE]; + sprintf(str,"Can not open output file %s",logfile); + error->one(FLERR,str); + } + for (int i=0; i<60; i++) fprintf(flog,"#"); fprintf(flog,"\n"); + fprintf(flog,"# group name of the atoms under study : %s\n", group->names[igroup]); + fprintf(flog,"# total number of atoms in the group : %d\n", nGFatoms); + fprintf(flog,"# dimension of the system : %d D\n", sysdim); + fprintf(flog,"# number of atoms per unit cell : %d\n", nucell); + fprintf(flog,"# dimension of the FFT mesh : %d x %d x %d\n", nx, ny, nz); + fprintf(flog,"# number of wait steps before measurement : " BIGINT_FORMAT "\n", waitsteps); + fprintf(flog,"# frequency of GFC measurement : %d\n", nevery); + fprintf(flog,"# output result after this many measurement: %d\n", nfreq); + fprintf(flog,"# number of processors used by this run : %d\n", nprocs); + for (int i=0; i<60; i++) fprintf(flog,"#"); fprintf(flog,"\n"); + fprintf(flog,"# mapping information between lattice index and atom id\n"); + fprintf(flog,"# nx ny nz nucell\n"); + fprintf(flog,"%d %d %d %d\n", nx, ny, nz, nucell); + fprintf(flog,"# l1 l2 l3 k atom_id\n"); + int ix, iy, iz, iu; + for (idx =0; idxfind_compute(id_temp); + temperature = modify->compute[icompute]; + inv_nTemp = 1.0/group->count(temperature->igroup); + +} // end of constructor + +/* ---------------------------------------------------------------------- */ + +void FixPhonon::post_run() +{ + // compute and output final GFC results + if (ifreq > 0 && ifreq != nfreq) postprocess(); + if (me == 0) fclose(flog); +} + +/* ---------------------------------------------------------------------- */ + +FixPhonon::~FixPhonon() +{ + // delete locally stored array + memory->destroy(RIloc); + memory->destroy(RIall); + memory->destroy(Rsort); + memory->destroy(Rnow); + memory->destroy(Rsum); + + memory->destroy(basis); + + memory->destroy(Rqnow); + memory->destroy(Rqsum); + memory->destroy(Phi_q); + memory->destroy(Phi_all); + + delete []recvcnts; + delete []displs; + delete []prefix; + delete []logfile; + delete []fft_cnts; + delete []fft_disp; + delete []id_temp; + delete []TempSum; + delete []M_inv_sqrt; + delete []basetype; + + // destroy FFT + delete fft; + memory->sfree(fft_data); + + // clear map info + tag2surf.clear(); + surf2tag.clear(); + +} + +/* ---------------------------------------------------------------------- */ + +int FixPhonon::setmask() +{ + int mask = 0; + mask |= END_OF_STEP; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixPhonon::init() +{ + // warn if more than one fix-phonon + int count = 0; + for (int i=0;infix;i++) if (strcmp(modify->fix[i]->style,"gfc") == 0) count++; + if (count > 1 && me == 0) error->warning(FLERR,"More than one fix phonon defined"); // just warn, but allowed. +} + +/* ---------------------------------------------------------------------- */ + +void FixPhonon::setup(int flag) +{ + // initialize accumulating variables + for (int i=0; i (0.,0.); + } + for (int i=0; i<6; i++) hsum[i] = 0.; + for (int i=0; intimestep; + GFcounter = 0; + ifreq = 0; +} + +/* ---------------------------------------------------------------------- */ + +void FixPhonon::end_of_step() +{ + if ( (update->ntimestep-prev_nstep) <= waitsteps) return; + + double **x = atom->x; + int *mask = atom->mask; + int *tag = atom->tag; + int *image = atom->image; + int nlocal = atom->nlocal; + + double xprd = domain->xprd; + double yprd = domain->yprd; + double zprd = domain->zprd; + double *h = domain->h; + double xbox, ybox, zbox; + + int i,idim,jdim,ndim; + double xcur[3]; + + // to get the current temperature + if (!(temperature->invoked_flag & INVOKED_VECTOR)) temperature->compute_vector(); + for (idim=0; idimvector[idim]; + + // evaluate R(r) on local proc + nfind = 0; + if (domain->triclinic == 0) { // for orthogonal lattice + for (i=0; i> 10 & 1023) - 512; + zbox = (image[i] >> 20) - 512; + xcur[0] = x[i][0] + xprd*xbox; + xcur[1] = x[i][1] + yprd*ybox; + xcur[2] = x[i][2] + zprd*zbox; + for (idim=0; idim> 10 & 1023) - 512; + zbox = (image[i] >> 20) - 512; + xcur[0] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox; + xcur[1] = x[i][1] + h[1]*ybox + h[3]*zbox; + xcur[2] = x[i][2] + h[2]*zbox; + for (idim=0; idim(RIall[i][sysdim]); + for (idim=0; idimcompute(fft_data, fft_data, -1); + m = 0; + for (idq=0; idq(fft_data[m], fft_data[m+1]); + m += 2; + } + } + + // to get sum(R(q).R(q)*) + for (idq=0; idq sysdim){ + for (idx=0; idxminimum_image(dist2orig); + for (idim=0; idim)*2*nGFatoms + + sizeof(double)*(nGFatoms*(3*sysdim+2)+mynpt*fft_dim*2) + + sizeof(std::complex)*MAX(1,mynq)*fft_dim *(1+2*fft_dim) + + sizeof(std::complex)*ntotal*fft_dim2 + + sizeof(int) * nprocs * 4; + return bytes; +} + +/* ---------------------------------------------------------------------- */ + +int FixPhonon::modify_param(int narg, char **arg) +{ + if (strcmp(arg[0],"temp") == 0) { + if (narg < 2) error->all(FLERR,"Illegal fix_modify command"); + delete [] id_temp; + int n = strlen(arg[1]) + 1; + id_temp = new char[n]; + strcpy(id_temp,arg[1]); + + int icompute = modify->find_compute(id_temp); + if (icompute < 0) error->all(FLERR,"Could not find fix_modify temp ID"); + temperature = modify->compute[icompute]; + + if (temperature->tempflag == 0) + error->all(FLERR,"Fix_modify temp ID does not compute temperature"); + inv_nTemp = 1.0/group->count(temperature->igroup); + + return 2; + } + return 0; +} + +/* ---------------------------------------------------------------------- + * private method, to get the mass matrix for dynamic matrix + * --------------------------------------------------------------------*/ +void FixPhonon::getmass() +{ + int nlocal = atom->nlocal; + int *mask = atom->mask; + int *tag = atom->tag; + int *type = atom->type; + double *rmass = atom->rmass; + double *mass = atom->mass; + double *mass_one, *mass_all; + double *type_one, *type_all; + + mass_one = new double[nucell]; + mass_all = new double[nucell]; + type_one = new double[nucell]; + type_all = new double[nucell]; + for (int i=0; iall(FLERR,str); + } + + if (fgets(strtmp,MAXLINE,fp) == NULL) + error->all(FLERR,"Error while reading header of mapping file!"); + sscanf(strtmp,"%d %d %d %d", &nx, &ny, &nz, &nucell); + ntotal = nx*ny*nz; + if (ntotal*nucell != nGFatoms) error->all(FLERR,"FFT mesh and number of atoms in group mismatch!"); + + if (fgets(strtmp,MAXLINE,fp) == NULL) // second line of mapfile is comment + error->all(FLERR,"Error while reading comment of mapping file!"); + + int ix, iy, iz, iu; + for (int i=0; i=nx || iy<0 || iy>=ny || iz<0 || iz>=nz|| iu<0 || iu>=nucell) {info = 2; break;} // check if index is in correct range + if (itag<1 || itag>static_cast(atom->natoms)) {info = 3; break;} // 1 <= itag <= natoms + idx = ((ix*ny+iy)*nz+iz)*nucell+iu; + tag2surf[itag] = idx; + surf2tag[idx] = itag; + } + fclose(fp); + + if (tag2surf.size() != surf2tag.size() || tag2surf.size() != static_cast(nGFatoms) ) + error->all(FLERR,"The mapping is incomplete!"); + if (info) error->all(FLERR,"Error while reading mapping file!"); + + // check the correctness of mapping + int *mask = atom->mask; + int *tag = atom->tag; + int nlocal = atom->nlocal; + + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit){ + itag = tag[i]; + idx = tag2surf[itag]; + if (itag != surf2tag[idx]) error->one(FLERR,"The mapping info read is incorrect!"); + } + } + + return; +} + +/* ---------------------------------------------------------------------- + * private method, to output the force constant matrix + * --------------------------------------------------------------------*/ + +void FixPhonon::postprocess( ) +{ + if (GFcounter<1) return; + + ifreq =0; + int idim, jdim, ndim; + double invGFcounter = 1.0 /double(GFcounter); + + // to get + for (idq=0; idq + for (idx=0; idxq + for (idim=0; idimcompute(fft_data,fft_data,-1); + m = 0; + for (idq=0; idq(fft_data[m], fft_data[m+1]); + m += 2; + } + } + + // to get G(q) = - q.q + for (idq=0; idqboltz, kbtsqrt[sysdim], TempAve = 0.; + double TempFac = invGFcounter*inv_nTemp; + double NormFac = TempFac*double(ntotal); + + for (idim=0; idim sysdim) + MPI_Reduce (&basis[1][0], &basis_root[sysdim], fft_dim-sysdim, MPI_DOUBLE, MPI_SUM, 0, world); + + if (me == 0){ // output dynamic matrix by root + + // get basis info + for (idim=0; idimntimestep); + GFC_bin = fopen(fname,"wb"); + + fwrite(&sysdim, sizeof(int), 1, GFC_bin); + fwrite(&nx, sizeof(int), 1, GFC_bin); + fwrite(&ny, sizeof(int), 1, GFC_bin); + fwrite(&nz, sizeof(int), 1, GFC_bin); + fwrite(&nucell, sizeof(int), 1, GFC_bin); + fwrite(&boltz, sizeof(double), 1, GFC_bin); + + fwrite(Phi_all[0],sizeof(double),ntotal*fft_dim2*2,GFC_bin); + + fwrite(&TempAve, sizeof(double),1, GFC_bin); + fwrite(&basevec[0], sizeof(double),9, GFC_bin); + fwrite(&basis_root[0],sizeof(double),fft_dim,GFC_bin); + fwrite(basetype, sizeof(int), nucell, GFC_bin); + fwrite(M_inv_sqrt, sizeof(double),nucell, GFC_bin); + + fclose(GFC_bin); + + // write log file, here however, it is the dynamical matrix that is written + for (int i=0; i<60; i++) fprintf(flog,"#"); fprintf(flog,"\n"); + fprintf(flog, "# Current time step : " BIGINT_FORMAT "\n", update->ntimestep); + fprintf(flog, "# Total number of measurements : %d\n", GFcounter); + fprintf(flog, "# Average temperature of the measurement : %lg\n", TempAve); + fprintf(flog, "# Boltzmann constant under current units : %lg\n", boltz); + fprintf(flog, "# basis vector A1 = [%lg %lg %lg]\n", basevec[0], basevec[1], basevec[2]); + fprintf(flog, "# basis vector A2 = [%lg %lg %lg]\n", basevec[3], basevec[4], basevec[5]); + fprintf(flog, "# basis vector A3 = [%lg %lg %lg]\n", basevec[6], basevec[7], basevec[8]); + for (int i=0; i<60; i++) fprintf(flog,"#"); fprintf(flog,"\n"); + fprintf(flog, "# qx\t qy \t qz \t\t Phi(q)\n"); + + EnforceASR(); + + // to get D = 1/M x Phi + for (idq=0; idq *Mat) +{ + int i,icol,irow,j,k,l,ll,idr,idc; + int *indxc,*indxr,*ipiv; + double big, nmjk; + std::complex dum, pivinv; + + indxc = new int[n]; + indxr = new int[n]; + ipiv = new int[n]; + + for (i=0; i= big){ + big = nmjk; + irow = j; + icol = k; + } + }else if (ipiv[k]>1){ + error->one(FLERR,"Singular matrix in complex GaussJordan!"); + } + } + } + } + ipiv[icol] += 1; + if (irow != icol){ + for (l=0; l(0.,0.)) error->one(FLERR,"Singular matrix in complex GaussJordan!"); + + pivinv = 1./ Mat[idr]; + Mat[idr] = std::complex(1.,0.); + idr = icol*n; + for (l=0; l=0; l--){ + int rl = indxr[l]; + int cl = indxc[l]; + if (rl != cl){ + for (k=0; k +#include "fix.h" +#include +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +namespace LAMMPS_NS { + +class FixPhonon : public Fix { + public: + FixPhonon(class LAMMPS *, int, char **); + ~FixPhonon(); + + int setmask(); + void init(); + void setup(int); + void end_of_step(); + void post_run(); + double memory_usage(); + int modify_param(int, char **); + + private: + int me,nprocs; + bigint waitsteps; // wait these number of timesteps before recording atom positions + bigint prev_nstep; // number of steps from previous run(s); to judge if waitsteps is reached. + int nfreq, ifreq; // after this number of measurement (nfreq), the result will be output once + int nx,ny,nz,nucell,ntotal; // surface dimensions in x- and y-direction, number of atom per unit surface cell + int GFcounter; // counter variables + int sysdim; // system dimension + int nGFatoms, nfind; // total number of GF atoms; total number of GF atom on this proc + char *prefix, *logfile; // prefix of output file names + FILE *flog; + + double *M_inv_sqrt; + + class FFT3d *fft; // to do fft via the fft3d wraper + int nxlo,nxhi,mysize; // size info for local MPI_FFTW + int mynpt,mynq,fft_nsend; + int *fft_cnts, *fft_disp; + int fft_dim, fft_dim2; + double *fft_data; + + int itag, idx, idq; // index variables + std::map tag2surf, surf2tag; // Mapping info + + double **RIloc; // R(r) and index on local proc + double **RIall; // gathered R(r) and index + double **Rsort; // sorted R(r) + double **Rnow; // Current R(r) on local proc for GF atoms + double **Rsum; // Accumulated R(r) on local proc for GF atoms + + int *recvcnts, *displs; // MPI related variables + + std::complex **Rqnow; // Current R(q) on local proc + std::complex **Rqsum; // Accumulator for conj(R(q)_alpha)*R(q)_beta + std::complex **Phi_q; // Phi's on local proc + std::complex **Phi_all; // Phi for all + + void readmap(); // to read the mapping of gf atoms + char *mapfile; // file name of the map file + + void getmass(); // to get the mass of each atom in a unit cell + + int nasr; + void postprocess(); // to post process the data + void EnforceASR(); // to apply acoustic sum rule to gamma point force constant matrix + + char *id_temp; // compute id for temperature + double *TempSum; // to get the average temperature vector + double inv_nTemp; // inverse of number of atoms in temperature group + class Compute *temperature; // compute that computes the temperature + + double hsum[6], **basis; + int *basetype; + + // private methods to do matrix inversion + void GaussJordan(int, std::complex*); + +}; +} +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal fix phonon command... + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: No atom found for fix phonon! + +Self-explanatory. Number of atoms in the group that was passed to +fix-phonon is less than 1. + +E: Can not open output file %s" + +Self-explanatory. + +E: Illegal fix_modify command + +Self-explanatory. + +E: Could not find fix_modify temp ID + +Self-explanatory. + +E: Fix_modify temp ID does not compute temperature + +Self-explanatory. + +E: Cannot open input map file %s + +Self-explanatory. + +E: Error while reading header of mapping file! + +Self-explanatory. The first line of the map file is expected to +contain 4 positive integer numbers. + +E: FFT mesh and number of atoms in group mismatch! + +Self-explanatory. The product of the 4 numbers should be exactly the +total number of atoms in the group that was passed to fix-phonon. + +E: Error while reading comment of mapping file! + +Self-explanatory. The second line of the map file should be a comment line. + +E: The mapping is incomplete! + +Self-explanatory. + +E: Error while reading mapping file! + +Self-explanatory. + +E: The mapping info read is incorrect! + +Self-explanatory. + +E: Singular matrix in complex GaussJordan! + +Self-explanatory. + +W: More than one fix phonon defined + +Self-explanatory. Just to warn that more than one fix-phonon is defined, but allowed. + +*/