Unverified Commit 2b9ab589 authored by Richard Berger's avatar Richard Berger
Browse files

Update accelerator pair eam alloy

parent 903a73d2
Loading
Loading
Loading
Loading
+92 −75
Original line number Diff line number Diff line
@@ -31,11 +31,11 @@
#include "domain.h"
#include "utils.h"
#include "suffix.h"
#include "tokenizer.h"
#include "potential_file_reader.h"

using namespace LAMMPS_NS;

#define MAXLINE 1024

// External functions from cuda library for atom decomposition

int eam_alloy_gpu_init(const int ntypes, double host_cutforcesq,
@@ -369,58 +369,73 @@ void PairEAMAlloyGPU::read_file(char *filename)
{
  Setfl *file = setfl;

  // open potential file
  // read potential file
  if(comm->me == 0) {
    PotentialFileReader reader(lmp, filename, "EAM");

  int me = comm->me;
  FILE *fptr;
  char line[MAXLINE];
    try {
      char * line = nullptr;

  if (me == 0) {
    fptr = fopen(filename,"r");
    if (fptr == NULL) {
      char str[128];
      snprintf(str,128,"Cannot open EAM potential file %s",filename);
      error->one(FLERR,str);
    }
  }
      reader.skip_line();
      reader.skip_line();
      reader.skip_line();

  // read and broadcast header
      // extract element names from nelements line
      line = reader.next_line(1);
      ValueTokenizer values(line);
      file->nelements = values.next_int();

      if (values.count() != file->nelements + 1)
        error->one(FLERR,"Incorrect element names in EAM potential file");

  int n;
  if (me == 0) {
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    n = strlen(line) + 1;
      file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
        const std::string word = values.next_string();
        const int n = word.length() + 1;
        file->elements[i] = new char[n];
        strcpy(file->elements[i], word.c_str());
      }
  MPI_Bcast(&n,1,MPI_INT,0,world);
  MPI_Bcast(line,n,MPI_CHAR,0,world);

  sscanf(line,"%d",&file->nelements);
  int nwords = utils::count_words(line);
  if (nwords != file->nelements + 1)
    error->all(FLERR,"Incorrect element names in EAM potential file");
      // 

  char **words = new char*[file->nelements+1];
  nwords = 0;
  strtok(line," \t\n\r\f");
  while ( (words[nwords++] = strtok(NULL," \t\n\r\f")) ) continue;
      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->mass, file->nelements, "pair:mass");
      memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
      memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
      memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");

  file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
    n = strlen(words[i]) + 1;
    file->elements[i] = new char[n];
    strcpy(file->elements[i],words[i]);
        line = reader.next_line(2);
        values = ValueTokenizer(line);
        values.next_int(); // ignore
        file->mass[i] = values.next_double();

        reader.next_dvector(file->nrho, &file->frho[i][1]);
        reader.next_dvector(file->nr, &file->rhor[i][1]);
      }
  delete [] words;

  if (me == 0) {
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    sscanf(line,"%d %lg %d %lg %lg",
           &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut);
      for (int i = 0; i < file->nelements; i++) {
        for (int j = 0; j <= i; j++) {
          reader.next_dvector(file->nr, &file->z2r[i][j][1]);
        }
      }
    } catch (TokenizerException & e) {
      error->one(FLERR, e.what());
    }
  }

  // broadcast potential information
  MPI_Bcast(&file->nelements, 1, MPI_INT, 0, world);

  MPI_Bcast(&file->nrho, 1, MPI_INT, 0, world);
  MPI_Bcast(&file->drho, 1, MPI_DOUBLE, 0, world);
@@ -428,35 +443,37 @@ void PairEAMAlloyGPU::read_file(char *filename)
  MPI_Bcast(&file->dr, 1, MPI_DOUBLE, 0, world);
  MPI_Bcast(&file->cut, 1, MPI_DOUBLE, 0, world);

  file->mass = new double[file->nelements];
  // allocate memory on other procs
  if (comm->me != 0) {
    file->elements = new char*[file->nelements];
    for (int i = 0; i < file->nelements; i++) file->elements[i] = nullptr;
    memory->create(file->mass, file->nelements, "pair:mass");
    memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
    memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
  memory->create(file->z2r,file->nelements,file->nelements,file->nr+1,
                 "pair:z2r");
    memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");
  }

  int i,j,tmp;
  for (i = 0; i < file->nelements; i++) {
    if (me == 0) {
      utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
      sscanf(line,"%d %lg",&tmp,&file->mass[i]);
  // broadcast file->elements string array
  for (int i = 0; i < file->nelements; i++) {
    int n = strlen(file->elements[i]) + 1;
    MPI_Bcast(&n, 1, MPI_INT, 0, world);
    if (comm->me != 0) file->elements[i] = new char[n];
    MPI_Bcast(file->elements[i], n, MPI_CHAR, 0, world);
  }
    MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world);

    if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]);
  // broadcast file->mass, frho, rhor
  for (int i = 0; i < file->nelements; i++) {
    MPI_Bcast(&file->mass[i], 1, MPI_DOUBLE, 0, world);
    MPI_Bcast(&file->frho[i][1], file->nrho, MPI_DOUBLE, 0, world);
    if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]);
    MPI_Bcast(&file->rhor[i][1], file->nr, MPI_DOUBLE, 0, world);
  }

  for (i = 0; i < file->nelements; i++)
    for (j = 0; j <= i; j++) {
      if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]);
  // broadcast file->z2r
  for (int i = 0; i < file->nelements; i++) {
    for (int j = 0; j <= i; j++) {
      MPI_Bcast(&file->z2r[i][j][1], file->nr, MPI_DOUBLE, 0, world);
    }

  // close the potential file

  if (me == 0) fclose(fptr);
  }
}

/* ----------------------------------------------------------------------
+92 −75
Original line number Diff line number Diff line
@@ -30,11 +30,11 @@
#include "error.h"
#include "atom_masks.h"
#include "utils.h"
#include "tokenizer.h"
#include "potential_file_reader.h"

using namespace LAMMPS_NS;

#define MAXLINE 1024

// Cannot use virtual inheritance on the GPU, so must duplicate code

/* ---------------------------------------------------------------------- */
@@ -983,58 +983,73 @@ void PairEAMAlloyKokkos<DeviceType>::read_file(char *filename)
{
  Setfl *file = setfl;

  // open potential file
  // read potential file
  if(comm->me == 0) {
    PotentialFileReader reader(lmp, filename, "EAM");

  int me = comm->me;
  FILE *fptr;
  char line[MAXLINE];
    try {
      char * line = nullptr;

  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);
    }
  }
      reader.skip_line();
      reader.skip_line();
      reader.skip_line();

  // read and broadcast header
      // extract element names from nelements line
      line = reader.next_line(1);
      ValueTokenizer values(line);
      file->nelements = values.next_int();

      if (values.count() != file->nelements + 1)
        error->one(FLERR,"Incorrect element names in EAM potential file");

  int n;
  if (me == 0) {
    fgets(line,MAXLINE,fptr);
    fgets(line,MAXLINE,fptr);
    fgets(line,MAXLINE,fptr);
    fgets(line,MAXLINE,fptr);
    n = strlen(line) + 1;
      file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
        const std::string word = values.next_string();
        const int n = word.length() + 1;
        file->elements[i] = new char[n];
        strcpy(file->elements[i], word.c_str());
      }
  MPI_Bcast(&n,1,MPI_INT,0,world);
  MPI_Bcast(line,n,MPI_CHAR,0,world);

  sscanf(line,"%d",&file->nelements);
  int nwords = utils::count_words(line);
  if (nwords != file->nelements + 1)
    error->all(FLERR,"Incorrect element names in EAM potential file");
      // 

  char **words = new char*[file->nelements+1];
  nwords = 0;
  strtok(line," \t\n\r\f");
  while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue;
      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->mass, file->nelements, "pair:mass");
      memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
      memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
      memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");

  file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
    n = strlen(words[i]) + 1;
    file->elements[i] = new char[n];
    strcpy(file->elements[i],words[i]);
        line = reader.next_line(2);
        values = ValueTokenizer(line);
        values.next_int(); // ignore
        file->mass[i] = values.next_double();

        reader.next_dvector(file->nrho, &file->frho[i][1]);
        reader.next_dvector(file->nr, &file->rhor[i][1]);
      }
  delete [] words;

  if (me == 0) {
    fgets(line,MAXLINE,fptr);
    sscanf(line,"%d %lg %d %lg %lg",
           &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut);
      for (int i = 0; i < file->nelements; i++) {
        for (int j = 0; j <= i; j++) {
          reader.next_dvector(file->nr, &file->z2r[i][j][1]);
        }
      }
    } catch (TokenizerException & e) {
      error->one(FLERR, e.what());
    }
  }

  // broadcast potential information
  MPI_Bcast(&file->nelements, 1, MPI_INT, 0, world);

  MPI_Bcast(&file->nrho, 1, MPI_INT, 0, world);
  MPI_Bcast(&file->drho, 1, MPI_DOUBLE, 0, world);
@@ -1042,35 +1057,37 @@ void PairEAMAlloyKokkos<DeviceType>::read_file(char *filename)
  MPI_Bcast(&file->dr, 1, MPI_DOUBLE, 0, world);
  MPI_Bcast(&file->cut, 1, MPI_DOUBLE, 0, world);

  file->mass = new double[file->nelements];
  // allocate memory on other procs
  if (comm->me != 0) {
    file->elements = new char*[file->nelements];
    for (int i = 0; i < file->nelements; i++) file->elements[i] = nullptr;
    memory->create(file->mass, file->nelements, "pair:mass");
    memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
    memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
  memory->create(file->z2r,file->nelements,file->nelements,file->nr+1,
                 "pair:z2r");
    memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");
  }

  int i,j,tmp;
  for (i = 0; i < file->nelements; i++) {
    if (me == 0) {
      fgets(line,MAXLINE,fptr);
      sscanf(line,"%d %lg",&tmp,&file->mass[i]);
  // broadcast file->elements string array
  for (int i = 0; i < file->nelements; i++) {
    int n = strlen(file->elements[i]) + 1;
    MPI_Bcast(&n, 1, MPI_INT, 0, world);
    if (comm->me != 0) file->elements[i] = new char[n];
    MPI_Bcast(file->elements[i], n, MPI_CHAR, 0, world);
  }
    MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world);

    if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]);
  // broadcast file->mass, frho, rhor
  for (int i = 0; i < file->nelements; i++) {
    MPI_Bcast(&file->mass[i], 1, MPI_DOUBLE, 0, world);
    MPI_Bcast(&file->frho[i][1], file->nrho, MPI_DOUBLE, 0, world);
    if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]);
    MPI_Bcast(&file->rhor[i][1], file->nr, MPI_DOUBLE, 0, world);
  }

  for (i = 0; i < file->nelements; i++)
    for (j = 0; j <= i; j++) {
      if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]);
  // broadcast file->z2r
  for (int i = 0; i < file->nelements; i++) {
    for (int j = 0; j <= i; j++) {
      MPI_Bcast(&file->z2r[i][j][1], file->nr, MPI_DOUBLE, 0, world);
    }

  // close the potential file

  if (me == 0) fclose(fptr);
  }
}

/* ----------------------------------------------------------------------
+92 −75
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@
#include "memory.h"
#include "error.h"
#include "utils.h"
#include "tokenizer.h"
#include "potential_file_reader.h"

using namespace LAMMPS_NS;

#define MAXLINE 1024

/* ---------------------------------------------------------------------- */

PairEAMAlloyIntel::PairEAMAlloyIntel(LAMMPS *lmp) : PairEAMIntel(lmp)
@@ -117,94 +117,111 @@ void PairEAMAlloyIntel::read_file(char *filename)
{
  Setfl *file = setfl;

  // open potential file
  // read potential file
  if(comm->me == 0) {
    PotentialFileReader reader(lmp, filename, "EAM");

  int me = comm->me;
  FILE *fptr;
  char line[MAXLINE];
    try {
      char * line = nullptr;

  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);
    }
  }
      reader.skip_line();
      reader.skip_line();
      reader.skip_line();

  // read and broadcast header
      // extract element names from nelements line
      line = reader.next_line(1);
      ValueTokenizer values(line);
      file->nelements = values.next_int();

  int n;
  if (me == 0) {
    fgets(line,MAXLINE,fptr);
    fgets(line,MAXLINE,fptr);
    fgets(line,MAXLINE,fptr);
    fgets(line,MAXLINE,fptr);
    n = strlen(line) + 1;
      if (values.count() != file->nelements + 1)
        error->one(FLERR,"Incorrect element names in EAM potential file");

      file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
        const std::string word = values.next_string();
        const int n = word.length() + 1;
        file->elements[i] = new char[n];
        strcpy(file->elements[i], word.c_str());
      }
  MPI_Bcast(&n,1,MPI_INT,0,world);
  MPI_Bcast(line,n,MPI_CHAR,0,world);

  sscanf(line,"%d",&file->nelements);
  int nwords = utils::count_words(line);
  if (nwords != file->nelements + 1)
    error->all(FLERR,"Incorrect element names in EAM potential file");
      // 

  char **words = new char*[file->nelements+1];
  nwords = 0;
  strtok(line," \t\n\r\f");
  while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue;
      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->mass, file->nelements, "pair:mass");
      memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
      memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
      memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");

  file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
    n = strlen(words[i]) + 1;
    file->elements[i] = new char[n];
    strcpy(file->elements[i],words[i]);
        line = reader.next_line(2);
        values = ValueTokenizer(line);
        values.next_int(); // ignore
        file->mass[i] = values.next_double();

        reader.next_dvector(file->nrho, &file->frho[i][1]);
        reader.next_dvector(file->nr, &file->rhor[i][1]);
      }
  delete [] words;

  if (me == 0) {
    fgets(line,MAXLINE,fptr);
    sscanf(line,"%d %lg %d %lg %lg",
           &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut);
      for (int i = 0; i < file->nelements; i++) {
        for (int j = 0; j <= i; j++) {
          reader.next_dvector(file->nr, &file->z2r[i][j][1]);
        }
      }
    } catch (TokenizerException & e) {
      error->one(FLERR, e.what());
    }
  }

  // broadcast potential information
  MPI_Bcast(&file->nelements, 1, MPI_INT, 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);

  file->mass = new double[file->nelements];
  // allocate memory on other procs
  if (comm->me != 0) {
    file->elements = new char*[file->nelements];
    for (int i = 0; i < file->nelements; i++) file->elements[i] = nullptr;
    memory->create(file->mass, file->nelements, "pair:mass");
    memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
    memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
  memory->create(file->z2r,file->nelements,file->nelements,file->nr+1,
                 "pair:z2r");

  int i,j,tmp;
  for (i = 0; i < file->nelements; i++) {
    if (me == 0) {
      fgets(line,MAXLINE,fptr);
      sscanf(line,"%d %lg",&tmp,&file->mass[i]);
    memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");
  }

  // broadcast file->elements string array
  for (int i = 0; i < file->nelements; i++) {
    int n = strlen(file->elements[i]) + 1;
    MPI_Bcast(&n, 1, MPI_INT, 0, world);
    if (comm->me != 0) file->elements[i] = new char[n];
    MPI_Bcast(file->elements[i], n, MPI_CHAR, 0, world);
  }
    MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world);

    if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]);
  // broadcast file->mass, frho, rhor
  for (int i = 0; i < file->nelements; i++) {
    MPI_Bcast(&file->mass[i], 1, MPI_DOUBLE, 0, world);
    MPI_Bcast(&file->frho[i][1], file->nrho, MPI_DOUBLE, 0, world);
    if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]);
    MPI_Bcast(&file->rhor[i][1], file->nr, MPI_DOUBLE, 0, world);
  }

  for (i = 0; i < file->nelements; i++)
    for (j = 0; j <= i; j++) {
      if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]);
  // broadcast file->z2r
  for (int i = 0; i < file->nelements; i++) {
    for (int j = 0; j <= i; j++) {
      MPI_Bcast(&file->z2r[i][j][1], file->nr, MPI_DOUBLE, 0, world);
    }

  // close the potential file

  if (me == 0) fclose(fptr);
  }
}

/* ----------------------------------------------------------------------
+92 −75
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@
#include "memory.h"
#include "error.h"
#include "utils.h"
#include "tokenizer.h"
#include "potential_file_reader.h"

using namespace LAMMPS_NS;

#define MAXLINE 1024

/* ---------------------------------------------------------------------- */

PairEAMAlloyOMP::PairEAMAlloyOMP(LAMMPS *lmp) : PairEAMOMP(lmp)
@@ -117,94 +117,111 @@ void PairEAMAlloyOMP::read_file(char *filename)
{
  Setfl *file = setfl;

  // open potential file
  // read potential file
  if(comm->me == 0) {
    PotentialFileReader reader(PairEAM::lmp, filename, "EAM");

  int me = comm->me;
  FILE *fptr;
  char line[MAXLINE];
    try {
      char * line = nullptr;

  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);
    }
  }
      reader.skip_line();
      reader.skip_line();
      reader.skip_line();

  // read and broadcast header
      // extract element names from nelements line
      line = reader.next_line(1);
      ValueTokenizer values(line);
      file->nelements = values.next_int();

  int n;
  if (me == 0) {
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    n = strlen(line) + 1;
      if (values.count() != file->nelements + 1)
        error->one(FLERR,"Incorrect element names in EAM potential file");

      file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
        const std::string word = values.next_string();
        const int n = word.length() + 1;
        file->elements[i] = new char[n];
        strcpy(file->elements[i], word.c_str());
      }
  MPI_Bcast(&n,1,MPI_INT,0,world);
  MPI_Bcast(line,n,MPI_CHAR,0,world);

  sscanf(line,"%d",&file->nelements);
  int nwords = utils::count_words(line);
  if (nwords != file->nelements + 1)
    error->all(FLERR,"Incorrect element names in EAM potential file");
      // 

  char **words = new char*[file->nelements+1];
  nwords = 0;
  strtok(line," \t\n\r\f");
  while ((words[nwords++] = strtok(NULL," \t\n\r\f"))) continue;
      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->mass, file->nelements, "pair:mass");
      memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
      memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
      memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");

  file->elements = new char*[file->nelements];
      for (int i = 0; i < file->nelements; i++) {
    n = strlen(words[i]) + 1;
    file->elements[i] = new char[n];
    strcpy(file->elements[i],words[i]);
        line = reader.next_line(2);
        values = ValueTokenizer(line);
        values.next_int(); // ignore
        file->mass[i] = values.next_double();

        reader.next_dvector(file->nrho, &file->frho[i][1]);
        reader.next_dvector(file->nr, &file->rhor[i][1]);
      }
  delete [] words;

  if (me == 0) {
    utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
    sscanf(line,"%d %lg %d %lg %lg",
           &file->nrho,&file->drho,&file->nr,&file->dr,&file->cut);
      for (int i = 0; i < file->nelements; i++) {
        for (int j = 0; j <= i; j++) {
          reader.next_dvector(file->nr, &file->z2r[i][j][1]);
        }
      }
    } catch (TokenizerException & e) {
      error->one(FLERR, e.what());
    }
  }

  // broadcast potential information
  MPI_Bcast(&file->nelements, 1, MPI_INT, 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);

  file->mass = new double[file->nelements];
  // allocate memory on other procs
  if (comm->me != 0) {
    file->elements = new char*[file->nelements];
    for (int i = 0; i < file->nelements; i++) file->elements[i] = nullptr;
    memory->create(file->mass, file->nelements, "pair:mass");
    memory->create(file->frho, file->nelements, file->nrho + 1, "pair:frho");
    memory->create(file->rhor, file->nelements, file->nr + 1, "pair:rhor");
  memory->create(file->z2r,file->nelements,file->nelements,file->nr+1,
                 "pair:z2r");

  int i,j,tmp;
  for (i = 0; i < file->nelements; i++) {
    if (me == 0) {
      utils::sfgets(FLERR,line,MAXLINE,fptr,filename,error);
      sscanf(line,"%d %lg",&tmp,&file->mass[i]);
    memory->create(file->z2r, file->nelements, file->nelements, file->nr + 1, "pair:z2r");
  }

  // broadcast file->elements string array
  for (int i = 0; i < file->nelements; i++) {
    int n = strlen(file->elements[i]) + 1;
    MPI_Bcast(&n, 1, MPI_INT, 0, world);
    if (comm->me != 0) file->elements[i] = new char[n];
    MPI_Bcast(file->elements[i], n, MPI_CHAR, 0, world);
  }
    MPI_Bcast(&file->mass[i],1,MPI_DOUBLE,0,world);

    if (me == 0) grab(fptr,file->nrho,&file->frho[i][1]);
  // broadcast file->mass, frho, rhor
  for (int i = 0; i < file->nelements; i++) {
    MPI_Bcast(&file->mass[i], 1, MPI_DOUBLE, 0, world);
    MPI_Bcast(&file->frho[i][1], file->nrho, MPI_DOUBLE, 0, world);
    if (me == 0) grab(fptr,file->nr,&file->rhor[i][1]);
    MPI_Bcast(&file->rhor[i][1], file->nr, MPI_DOUBLE, 0, world);
  }

  for (i = 0; i < file->nelements; i++)
    for (j = 0; j <= i; j++) {
      if (me == 0) grab(fptr,file->nr,&file->z2r[i][j][1]);
  // broadcast file->z2r
  for (int i = 0; i < file->nelements; i++) {
    for (int j = 0; j <= i; j++) {
      MPI_Bcast(&file->z2r[i][j][1], file->nr, MPI_DOUBLE, 0, world);
    }

  // close the potential file

  if (me == 0) fclose(fptr);
  }
}

/* ----------------------------------------------------------------------