diff --git a/src/MAKE/Makefile.linux b/src/MAKE/Makefile.linux index f0348b3ee..cf39084f2 100755 --- a/src/MAKE/Makefile.linux +++ b/src/MAKE/Makefile.linux @@ -1,95 +1,95 @@ # linux = RedHat Linux box, Intel icc, MPICH2, FFTW SHELL = /bin/sh # --------------------------------------------------------------------- # compiler/linker settings # specify flags and libraries needed for your compiler CC = icc CCFLAGS = -O DEPFLAGS = -M LINK = icc LINKFLAGS = -O LIB = -lstdc++ ARCHIVE = ar ARFLAGS = -rc SIZE = size # --------------------------------------------------------------------- # LAMMPS-specific settings # specify settings for LAMMPS features you will use # if you change any -D setting, do full re-compile after "make clean" # LAMMPS ifdef settings, OPTIONAL # see possible settings in doc/Section_start.html#2_2 (step 4) -LMP_INC = -DLAMMPS_GZIP +LMP_INC = -DLAMMPS_GZIP -DLAMMPS_JPEG # MPI library, REQUIRED # see discussion in doc/Section_start.html#2_2 (step 5) # can point to dummy MPI library in src/STUBS as in Makefile.serial # INC = path for mpi.h, MPI compiler settings # PATH = path for MPI library # LIB = name of MPI library MPI_INC = -DMPICH_SKIP_MPICXX MPI_PATH = -MPI_LIB = -lmpich -lpthread +MPI_LIB = -lmpich -lmpl -lpthread # FFT library, OPTIONAL # see discussion in doc/Section_start.html#2_2 (step 6) # can be left blank to use provided KISS FFT library # INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings # PATH = path for FFT library # LIB = name of FFT library FFT_INC = -DFFT_FFTW FFT_PATH = FFT_LIB = -lfftw # JPEG library, OPTIONAL # see discussion in doc/Section_start.html#2_2 (step 7) # only needed if -DLAMMPS_JPEG listed with LMP_INC # INC = path for jpeglib.h # PATH = path for JPEG library # LIB = name of JPEG library JPG_INC = JPG_PATH = -JPG_LIB = +JPG_LIB = -ljpeg # --------------------------------------------------------------------- # build rules and dependencies # no need to edit this section include Makefile.package.settings include Makefile.package EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) # Link target $(EXE): $(OBJ) $(LINK) $(LINKFLAGS) $(EXTRA_PATH) $(OBJ) $(EXTRA_LIB) $(LIB) -o $(EXE) $(SIZE) $(EXE) # Library target lib: $(OBJ) $(ARCHIVE) $(ARFLAGS) $(EXE) $(OBJ) # Compilation rules %.o:%.cpp $(CC) $(CCFLAGS) $(EXTRA_INC) -c $< %.d:%.cpp $(CC) $(CCFLAGS) $(EXTRA_INC) $(DEPFLAGS) $< > $@ # Individual dependencies DEPENDS = $(OBJ:.o=.d) sinclude $(DEPENDS) diff --git a/src/read_data.cpp b/src/read_data.cpp index 772c3a382..a96a566b0 100644 --- a/src/read_data.cpp +++ b/src/read_data.cpp @@ -1,1451 +1,1448 @@ /* ---------------------------------------------------------------------- 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. ------------------------------------------------------------------------- */ #include "lmptype.h" #include "math.h" #include "mpi.h" #include "string.h" #include "stdlib.h" #include "ctype.h" #include "read_data.h" #include "atom.h" #include "atom_vec.h" #include "atom_vec_ellipsoid.h" #include "atom_vec_line.h" #include "atom_vec_tri.h" #include "comm.h" #include "update.h" #include "force.h" #include "pair.h" #include "domain.h" #include "bond.h" #include "angle.h" #include "dihedral.h" #include "improper.h" #include "error.h" #include "memory.h" #include "special.h" using namespace LAMMPS_NS; #define MAXLINE 256 #define LB_FACTOR 1.1 #define CHUNK 1024 #define DELTA 4 // must be 2 or larger // customize for new sections #define NSECTIONS 23 // change when add to header::section_keywords -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) - /* ---------------------------------------------------------------------- */ ReadData::ReadData(LAMMPS *lmp) : Pointers(lmp) { MPI_Comm_rank(world,&me); line = new char[MAXLINE]; keyword = new char[MAXLINE]; buffer = new char[CHUNK*MAXLINE]; narg = maxarg = 0; arg = NULL; // customize for new sections // pointers to atom styles that store extra info nellipsoids = 0; avec_ellipsoid = (AtomVecEllipsoid *) atom->style_match("ellipsoid"); nlines = 0; avec_line = (AtomVecLine *) atom->style_match("line"); ntris = 0; avec_tri = (AtomVecTri *) atom->style_match("tri"); } /* ---------------------------------------------------------------------- */ ReadData::~ReadData() { delete [] line; delete [] keyword; delete [] buffer; memory->sfree(arg); } /* ---------------------------------------------------------------------- */ void ReadData::command(int narg, char **arg) { if (narg != 1) error->all(FLERR,"Illegal read_data command"); if (domain->box_exist) error->all(FLERR,"Cannot read_data after simulation box is defined"); if (domain->dimension == 2 && domain->zperiodic == 0) error->all(FLERR,"Cannot run 2d simulation with nonperiodic Z dimension"); // scan data file to determine max topology needed per atom // allocate initial topology arrays if (atom->molecular) { if (me == 0) { if (screen) fprintf(screen,"Scanning data file ...\n"); open(arg[0]); header(0); scan(atom->bond_per_atom,atom->angle_per_atom, atom->dihedral_per_atom,atom->improper_per_atom); if (compressed) pclose(fp); else fclose(fp); atom->bond_per_atom += atom->extra_bond_per_atom; } MPI_Bcast(&atom->bond_per_atom,1,MPI_INT,0,world); MPI_Bcast(&atom->angle_per_atom,1,MPI_INT,0,world); MPI_Bcast(&atom->dihedral_per_atom,1,MPI_INT,0,world); MPI_Bcast(&atom->improper_per_atom,1,MPI_INT,0,world); } else atom->bond_per_atom = atom->angle_per_atom = atom->dihedral_per_atom = atom->improper_per_atom = 0; // read header info if (me == 0) { if (screen) fprintf(screen,"Reading data file ...\n"); open(arg[0]); } header(1); domain->box_exist = 1; // problem setup using info from header update->ntimestep = 0; int n; if (comm->nprocs == 1) n = static_cast<int> (atom->natoms); else n = static_cast<int> (LB_FACTOR * atom->natoms / comm->nprocs); atom->allocate_type_arrays(); atom->avec->grow(n); n = atom->nmax; domain->print_box(" "); domain->set_initial_box(); domain->set_global_box(); comm->set_procs(); domain->set_local_box(); // customize for new sections // read rest of file in free format int atomflag = 0; while (strlen(keyword)) { if (strcmp(keyword,"Atoms") == 0) { atoms(); atomflag = 1; } else if (strcmp(keyword,"Velocities") == 0) { if (atomflag == 0) error->all(FLERR,"Must read Atoms before Velocities"); velocities(); } else if (strcmp(keyword,"Ellipsoids") == 0) { if (!avec_ellipsoid) error->all(FLERR,"Invalid data file section: Ellipsoids"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Ellipsoids"); bonus(nellipsoids,(AtomVec *) avec_ellipsoid,"ellipsoids"); } else if (strcmp(keyword,"Lines") == 0) { if (!avec_line) error->all(FLERR,"Invalid data file section: Lines"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Lines"); bonus(nlines,(AtomVec *) avec_line,"lines"); } else if (strcmp(keyword,"Triangles") == 0) { if (!avec_tri) error->all(FLERR,"Invalid data file section: Triangles"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Triangles"); bonus(ntris,(AtomVec *) avec_tri,"triangles"); } else if (strcmp(keyword,"Bonds") == 0) { if (atom->avec->bonds_allow == 0) error->all(FLERR,"Invalid data file section: Bonds"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Bonds"); bonds(); } else if (strcmp(keyword,"Angles") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: Angles"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Angles"); angles(); } else if (strcmp(keyword,"Dihedrals") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: Dihedrals"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Dihedrals"); dihedrals(); } else if (strcmp(keyword,"Impropers") == 0) { if (atom->avec->impropers_allow == 0) error->all(FLERR,"Invalid data file section: Impropers"); if (atomflag == 0) error->all(FLERR,"Must read Atoms before Impropers"); impropers(); } else if (strcmp(keyword,"Masses") == 0) { mass(); } else if (strcmp(keyword,"Pair Coeffs") == 0) { if (force->pair == NULL) error->all(FLERR,"Must define pair_style before Pair Coeffs"); paircoeffs(); } else if (strcmp(keyword,"Bond Coeffs") == 0) { if (atom->avec->bonds_allow == 0) error->all(FLERR,"Invalid data file section: Bond Coeffs"); if (force->bond == NULL) error->all(FLERR,"Must define bond_style before Bond Coeffs"); bondcoeffs(); } else if (strcmp(keyword,"Angle Coeffs") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: Angle Coeffs"); if (force->angle == NULL) error->all(FLERR,"Must define angle_style before Angle Coeffs"); anglecoeffs(0); } else if (strcmp(keyword,"Dihedral Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: Dihedral Coeffs"); if (force->dihedral == NULL) error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs"); dihedralcoeffs(0); } else if (strcmp(keyword,"Improper Coeffs") == 0) { if (atom->avec->impropers_allow == 0) error->all(FLERR,"Invalid data file section: Improper Coeffs"); if (force->improper == NULL) error->all(FLERR,"Must define improper_style before Improper Coeffs"); impropercoeffs(0); } else if (strcmp(keyword,"BondBond Coeffs") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: BondBond Coeffs"); if (force->angle == NULL) error->all(FLERR,"Must define angle_style before BondBond Coeffs"); anglecoeffs(1); } else if (strcmp(keyword,"BondAngle Coeffs") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: BondAngle Coeffs"); if (force->angle == NULL) error->all(FLERR,"Must define angle_style before BondAngle Coeffs"); anglecoeffs(2); } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before " "MiddleBondTorsion Coeffs"); dihedralcoeffs(1); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before EndBondTorsion Coeffs"); dihedralcoeffs(2); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before AngleTorsion Coeffs"); dihedralcoeffs(3); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before " "AngleAngleTorsion Coeffs"); dihedralcoeffs(4); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: BondBond13 Coeffs"); if (force->dihedral == NULL) error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs"); dihedralcoeffs(5); } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) { if (atom->avec->impropers_allow == 0) error->all(FLERR,"Invalid data file section: AngleAngle Coeffs"); if (force->improper == NULL) error->all(FLERR,"Must define improper_style before AngleAngle Coeffs"); impropercoeffs(1); } else { char str[128]; sprintf(str,"Unknown identifier in data file: %s",keyword); error->all(FLERR,str); } parse_keyword(0,1); } // close file if (me == 0) { if (compressed) pclose(fp); else fclose(fp); } // error if natoms > 0 yet no atoms were read if (atom->natoms > 0 && atomflag == 0) error->all(FLERR,"No atoms in data file"); // create bond topology now that system is defined if (atom->molecular) { Special special(lmp); special.build(); } } /* ---------------------------------------------------------------------- read free-format header of data file if flag = 0, only called by proc 0 if flag = 1, called by all procs so bcast lines as read them 1st line and blank lines are skipped non-blank lines are checked for header keywords and leading value is read header ends with EOF or non-blank line containing no header keyword if EOF, line is set to blank line else line has first keyword line for rest of file ------------------------------------------------------------------------- */ void ReadData::header(int flag) { int n; char *ptr; // customize for new sections char *section_keywords[NSECTIONS] = {"Atoms","Velocities","Ellipsoids","Lines","Triangles", "Bonds","Angles","Dihedrals","Impropers", "Masses","Pair Coeffs","Bond Coeffs","Angle Coeffs", "Dihedral Coeffs","Improper Coeffs", "BondBond Coeffs","BondAngle Coeffs","MiddleBondTorsion Coeffs", "EndBondTorsion Coeffs","AngleTorsion Coeffs", "AngleAngleTorsion Coeffs","BondBond13 Coeffs","AngleAngle Coeffs"}; // skip 1st line of file if (me == 0) { char *eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); } // customize for new header lines while (1) { // read a line and bcast length if flag is set if (me == 0) { if (fgets(line,MAXLINE,fp) == NULL) n = 0; else n = strlen(line) + 1; } if (flag) MPI_Bcast(&n,1,MPI_INT,0,world); // if n = 0 then end-of-file so return with blank line if (n == 0) { line[0] = '\0'; return; } // bcast line if flag is set if (flag) MPI_Bcast(line,n,MPI_CHAR,0,world); // trim anything from '#' onward // if line is blank, continue if (ptr = strchr(line,'#')) *ptr = '\0'; if (strspn(line," \t\n\r") == strlen(line)) continue; // search line for header keyword and set corresponding variable if (strstr(line,"atoms")) sscanf(line,BIGINT_FORMAT,&atom->natoms); else if (strstr(line,"bonds")) sscanf(line,BIGINT_FORMAT,&atom->nbonds); else if (strstr(line,"angles")) sscanf(line,BIGINT_FORMAT,&atom->nangles); else if (strstr(line,"dihedrals")) sscanf(line,BIGINT_FORMAT, &atom->ndihedrals); else if (strstr(line,"impropers")) sscanf(line,BIGINT_FORMAT, &atom->nimpropers); else if (strstr(line,"atom types")) sscanf(line,"%d",&atom->ntypes); else if (strstr(line,"bond types")) sscanf(line,"%d",&atom->nbondtypes); else if (strstr(line,"angle types")) sscanf(line,"%d",&atom->nangletypes); else if (strstr(line,"dihedral types")) sscanf(line,"%d",&atom->ndihedraltypes); else if (strstr(line,"improper types")) sscanf(line,"%d",&atom->nimpropertypes); else if (strstr(line,"extra bond per atom")) sscanf(line,"%d",&atom->extra_bond_per_atom); else if (strstr(line,"ellipsoids")) { if (!avec_ellipsoid) error->all(FLERR,"No ellipsoids allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nellipsoids); } else if (strstr(line,"lines")) { if (!avec_line) error->all(FLERR,"No lines allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&nlines); } else if (strstr(line,"triangles")) { if (!avec_tri) error->all(FLERR,"No triangles allowed with this atom style"); sscanf(line,BIGINT_FORMAT,&ntris); } else if (strstr(line,"xlo xhi")) sscanf(line,"%lg %lg",&domain->boxlo[0],&domain->boxhi[0]); else if (strstr(line,"ylo yhi")) sscanf(line,"%lg %lg",&domain->boxlo[1],&domain->boxhi[1]); else if (strstr(line,"zlo zhi")) sscanf(line,"%lg %lg",&domain->boxlo[2],&domain->boxhi[2]); else if (strstr(line,"xy xz yz")) { domain->triclinic = 1; sscanf(line,"%lg %lg %lg",&domain->xy,&domain->xz,&domain->yz); } else break; } // error check on total system size if (atom->natoms < 0 || atom->natoms > MAXBIGINT || atom->nbonds < 0 || atom->nbonds > MAXBIGINT || atom->nangles < 0 || atom->nangles > MAXBIGINT || atom->ndihedrals < 0 || atom->ndihedrals > MAXBIGINT || atom->nimpropers < 0 || atom->nimpropers > MAXBIGINT) { if (flag == 0) error->one(FLERR,"System in data file is too big"); else error->all(FLERR,"System in data file is too big"); } // check that exiting string is a valid section keyword parse_keyword(1,flag); for (n = 0; n < NSECTIONS; n++) if (strcmp(keyword,section_keywords[n]) == 0) break; if (n == NSECTIONS) { char str[128]; sprintf(str,"Unknown identifier in data file: %s",keyword); error->all(FLERR,str); } // error check on consistency of header values if ((atom->nbonds || atom->nbondtypes) && atom->avec->bonds_allow == 0) error->one(FLERR,"No bonds allowed with this atom style"); if ((atom->nangles || atom->nangletypes) && atom->avec->angles_allow == 0) error->one(FLERR,"No angles allowed with this atom style"); if ((atom->ndihedrals || atom->ndihedraltypes) && atom->avec->dihedrals_allow == 0) error->one(FLERR,"No dihedrals allowed with this atom style"); if ((atom->nimpropers || atom->nimpropertypes) && atom->avec->impropers_allow == 0) error->one(FLERR,"No impropers allowed with this atom style"); if (atom->nbonds > 0 && atom->nbondtypes <= 0) error->one(FLERR,"Bonds defined but no bond types"); if (atom->nangles > 0 && atom->nangletypes <= 0) error->one(FLERR,"Angles defined but no angle types"); if (atom->ndihedrals > 0 && atom->ndihedraltypes <= 0) error->one(FLERR,"Dihedrals defined but no dihedral types"); if (atom->nimpropers > 0 && atom->nimpropertypes <= 0) error->one(FLERR,"Impropers defined but no improper types"); } /* ---------------------------------------------------------------------- read all atoms ------------------------------------------------------------------------- */ void ReadData::atoms() { int i,m,nchunk; bigint nread = 0; bigint natoms = atom->natoms; while (nread < natoms) { if (natoms-nread > CHUNK) nchunk = CHUNK; else nchunk = natoms-nread; if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_atoms(nchunk,buffer); nread += nchunk; } // check that all atoms were assigned correctly bigint tmp = atom->nlocal; MPI_Allreduce(&tmp,&natoms,1,MPI_LMP_BIGINT,MPI_SUM,world); if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " atoms\n",natoms); if (logfile) fprintf(logfile," " BIGINT_FORMAT " atoms\n",natoms); } if (natoms != atom->natoms) error->all(FLERR,"Did not assign all atoms correctly"); // if any atom ID < 0, error // if all atom IDs = 0, tag_enable = 0 // if any atom ID > 0, error if any atom ID == 0 // not checking if atom IDs > natoms or are unique int nlocal = atom->nlocal; int *tag = atom->tag; int flag = 0; for (int i = 0; i < nlocal; i++) if (tag[i] < 0) flag = 1; int flag_all; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) error->all(FLERR,"Invalid atom ID in Atoms section of data file"); flag = 0; for (int i = 0; i < nlocal; i++) if (tag[i] > 0) flag = 1; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_MAX,world); if (flag_all == 0) atom->tag_enable = 0; if (atom->tag_enable) { flag = 0; for (int i = 0; i < nlocal; i++) if (tag[i] == 0) flag = 1; MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); if (flag_all) error->all(FLERR,"Invalid atom ID in Atoms section of data file"); } // create global mapping if (atom->map_style) { atom->map_init(); atom->map_set(); } } /* ---------------------------------------------------------------------- read all velocities to find atoms, must build atom map if not a molecular system ------------------------------------------------------------------------- */ void ReadData::velocities() { int i,m,nchunk; int mapflag = 0; if (atom->map_style == 0) { mapflag = 1; atom->map_style = 1; atom->map_init(); atom->map_set(); } bigint nread = 0; bigint natoms = atom->natoms; while (nread < natoms) { if (natoms-nread > CHUNK) nchunk = CHUNK; else nchunk = natoms-nread; if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_vels(nchunk,buffer); nread += nchunk; } if (mapflag) { atom->map_delete(); atom->map_style = 0; } if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " velocities\n",natoms); if (logfile) fprintf(logfile," " BIGINT_FORMAT " velocities\n",natoms); } } /* ---------------------------------------------------------------------- read all bonus data to find atoms, must build atom map if not a molecular system ------------------------------------------------------------------------- */ void ReadData::bonus(bigint nbonus, AtomVec *ptr, char *type) { int i,m,nchunk; int mapflag = 0; if (atom->map_style == 0) { mapflag = 1; atom->map_style = 1; atom->map_init(); atom->map_set(); } bigint nread = 0; bigint natoms = nbonus; while (nread < natoms) { if (natoms-nread > CHUNK) nchunk = CHUNK; else nchunk = natoms-nread; if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_bonus(nchunk,buffer,ptr); nread += nchunk; } if (mapflag) { atom->map_delete(); atom->map_style = 0; } if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " %s\n",natoms,type); if (logfile) fprintf(logfile," " BIGINT_FORMAT " %s\n",natoms,type); } } /* ---------------------------------------------------------------------- */ void ReadData::bonds() { int i,m,nchunk; bigint nread = 0; bigint nbonds = atom->nbonds; while (nread < nbonds) { nchunk = MIN(nbonds-nread,CHUNK); if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_bonds(nchunk,buffer); nread += nchunk; } // check that bonds were assigned correctly int nlocal = atom->nlocal; bigint sum; bigint n = 0; for (i = 0; i < nlocal; i++) n += atom->num_bond[i]; MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world); int factor = 1; if (!force->newton_bond) factor = 2; if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " bonds\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " bonds\n",sum/factor); } if (sum != factor*atom->nbonds) error->all(FLERR,"Bonds assigned incorrectly"); } /* ---------------------------------------------------------------------- */ void ReadData::angles() { int i,m,nchunk; bigint nread = 0; bigint nangles = atom->nangles; while (nread < nangles) { nchunk = MIN(nangles-nread,CHUNK); if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_angles(nchunk,buffer); nread += nchunk; } // check that ang int nlocal = atom->nlocal; bigint sum; bigint n = 0; for (i = 0; i < nlocal; i++) n += atom->num_angle[i]; MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world); int factor = 1; if (!force->newton_bond) factor = 3; if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " angles\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " angles\n",sum/factor); } if (sum != factor*atom->nangles) error->all(FLERR,"Angles assigned incorrectly"); } /* ---------------------------------------------------------------------- */ void ReadData::dihedrals() { int i,m,nchunk; bigint nread = 0; bigint ndihedrals = atom->ndihedrals; while (nread < ndihedrals) { nchunk = MIN(ndihedrals-nread,CHUNK); if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_dihedrals(nchunk,buffer); nread += nchunk; } // check that dihedrals were assigned correctly int nlocal = atom->nlocal; bigint sum; bigint n = 0; for (i = 0; i < nlocal; i++) n += atom->num_dihedral[i]; MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world); int factor = 1; if (!force->newton_bond) factor = 4; if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " dihedrals\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " dihedrals\n",sum/factor); } if (sum != factor*atom->ndihedrals) error->all(FLERR,"Dihedrals assigned incorrectly"); } /* ---------------------------------------------------------------------- */ void ReadData::impropers() { int i,m,nchunk; bigint nread = 0; bigint nimpropers = atom->nimpropers; while (nread < nimpropers) { nchunk = MIN(nimpropers-nread,CHUNK); if (me == 0) { char *eof; m = 0; for (i = 0; i < nchunk; i++) { eof = fgets(&buffer[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buffer[m]); } m++; } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buffer,m,MPI_CHAR,0,world); atom->data_impropers(nchunk,buffer); nread += nchunk; } // check that impropers were assigned correctly int nlocal = atom->nlocal; bigint sum; bigint n = 0; for (i = 0; i < nlocal; i++) n += atom->num_improper[i]; MPI_Allreduce(&n,&sum,1,MPI_LMP_BIGINT,MPI_SUM,world); int factor = 1; if (!force->newton_bond) factor = 4; if (me == 0) { if (screen) fprintf(screen," " BIGINT_FORMAT " impropers\n",sum/factor); if (logfile) fprintf(logfile," " BIGINT_FORMAT " impropers\n",sum/factor); } if (sum != factor*atom->nimpropers) error->all(FLERR,"Impropers assigned incorrectly"); } /* ---------------------------------------------------------------------- */ void ReadData::mass() { int i,m; char *buf = new char[atom->ntypes*MAXLINE]; char *original = buf; if (me == 0) { char *eof; m = 0; for (i = 0; i < atom->ntypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buf,m,MPI_CHAR,0,world); for (i = 0; i < atom->ntypes; i++) { atom->set_mass(buf); buf += strlen(buf) + 1; } delete [] original; } /* ---------------------------------------------------------------------- */ void ReadData::paircoeffs() { int i,m; char *buf = new char[atom->ntypes*MAXLINE]; char *original = buf; if (me == 0) { char *eof; m = 0; for (i = 0; i < atom->ntypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buf,m,MPI_CHAR,0,world); for (i = 0; i < atom->ntypes; i++) { m = strlen(buf) + 1; parse_coeffs(buf,NULL,1); force->pair->coeff(narg,arg); buf += m; } delete [] original; } /* ---------------------------------------------------------------------- */ void ReadData::bondcoeffs() { int i,m; char *buf = new char[atom->nbondtypes*MAXLINE]; char *original = buf; if (me == 0) { char *eof; m = 0; for (i = 0; i < atom->nbondtypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buf,m,MPI_CHAR,0,world); for (i = 0; i < atom->nbondtypes; i++) { m = strlen(buf) + 1; parse_coeffs(buf,NULL,0); force->bond->coeff(narg,arg); buf += m; } delete [] original; } /* ---------------------------------------------------------------------- */ void ReadData::anglecoeffs(int which) { int i,m; char *buf = new char[atom->nangletypes*MAXLINE]; char *original = buf; if (me == 0) { char *eof; m = 0; for (i = 0; i < atom->nangletypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buf,m,MPI_CHAR,0,world); for (i = 0; i < atom->nangletypes; i++) { m = strlen(buf) + 1; if (which == 0) parse_coeffs(buf,NULL,0); else if (which == 1) parse_coeffs(buf,"bb",0); else if (which == 2) parse_coeffs(buf,"ba",0); force->angle->coeff(narg,arg); buf += m; } delete [] original; } /* ---------------------------------------------------------------------- */ void ReadData::dihedralcoeffs(int which) { int i,m; char *buf = new char[atom->ndihedraltypes*MAXLINE]; char *original = buf; if (me == 0) { char *eof; m = 0; for (i = 0; i < atom->ndihedraltypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buf,m,MPI_CHAR,0,world); for (i = 0; i < atom->ndihedraltypes; i++) { m = strlen(buf) + 1; if (which == 0) parse_coeffs(buf,NULL,0); else if (which == 1) parse_coeffs(buf,"mbt",0); else if (which == 2) parse_coeffs(buf,"ebt",0); else if (which == 3) parse_coeffs(buf,"at",0); else if (which == 4) parse_coeffs(buf,"aat",0); else if (which == 5) parse_coeffs(buf,"bb13",0); force->dihedral->coeff(narg,arg); buf += m; } delete [] original; } /* ---------------------------------------------------------------------- */ void ReadData::impropercoeffs(int which) { int i,m; char *buf = new char[atom->nimpropertypes*MAXLINE]; char *original = buf; if (me == 0) { char *eof; m = 0; for (i = 0; i < atom->nimpropertypes; i++) { eof = fgets(&buf[m],MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); m += strlen(&buf[m]); buf[m-1] = '\0'; } } MPI_Bcast(&m,1,MPI_INT,0,world); MPI_Bcast(buf,m,MPI_CHAR,0,world); for (i = 0; i < atom->nimpropertypes; i++) { m = strlen(buf) + 1; if (which == 0) parse_coeffs(buf,NULL,0); else if (which == 1) parse_coeffs(buf,"aa",0); force->improper->coeff(narg,arg); buf += m; } delete [] original; } /* ---------------------------------------------------------------------- proc 0 scans the data file for topology maximums ------------------------------------------------------------------------- */ void ReadData::scan(int &bond_per_atom, int &angle_per_atom, int &dihedral_per_atom, int &improper_per_atom) { int i,tmp1,tmp2,atom1,atom2,atom3,atom4; char *eof; if (atom->natoms > MAXSMALLINT) error->all(FLERR,"Molecular data file has too many atoms"); // customize for new sections int natoms = static_cast<int> (atom->natoms); bond_per_atom = angle_per_atom = dihedral_per_atom = improper_per_atom = 0; int ellipsoid_flag = 0; int line_flag = 0; int tri_flag = 0; // customize for new sections // allocate topology counting vector // initially, array length = 1 to natoms // will grow via reallocate() if atom IDs > natoms int cmax = natoms + 1; int *count; memory->create(count,cmax,"read_data:count"); while (strlen(keyword)) { if (strcmp(keyword,"Masses") == 0) skip_lines(atom->ntypes); else if (strcmp(keyword,"Atoms") == 0) skip_lines(natoms); else if (strcmp(keyword,"Velocities") == 0) skip_lines(natoms); else if (strcmp(keyword,"Ellipsoids") == 0) { if (!avec_ellipsoid) error->all(FLERR,"Invalid data file section: Ellipsoids"); ellipsoid_flag = 1; skip_lines(nellipsoids); } else if (strcmp(keyword,"Lines") == 0) { if (!avec_line) error->all(FLERR,"Invalid data file section: Lines"); line_flag = 1; skip_lines(nlines); } else if (strcmp(keyword,"Triangles") == 0) { if (!avec_tri) error->all(FLERR,"Invalid data file section: Triangles"); tri_flag = 1; skip_lines(ntris); } else if (strcmp(keyword,"Pair Coeffs") == 0) { if (force->pair == NULL) error->all(FLERR,"Must define pair_style before Pair Coeffs"); skip_lines(atom->ntypes); } else if (strcmp(keyword,"Bond Coeffs") == 0) { if (atom->avec->bonds_allow == 0) error->all(FLERR,"Invalid data file section: Bond Coeffs"); if (force->bond == NULL) error->all(FLERR,"Must define bond_style before Bond Coeffs"); skip_lines(atom->nbondtypes); } else if (strcmp(keyword,"Angle Coeffs") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: Angle Coeffs"); if (force->angle == NULL) error->all(FLERR,"Must define angle_style before Angle Coeffs"); skip_lines(atom->nangletypes); } else if (strcmp(keyword,"Dihedral Coeffs") == 0) { skip_lines(atom->ndihedraltypes); if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: Dihedral Coeffs"); if (force->dihedral == NULL) error->all(FLERR,"Must define dihedral_style before Dihedral Coeffs"); } else if (strcmp(keyword,"Improper Coeffs") == 0) { if (atom->avec->impropers_allow == 0) error->all(FLERR,"Invalid data file section: Improper Coeffs"); if (force->improper == NULL) error->all(FLERR,"Must define improper_style before Improper Coeffs"); skip_lines(atom->nimpropertypes); } else if (strcmp(keyword,"BondBond Coeffs") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: BondBond Coeffs"); if (force->angle == NULL) error->all(FLERR,"Must define angle_style before BondBond Coeffs"); skip_lines(atom->nangletypes); } else if (strcmp(keyword,"BondAngle Coeffs") == 0) { if (atom->avec->angles_allow == 0) error->all(FLERR,"Invalid data file section: BondAngle Coeffs"); if (force->angle == NULL) error->all(FLERR,"Must define angle_style before BondAngle Coeffs"); skip_lines(atom->nangletypes); } else if (strcmp(keyword,"MiddleBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: MiddleBondTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before " "MiddleBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"EndBondTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: EndBondTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before EndBondTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before AngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleAngleTorsion Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: AngleAngleTorsion Coeffs"); if (force->dihedral == NULL) error->all(FLERR, "Must define dihedral_style before " "AngleAngleTorsion Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"BondBond13 Coeffs") == 0) { if (atom->avec->dihedrals_allow == 0) error->all(FLERR,"Invalid data file section: BondBond13 Coeffs"); if (force->dihedral == NULL) error->all(FLERR,"Must define dihedral_style before BondBond13 Coeffs"); skip_lines(atom->ndihedraltypes); } else if (strcmp(keyword,"AngleAngle Coeffs") == 0) { if (atom->avec->impropers_allow == 0) error->all(FLERR,"Invalid data file section: AngleAngle Coeffs"); if (force->improper == NULL) error->all(FLERR,"Must define improper_style before AngleAngle Coeffs"); skip_lines(atom->nimpropertypes); } else if (strcmp(keyword,"Bonds") == 0) { for (i = 1; i < cmax; i++) count[i] = 0; if (force->newton_bond) for (i = 0; i < atom->nbonds; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2); if (atom1 >= cmax) cmax = reallocate(&count,cmax,atom1); count[atom1]++; } else for (i = 0; i < atom->nbonds; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d",&tmp1,&tmp2,&atom1,&atom2); int amax = MAX(atom1,atom2); if (amax >= cmax) cmax = reallocate(&count,cmax,amax); count[atom1]++; count[atom2]++; } for (i = 1; i < cmax; i++) bond_per_atom = MAX(bond_per_atom,count[i]); if (screen) fprintf(screen," %d = max bonds/atom\n",bond_per_atom); if (logfile) fprintf(logfile," %d = max bonds/atom\n",bond_per_atom); } else if (strcmp(keyword,"Angles") == 0) { for (i = 1; i < cmax; i++) count[i] = 0; if (force->newton_bond) for (i = 0; i < atom->nangles; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3); if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2); count[atom2]++; } else for (i = 0; i < atom->nangles; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d",&tmp1,&tmp2,&atom1,&atom2,&atom3); int amax = MAX(atom1,atom2); amax = MAX(amax,atom3); if (amax >= cmax) cmax = reallocate(&count,cmax,amax); count[atom1]++; count[atom2]++; count[atom3]++; } for (i = 1; i < cmax; i++) angle_per_atom = MAX(angle_per_atom,count[i]); if (screen) fprintf(screen," %d = max angles/atom\n",angle_per_atom); if (logfile) fprintf(logfile," %d = max angles/atom\n",angle_per_atom); } else if (strcmp(keyword,"Dihedrals") == 0) { for (i = 1; i < cmax; i++) count[i] = 0; if (force->newton_bond) for (i = 0; i < atom->ndihedrals; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2); count[atom2]++; } else for (i = 0; i < atom->ndihedrals; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); int amax = MAX(atom1,atom2); amax = MAX(amax,atom3); amax = MAX(amax,atom4); if (amax >= cmax) cmax = reallocate(&count,cmax,amax); count[atom1]++; count[atom2]++; count[atom3]++; count[atom4]++; } for (i = 1; i < cmax; i++) dihedral_per_atom = MAX(dihedral_per_atom,count[i]); if (screen) fprintf(screen," %d = max dihedrals/atom\n",dihedral_per_atom); if (logfile) fprintf(logfile," %d = max dihedrals/atom\n",dihedral_per_atom); } else if (strcmp(keyword,"Impropers") == 0) { for (i = 1; i < cmax; i++) count[i] = 0; if (force->newton_bond) for (i = 0; i < atom->nimpropers; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); if (atom2 >= cmax) cmax = reallocate(&count,cmax,atom2); count[atom2]++; } else for (i = 0; i < atom->nimpropers; i++) { eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); sscanf(line,"%d %d %d %d %d %d", &tmp1,&tmp2,&atom1,&atom2,&atom3,&atom4); int amax = MAX(atom1,atom2); amax = MAX(amax,atom3); amax = MAX(amax,atom4); if (amax >= cmax) cmax = reallocate(&count,cmax,amax); count[atom1]++; count[atom2]++; count[atom3]++; count[atom4]++; } for (i = 1; i < cmax; i++) improper_per_atom = MAX(improper_per_atom,count[i]); if (screen) fprintf(screen," %d = max impropers/atom\n",improper_per_atom); if (logfile) fprintf(logfile," %d = max impropers/atom\n",improper_per_atom); } else { char str[128]; sprintf(str,"Unknown identifier in data file: %s",keyword); error->one(FLERR,str); } parse_keyword(0,0); } // free topology counting vector memory->destroy(count); // error check that topology was specified in file if ((atom->nbonds && !bond_per_atom) || (atom->nangles && !angle_per_atom) || (atom->ndihedrals && !dihedral_per_atom) || (atom->nimpropers && !improper_per_atom)) error->one(FLERR,"Needed topology not in data file"); // customize for new sections // error check that Bonus sections were speficied in file if (nellipsoids && !ellipsoid_flag) error->one(FLERR,"Needed bonus data not in data file"); if (nlines && !line_flag) error->one(FLERR,"Needed bonus data not in data file"); if (ntris && !tri_flag) error->one(FLERR,"Needed bonus data not in data file"); } /* ---------------------------------------------------------------------- reallocate the count vector from cmax to amax+1 and return new length zero new locations ------------------------------------------------------------------------- */ int ReadData::reallocate(int **pcount, int cmax, int amax) { int *count = *pcount; memory->grow(count,amax+1,"read_data:count"); for (int i = cmax; i <= amax; i++) count[i] = 0; *pcount = count; return amax+1; } /* ---------------------------------------------------------------------- proc 0 opens data file test if gzipped ------------------------------------------------------------------------- */ void ReadData::open(char *file) { compressed = 0; char *suffix = file + strlen(file) - 3; if (suffix > file && strcmp(suffix,".gz") == 0) compressed = 1; if (!compressed) fp = fopen(file,"r"); else { #ifdef LAMMPS_GZIP char gunzip[128]; sprintf(gunzip,"gunzip -c %s",file); fp = popen(gunzip,"r"); #else error->one(FLERR,"Cannot open gzipped file"); #endif } if (fp == NULL) { char str[128]; sprintf(str,"Cannot open file %s",file); error->one(FLERR,str); } } /* ---------------------------------------------------------------------- grab next keyword read lines until one is non-blank keyword is all text on line w/out leading & trailing white space read one additional line (assumed blank) if any read hits EOF, set keyword to empty if first = 1, line variable holds non-blank line that ended header if flag = 0, only proc 0 is calling so no bcast else flag = 1, bcast keyword line to all procs ------------------------------------------------------------------------- */ void ReadData::parse_keyword(int first, int flag) { int eof = 0; // proc 0 reads upto non-blank line plus 1 following line // eof is set to 1 if any read hits end-of-file if (me == 0) { if (!first) { if (fgets(line,MAXLINE,fp) == NULL) eof = 1; } while (eof == 0 && strspn(line," \t\n\r") == strlen(line)) { if (fgets(line,MAXLINE,fp) == NULL) eof = 1; } if (fgets(buffer,MAXLINE,fp) == NULL) eof = 1; } // if eof, set keyword empty and return if (flag) MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) { keyword[0] = '\0'; return; } // bcast keyword line to all procs if (flag) { int n; if (me == 0) n = strlen(line) + 1; MPI_Bcast(&n,1,MPI_INT,0,world); MPI_Bcast(line,n,MPI_CHAR,0,world); } // copy non-whitespace portion of line into keyword int start = strspn(line," \t\n\r"); int stop = strlen(line) - 1; while (line[stop] == ' ' || line[stop] == '\t' || line[stop] == '\n' || line[stop] == '\r') stop--; line[stop+1] = '\0'; strcpy(keyword,&line[start]); } /* ---------------------------------------------------------------------- proc 0 reads N lines from file ------------------------------------------------------------------------- */ void ReadData::skip_lines(int n) { char *eof; for (int i = 0; i < n; i++) eof = fgets(line,MAXLINE,fp); if (eof == NULL) error->one(FLERR,"Unexpected end of data file"); } /* ---------------------------------------------------------------------- parse a line of coeffs into words, storing them in narg,arg trim anything from '#' onward word strings remain in line, are not copied if addstr != NULL, add addstr as extra arg for class2 angle/dihedral/improper if 2nd word starts with letter, then is hybrid style, add addstr after it else add addstr before 2nd word if dupflag, duplicate 1st word, so pair_coeff "2" becomes "2 2" ------------------------------------------------------------------------- */ void ReadData::parse_coeffs(char *line, char *addstr, int dupflag) { char *ptr; if (ptr = strchr(line,'#')) *ptr = '\0'; narg = 0; char *word = strtok(line," \t\n\r\f"); while (word) { if (narg == maxarg) { maxarg += DELTA; arg = (char **) memory->srealloc(arg,maxarg*sizeof(char *),"read_data:arg"); } if (addstr && narg == 1 && !islower(word[0])) arg[narg++] = addstr; arg[narg++] = word; if (addstr && narg == 2 && islower(word[0])) arg[narg++] = addstr; if (dupflag && narg == 1) arg[narg++] = word; word = strtok(NULL," \t\n\r\f"); } }