diff --git a/src/MANYBODY/pair_eam.cpp b/src/MANYBODY/pair_eam.cpp index a1bc6e1eb4..e74755ecb9 100644 --- a/src/MANYBODY/pair_eam.cpp +++ b/src/MANYBODY/pair_eam.cpp @@ -29,6 +29,8 @@ #include "error.h" #include "update.h" #include "utils.h" +#include "tokenizer.h" +#include "potential_file_reader.h" using namespace LAMMPS_NS; @@ -462,54 +464,58 @@ void PairEAM::read_file(char *filename) { Funcfl *file = &funcfl[nfuncfl-1]; - int me = comm->me; - FILE *fptr; - char line[MAXLINE]; + if(comm->me == 0) { + PotentialFileReader reader(lmp, filename, "EAM"); - if (me == 0) { - fptr = force->open_potential(filename); - if (fptr == NULL) { - char str[128]; - snprintf(str,128,"Cannot open EAM potential file %s",filename); - error->one(FLERR,str); + try { + char * line = nullptr; + + reader.skip_line(); + + line = reader.next_line(2); + ValueTokenizer values(line); + values.next_int(); // ignore + file->mass = values.next_double(); + + line = reader.next_line(5); + values = ValueTokenizer(line); + file->nrho = values.next_int(); + file->drho = values.next_double(); + file->nr = values.next_int(); + file->dr = values.next_double(); + file->cut = values.next_double(); + + if ((file->nrho <= 0) || (file->nr <= 0) || (file->dr <= 0.0)) + error->one(FLERR,"Invalid EAM potential file"); + + memory->create(file->frho, (file->nrho+1), "pair:frho"); + memory->create(file->rhor, (file->nr+1), "pair:rhor"); + memory->create(file->zr, (file->nr+1), "pair:zr"); + + reader.next_dvector(file->nrho, &file->frho[1]); + reader.next_dvector(file->nr, &file->zr[1]); + reader.next_dvector(file->nr, &file->rhor[1]); + } catch (TokenizerException & e) { + error->one(FLERR, e.what()); } } - int tmp,nwords; - if (me == 0) { - utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error); - utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error); - sscanf(line,"%d %lg",&tmp,&file->mass); - utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error); - nwords = sscanf(line,"%d %lg %d %lg %lg", - &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut); + MPI_Bcast(&file->mass, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&file->nrho, 1, MPI_INT, 0, world); + MPI_Bcast(&file->drho, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&file->nr, 1, MPI_INT, 0, world); + MPI_Bcast(&file->dr, 1, MPI_DOUBLE, 0, world); + MPI_Bcast(&file->cut, 1, MPI_DOUBLE, 0, world); + + if(comm->me != 0) { + memory->create(file->frho, (file->nrho+1), "pair:frho"); + memory->create(file->rhor, (file->nr+1), "pair:rhor"); + memory->create(file->zr, (file->nr+1), "pair:zr"); } - MPI_Bcast(&nwords,1,MPI_INT,0,world); - MPI_Bcast(&file->mass,1,MPI_DOUBLE,0,world); - MPI_Bcast(&file->nrho,1,MPI_INT,0,world); - MPI_Bcast(&file->drho,1,MPI_DOUBLE,0,world); - MPI_Bcast(&file->nr,1,MPI_INT,0,world); - MPI_Bcast(&file->dr,1,MPI_DOUBLE,0,world); - MPI_Bcast(&file->cut,1,MPI_DOUBLE,0,world); - - if ((nwords != 5) || (file->nrho <= 0) || (file->nr <= 0) || (file->dr <= 0.0)) - error->all(FLERR,"Invalid EAM potential file"); - - memory->create(file->frho,(file->nrho+1),"pair:frho"); - memory->create(file->rhor,(file->nr+1),"pair:rhor"); - memory->create(file->zr,(file->nr+1),"pair:zr"); - - if (me == 0) grab(fptr,file->nrho,&file->frho[1]); - MPI_Bcast(&file->frho[1],file->nrho,MPI_DOUBLE,0,world); - - if (me == 0) grab(fptr,file->nr,&file->zr[1]); - MPI_Bcast(&file->zr[1],file->nr,MPI_DOUBLE,0,world); - - if (me == 0) grab(fptr,file->nr,&file->rhor[1]); - MPI_Bcast(&file->rhor[1],file->nr,MPI_DOUBLE,0,world); - - if (me == 0) fclose(fptr); + MPI_Bcast(&file->frho[1], file->nrho, MPI_DOUBLE, 0, world); + MPI_Bcast(&file->zr[1], file->nr, MPI_DOUBLE, 0, world); + MPI_Bcast(&file->rhor[1], file->nr, MPI_DOUBLE, 0, world); } /* ---------------------------------------------------------------------- diff --git a/src/potential_file_reader.cpp b/src/potential_file_reader.cpp index 2e79b5843c..bf886c5f97 100644 --- a/src/potential_file_reader.cpp +++ b/src/potential_file_reader.cpp @@ -21,6 +21,7 @@ #include "comm.h" #include "potential_file_reader.h" #include "utils.h" +#include "tokenizer.h" #include @@ -28,7 +29,7 @@ using namespace LAMMPS_NS; PotentialFileReader::PotentialFileReader(LAMMPS *lmp, const std::string &filename, - const std::string &potential_name) : Pointers(lmp) { + const std::string &potential_name) : Pointers(lmp), filename(filename) { if (comm->me != 0) { error->one(FLERR, "PotentialFileReader should only be called by proc 0!"); } @@ -46,6 +47,16 @@ PotentialFileReader::~PotentialFileReader() { fclose(fp); } +void PotentialFileReader::skip_line() { + char *ptr = fgets(line, MAXLINE, fp); + if (ptr == nullptr) { + // EOF + char str[128]; + snprintf(str, 128, "Missing line in %s potential file!", potential_name.c_str()); + error->one(FLERR, str); + } +} + char *PotentialFileReader::next_line(int nparams) { // concatenate lines until have nparams words int n = 0; @@ -95,3 +106,24 @@ char *PotentialFileReader::next_line(int nparams) { return line; } + +void PotentialFileReader::next_dvector(int n, double * list) { + int i = 0; + while (i < n) { + char *ptr = fgets(line, MAXLINE, fp); + + if (ptr == nullptr) { + // EOF + if (i < n) { + char str[128]; + snprintf(str, 128, "Incorrect format in %s potential file! %d/%d values", potential_name.c_str(), i, n); + error->one(FLERR, str); + } + } + + ValueTokenizer values(line); + while(values.has_next()) { + list[i++] = values.next_double(); + } + } +} diff --git a/src/potential_file_reader.h b/src/potential_file_reader.h index 1718251f4b..b18d3841c3 100644 --- a/src/potential_file_reader.h +++ b/src/potential_file_reader.h @@ -26,6 +26,7 @@ namespace LAMMPS_NS { class PotentialFileReader : protected Pointers { std::string potential_name; + std::string filename; static const int MAXLINE = 1024; char line[MAXLINE]; FILE *fp; @@ -34,7 +35,9 @@ namespace LAMMPS_NS PotentialFileReader(class LAMMPS *lmp, const std::string &filename, const std::string &potential_name); ~PotentialFileReader(); - char *next_line(int nparams); + void skip_line(); + char * next_line(int nparams); + void next_dvector(int n, double * list); }; } // namespace LAMMPS_NS