Merge pull request #3072 from akohlmey/refactor-data-file-parsing

Modernize parsing of topology data sections of data files
This commit is contained in:
Axel Kohlmeyer
2022-01-04 13:21:14 -05:00
committed by GitHub
40 changed files with 508 additions and 338 deletions

View File

@ -56,11 +56,11 @@ String to number conversions with validity check
These functions should be used to convert strings to numbers. They are These functions should be used to convert strings to numbers. They are
are strongly preferred over C library calls like ``atoi()`` or are strongly preferred over C library calls like ``atoi()`` or
``atof()`` since they check if the **entire** provided string is a valid ``atof()`` since they check if the **entire** string is a valid
(floating-point or integer) number, and will error out instead of (floating-point or integer) number, and will error out instead of
silently returning the result of a partial conversion or zero in cases silently returning the result of a partial conversion or zero in cases
where the string is not a valid number. This behavior allows to more where the string is not a valid number. This behavior improves
easily detect typos or issues when processing input files. detecting typos or issues when processing input files.
Similarly the :cpp:func:`logical() <LAMMPS_NS::utils::logical>` function Similarly the :cpp:func:`logical() <LAMMPS_NS::utils::logical>` function
will convert a string into a boolean and will only accept certain words. will convert a string into a boolean and will only accept certain words.
@ -76,19 +76,34 @@ strings for compliance without conversion.
---------- ----------
.. doxygenfunction:: numeric .. doxygenfunction:: numeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
:project: progguide :project: progguide
.. doxygenfunction:: inumeric .. doxygenfunction:: numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
:project: progguide :project: progguide
.. doxygenfunction:: bnumeric .. doxygenfunction:: inumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
:project: progguide :project: progguide
.. doxygenfunction:: tnumeric .. doxygenfunction:: inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
:project: progguide :project: progguide
.. doxygenfunction:: logical .. doxygenfunction:: bnumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
:project: progguide
.. doxygenfunction:: bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
:project: progguide
.. doxygenfunction:: tnumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
:project: progguide
.. doxygenfunction:: tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
:project: progguide
.. doxygenfunction:: logical(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
:project: progguide
.. doxygenfunction:: logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
:project: progguide :project: progguide

View File

@ -55,7 +55,7 @@ of each timestep. First of all, implement a constructor:
if (narg < 4) if (narg < 4)
error->all(FLERR,"Illegal fix print/vel command"); error->all(FLERR,"Illegal fix print/vel command");
nevery = force->inumeric(FLERR,arg[3]); nevery = utils::inumeric(FLERR,arg[3],false,lmp);
if (nevery <= 0) if (nevery <= 0)
error->all(FLERR,"Illegal fix print/vel command"); error->all(FLERR,"Illegal fix print/vel command");
} }

View File

@ -1630,7 +1630,7 @@ void AtomVecAngleKokkos::create_atom(int itype, double *coord)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecAngleKokkos::data_atom(double *coord, imageint imagetmp, void AtomVecAngleKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -1663,9 +1663,10 @@ void AtomVecAngleKokkos::data_atom(double *coord, imageint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecAngleKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecAngleKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_molecule(nlocal) = utils::inumeric(FLERR,values[0],true,lmp); h_molecule(nlocal) = utils::inumeric(FLERR,values[offset],true,lmp);
h_num_bond(nlocal) = 0; h_num_bond(nlocal) = 0;
h_num_angle(nlocal) = 0; h_num_angle(nlocal) = 0;
return 1; return 1;

View File

@ -51,8 +51,8 @@ class AtomVecAngleKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -821,8 +821,8 @@ void AtomVecAtomicKokkos::create_atom(int itype, double *coord)
initialize other atom quantities initialize other atom quantities
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecAtomicKokkos::data_atom(double *coord, tagint imagetmp, void AtomVecAtomicKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);

View File

@ -44,7 +44,7 @@ class AtomVecAtomicKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
void pack_data(double **); void pack_data(double **);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);
double memory_usage(); double memory_usage();

View File

@ -1056,7 +1056,7 @@ void AtomVecBondKokkos::create_atom(int itype, double *coord)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecBondKokkos::data_atom(double *coord, imageint imagetmp, void AtomVecBondKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atomKK->nlocal; int nlocal = atomKK->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -1088,9 +1088,10 @@ void AtomVecBondKokkos::data_atom(double *coord, imageint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecBondKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecBondKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_molecule(nlocal) = utils::inumeric(FLERR,values[0],true,lmp); h_molecule(nlocal) = utils::inumeric(FLERR,values[offset],true,lmp);
h_num_bond(nlocal) = 0; h_num_bond(nlocal) = 0;
return 1; return 1;
} }

View File

@ -45,8 +45,8 @@ class AtomVecBondKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -955,7 +955,7 @@ void AtomVecChargeKokkos::create_atom(int itype, double *coord)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecChargeKokkos::data_atom(double *coord, imageint imagetmp, void AtomVecChargeKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -987,9 +987,10 @@ void AtomVecChargeKokkos::data_atom(double *coord, imageint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecChargeKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecChargeKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_q[nlocal] = utils::numeric(FLERR,values[0],true,lmp); h_q[nlocal] = utils::numeric(FLERR,values[offset],true,lmp);
return 1; return 1;
} }

View File

@ -46,8 +46,8 @@ class AtomVecChargeKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int , char **); int data_atom_hybrid(int , const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -1716,8 +1716,8 @@ void AtomVecDPDKokkos::create_atom(int itype, double *coord)
initialize other atom quantities initialize other atom quantities
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecDPDKokkos::data_atom(double *coord, tagint imagetmp, void AtomVecDPDKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -1759,9 +1759,10 @@ void AtomVecDPDKokkos::data_atom(double *coord, tagint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecDPDKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_dpdTheta(nlocal) = utils::numeric(FLERR,values[0],true,lmp); h_dpdTheta(nlocal) = utils::numeric(FLERR,values[offset],true,lmp);
atomKK->modified(Host,DPDTHETA_MASK); atomKK->modified(Host,DPDTHETA_MASK);

View File

@ -54,8 +54,8 @@ class AtomVecDPDKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -1488,7 +1488,7 @@ void AtomVecFullKokkos::create_atom(int itype, double *coord)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecFullKokkos::data_atom(double *coord, imageint imagetmp, void AtomVecFullKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -1525,10 +1525,11 @@ void AtomVecFullKokkos::data_atom(double *coord, imageint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecFullKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecFullKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_molecule(nlocal) = utils::inumeric(FLERR,values[0],true,lmp); h_molecule(nlocal) = utils::inumeric(FLERR,values[offset],true,lmp);
h_q(nlocal) = utils::numeric(FLERR,values[1],true,lmp); h_q(nlocal) = utils::numeric(FLERR,values[offset+1],true,lmp);
h_num_bond(nlocal) = 0; h_num_bond(nlocal) = 0;
h_num_angle(nlocal) = 0; h_num_angle(nlocal) = 0;
h_num_dihedral(nlocal) = 0; h_num_dihedral(nlocal) = 0;

View File

@ -45,8 +45,8 @@ class AtomVecFullKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -970,7 +970,8 @@ void AtomVecHybridKokkos::create_atom(int itype, double *coord)
grow() occurs here so arrays for all sub-styles are grown grow() occurs here so arrays for all sub-styles are grown
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **values) void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp,
const std::vector<std::string> &values)
{ {
atomKK->sync(Host,X_MASK|TAG_MASK|TYPE_MASK|IMAGE_MASK|MASK_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/); atomKK->sync(Host,X_MASK|TAG_MASK|TYPE_MASK|IMAGE_MASK|MASK_MASK|V_MASK|OMEGA_MASK/*|ANGMOM_MASK*/);
@ -1009,7 +1010,7 @@ void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **val
int m = 5; int m = 5;
for (int k = 0; k < nstyles; k++) for (int k = 0; k < nstyles; k++)
m += styles[k]->data_atom_hybrid(nlocal,&values[m]); m += styles[k]->data_atom_hybrid(nlocal,values,m);
atom->nlocal++; atom->nlocal++;
} }
@ -1018,21 +1019,21 @@ void AtomVecHybridKokkos::data_atom(double *coord, imageint imagetmp, char **val
unpack one line from Velocities section of data file unpack one line from Velocities section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecHybridKokkos::data_vel(int m, char **values) void AtomVecHybridKokkos::data_vel(int m, const std::vector<std::string> &values)
{ {
atomKK->sync(Host,V_MASK); atomKK->sync(Host,V_MASK);
h_v(m,0) = utils::numeric(FLERR,values[0],true,lmp); int ivalue = 1;
h_v(m,1) = utils::numeric(FLERR,values[1],true,lmp); h_v(m,0) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_v(m,2) = utils::numeric(FLERR,values[2],true,lmp); h_v(m,1) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_v(m,2) = utils::numeric(FLERR,values[ivalue++],true,lmp);
atomKK->modified(Host,V_MASK); atomKK->modified(Host,V_MASK);
// each sub-style parses sub-style specific values // each sub-style parses sub-style specific values
int n = 3;
for (int k = 0; k < nstyles; k++) for (int k = 0; k < nstyles; k++)
n += styles[k]->data_vel_hybrid(m,&values[n]); ivalue += styles[k]->data_vel_hybrid(m,values,ivalue);
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -57,9 +57,9 @@ class AtomVecHybridKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, imageint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **) {return 0;} int data_atom_hybrid(int, const std::vector<std::string> &, int) {return 0;}
void data_vel(int, char **); void data_vel(int, const std::vector<std::string> &);
void pack_data(double **); void pack_data(double **);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);
void pack_vel(double **); void pack_vel(double **);

View File

@ -1016,12 +1016,13 @@ void AtomVecKokkos::unpack_reverse(int n, int *list, double *buf)
* unpack one line from Velocities section of data file * unpack one line from Velocities section of data file
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
void AtomVecKokkos::data_vel(int m, char **values) void AtomVecKokkos::data_vel(int m, const std::vector<std::string> &values)
{ {
double **v = atom->v; double **v = atom->v;
v[m][0] = utils::numeric(FLERR,values[0],true,lmp); int ivalue = 1;
v[m][1] = utils::numeric(FLERR,values[1],true,lmp); v[m][0] = utils::numeric(FLERR,values[ivalue++],true,lmp);
v[m][2] = utils::numeric(FLERR,values[2],true,lmp); v[m][1] = utils::numeric(FLERR,values[ivalue++],true,lmp);
v[m][2] = utils::numeric(FLERR,values[ivalue++],true,lmp);
atomKK->modified(Host,V_MASK); atomKK->modified(Host,V_MASK);
} }

View File

@ -44,7 +44,7 @@ class AtomVecKokkos : public AtomVec {
virtual void unpack_comm_vel(int, int, double *); virtual void unpack_comm_vel(int, int, double *);
virtual int pack_reverse(int, int, double *); virtual int pack_reverse(int, int, double *);
virtual void unpack_reverse(int, int *, double *); virtual void unpack_reverse(int, int *, double *);
virtual void data_vel(int, char **); virtual void data_vel(int, const std::vector<std::string> &);
virtual void pack_vel(double **); virtual void pack_vel(double **);
virtual void write_vel(FILE *, int, double **); virtual void write_vel(FILE *, int, double **);

View File

@ -1889,7 +1889,7 @@ void AtomVecMolecularKokkos::create_atom(int itype, double *coord)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecMolecularKokkos::data_atom(double *coord, imageint imagetmp, void AtomVecMolecularKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -1924,9 +1924,10 @@ void AtomVecMolecularKokkos::data_atom(double *coord, imageint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecMolecularKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecMolecularKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_molecule(nlocal) = utils::inumeric(FLERR,values[0],true,lmp); h_molecule(nlocal) = utils::inumeric(FLERR,values[offset],true,lmp);
h_num_bond(nlocal) = 0; h_num_bond(nlocal) = 0;
h_num_angle(nlocal) = 0; h_num_angle(nlocal) = 0;
h_num_dihedral(nlocal) = 0; h_num_dihedral(nlocal) = 0;

View File

@ -51,8 +51,8 @@ class AtomVecMolecularKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, tagint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -2543,7 +2543,8 @@ void AtomVecSphereKokkos::create_atom(int itype, double *coord)
initialize other atom quantities initialize other atom quantities
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecSphereKokkos::data_atom(double *coord, imageint imagetmp, char **values) void AtomVecSphereKokkos::data_atom(double *coord, imageint imagetmp,
const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -2590,13 +2591,14 @@ void AtomVecSphereKokkos::data_atom(double *coord, imageint imagetmp, char **val
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecSphereKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecSphereKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
radius[nlocal] = 0.5 * utils::numeric(FLERR,values[0],true,lmp); radius[nlocal] = 0.5 * utils::numeric(FLERR,values[offset],true,lmp);
if (radius[nlocal] < 0.0) if (radius[nlocal] < 0.0)
error->one(FLERR,"Invalid radius in Atoms section of data file"); error->one(FLERR,"Invalid radius in Atoms section of data file");
double density = utils::numeric(FLERR,values[1],true,lmp); double density = utils::numeric(FLERR,values[offset+1],true,lmp);
if (density <= 0.0) if (density <= 0.0)
error->one(FLERR,"Invalid density in Atoms section of data file"); error->one(FLERR,"Invalid density in Atoms section of data file");
@ -2615,15 +2617,16 @@ int AtomVecSphereKokkos::data_atom_hybrid(int nlocal, char **values)
unpack one line from Velocities section of data file unpack one line from Velocities section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecSphereKokkos::data_vel(int m, char **values) void AtomVecSphereKokkos::data_vel(int m, const std::vector<std::string> &values)
{ {
int ivalue = 1;
atomKK->sync(Host,V_MASK|OMEGA_MASK); atomKK->sync(Host,V_MASK|OMEGA_MASK);
h_v(m,0) = utils::numeric(FLERR,values[0],true,lmp); h_v(m,0) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_v(m,1) = utils::numeric(FLERR,values[1],true,lmp); h_v(m,1) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_v(m,2) = utils::numeric(FLERR,values[2],true,lmp); h_v(m,2) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_omega(m,0) = utils::numeric(FLERR,values[3],true,lmp); h_omega(m,0) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_omega(m,1) = utils::numeric(FLERR,values[4],true,lmp); h_omega(m,1) = utils::numeric(FLERR,values[ivalue++],true,lmp);
h_omega(m,2) = utils::numeric(FLERR,values[5],true,lmp); h_omega(m,2) = utils::numeric(FLERR,values[ivalue++],true,lmp);
atomKK->modified(Host,V_MASK|OMEGA_MASK); atomKK->modified(Host,V_MASK|OMEGA_MASK);
} }
@ -2631,12 +2634,13 @@ void AtomVecSphereKokkos::data_vel(int m, char **values)
unpack hybrid quantities from one line in Velocities section of data file unpack hybrid quantities from one line in Velocities section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecSphereKokkos::data_vel_hybrid(int m, char **values) int AtomVecSphereKokkos::data_vel_hybrid(int m, const std::vector<std::string> &values,
int offset)
{ {
atomKK->sync(Host,OMEGA_MASK); atomKK->sync(Host,OMEGA_MASK);
omega[m][0] = utils::numeric(FLERR,values[0],true,lmp); omega[m][0] = utils::numeric(FLERR,values[offset],true,lmp);
omega[m][1] = utils::numeric(FLERR,values[1],true,lmp); omega[m][1] = utils::numeric(FLERR,values[offset+1],true,lmp);
omega[m][2] = utils::numeric(FLERR,values[2],true,lmp); omega[m][2] = utils::numeric(FLERR,values[offset+2],true,lmp);
atomKK->modified(Host,OMEGA_MASK); atomKK->modified(Host,OMEGA_MASK);
return 3; return 3;
} }

View File

@ -58,10 +58,10 @@ class AtomVecSphereKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, imageint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void data_vel(int, char **); void data_vel(int, const std::vector<std::string> &);
int data_vel_hybrid(int, char **); int data_vel_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -1056,7 +1056,7 @@ void AtomVecSpinKokkos::create_atom(int itype, double *coord)
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecSpinKokkos::data_atom(double *coord, imageint imagetmp, void AtomVecSpinKokkos::data_atom(double *coord, imageint imagetmp,
char **values) const std::vector<std::string> &values)
{ {
int nlocal = atom->nlocal; int nlocal = atom->nlocal;
if (nlocal == nmax) grow(0); if (nlocal == nmax) grow(0);
@ -1098,12 +1098,13 @@ void AtomVecSpinKokkos::data_atom(double *coord, imageint imagetmp,
initialize other atom quantities for this sub-style initialize other atom quantities for this sub-style
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int AtomVecSpinKokkos::data_atom_hybrid(int nlocal, char **values) int AtomVecSpinKokkos::data_atom_hybrid(int nlocal, const std::vector<std::string> &values,
int offset)
{ {
h_sp(nlocal,3) = utils::numeric(FLERR,values[0],true,lmp); h_sp(nlocal,3) = utils::numeric(FLERR,values[offset],true,lmp);
h_sp(nlocal,0) = utils::numeric(FLERR,values[1],true,lmp); h_sp(nlocal,0) = utils::numeric(FLERR,values[offset+1],true,lmp);
h_sp(nlocal,1) = utils::numeric(FLERR,values[2],true,lmp); h_sp(nlocal,1) = utils::numeric(FLERR,values[offset+2],true,lmp);
h_sp(nlocal,2) = utils::numeric(FLERR,values[3],true,lmp); h_sp(nlocal,2) = utils::numeric(FLERR,values[offset+3],true,lmp);
double inorm = 1.0/sqrt(sp[nlocal][0]*sp[nlocal][0] + double inorm = 1.0/sqrt(sp[nlocal][0]*sp[nlocal][0] +
sp[nlocal][1]*sp[nlocal][1] + sp[nlocal][1]*sp[nlocal][1] +
sp[nlocal][2]*sp[nlocal][2]); sp[nlocal][2]*sp[nlocal][2]);

View File

@ -45,8 +45,8 @@ class AtomVecSpinKokkos : public AtomVecKokkos {
int pack_restart(int, double *); int pack_restart(int, double *);
int unpack_restart(double *); int unpack_restart(double *);
void create_atom(int, double *); void create_atom(int, double *);
void data_atom(double *, imageint, char **); void data_atom(double *, imageint, const std::vector<std::string> &);
int data_atom_hybrid(int, char **); int data_atom_hybrid(int, const std::vector<std::string> &, int);
void pack_data(double **); void pack_data(double **);
int pack_data_hybrid(int, double *); int pack_data_hybrid(int, double *);
void write_data(FILE *, int, double **); void write_data(FILE *, int, double **);

View File

@ -125,28 +125,27 @@ void MLIAPDescriptorSO3::read_paramfile(char *paramfilename)
// check for keywords with one value per element // check for keywords with one value per element
if (strcmp(skeywd.c_str(), "elems") == 0 || strcmp(skeywd.c_str(), "radelems") == 0 || if ((skeywd == "elems") || (skeywd == "radelems") || (skeywd == "welems")) {
strcmp(skeywd.c_str(), "welems") == 0) {
if (nelementsflag == 0 || nwords != nelements + 1) if (nelementsflag == 0 || nwords != nelements + 1)
error->all(FLERR, "Incorrect SO3 parameter file"); error->all(FLERR, "Incorrect SO3 parameter file");
if (strcmp(skeywd.c_str(), "elems") == 0) { if (skeywd == "elems") {
for (int ielem = 0; ielem < nelements; ielem++) { for (int ielem = 0; ielem < nelements; ielem++) {
elements[ielem] = utils::strdup(skeyval); elements[ielem] = utils::strdup(skeyval);
if (ielem < nelements - 1) skeyval = p.next(); if (ielem < nelements - 1) skeyval = p.next();
} }
elementsflag = 1; elementsflag = 1;
} else if (strcmp(skeywd.c_str(), "radelems") == 0) { } else if (skeywd == "radelems") {
for (int ielem = 0; ielem < nelements; ielem++) { for (int ielem = 0; ielem < nelements; ielem++) {
radelem[ielem] = utils::numeric(FLERR, skeyval.c_str(), false, lmp); radelem[ielem] = utils::numeric(FLERR, skeyval, false, lmp);
if (ielem < nelements - 1) skeyval = p.next(); if (ielem < nelements - 1) skeyval = p.next();
} }
radelemflag = 1; radelemflag = 1;
} else if (strcmp(skeywd.c_str(), "welems") == 0) { } else if (skeywd == "welems") {
for (int ielem = 0; ielem < nelements; ielem++) { for (int ielem = 0; ielem < nelements; ielem++) {
wjelem[ielem] = utils::numeric(FLERR, skeyval.c_str(), false, lmp); wjelem[ielem] = utils::numeric(FLERR, skeyval, false, lmp);
if (ielem < nelements - 1) skeyval = p.next(); if (ielem < nelements - 1) skeyval = p.next();
} }
wjelemflag = 1; wjelemflag = 1;
@ -158,23 +157,23 @@ void MLIAPDescriptorSO3::read_paramfile(char *paramfilename)
if (nwords != 2) error->all(FLERR, "Incorrect SO3 parameter file"); if (nwords != 2) error->all(FLERR, "Incorrect SO3 parameter file");
if (strcmp(skeywd.c_str(), "nelems") == 0) { if (skeywd == "nelems") {
nelements = utils::inumeric(FLERR, skeyval.c_str(), false, lmp); nelements = utils::inumeric(FLERR, skeyval, false, lmp);
elements = new char *[nelements]; elements = new char *[nelements];
memory->create(radelem, nelements, "mliap_so3_descriptor:radelem"); memory->create(radelem, nelements, "mliap_so3_descriptor:radelem");
memory->create(wjelem, nelements, "mliap_so3_descriptor:wjelem"); memory->create(wjelem, nelements, "mliap_so3_descriptor:wjelem");
nelementsflag = 1; nelementsflag = 1;
} else if (strcmp(skeywd.c_str(), "rcutfac") == 0) { } else if (skeywd == "rcutfac") {
rcutfac = utils::numeric(FLERR, skeyval.c_str(), false, lmp); rcutfac = utils::numeric(FLERR, skeyval, false, lmp);
rcutfacflag = 1; rcutfacflag = 1;
} else if (strcmp(skeywd.c_str(), "nmax") == 0) { } else if (skeywd == "nmax") {
nmax = utils::inumeric(FLERR, skeyval.c_str(), false, lmp); nmax = utils::inumeric(FLERR, skeyval, false, lmp);
nmaxflag = 1; nmaxflag = 1;
} else if (strcmp(skeywd.c_str(), "lmax") == 0) { } else if (skeywd == "lmax") {
lmax = utils::inumeric(FLERR, skeyval.c_str(), false, lmp); lmax = utils::inumeric(FLERR, skeyval, false, lmp);
lmaxflag = 1; lmaxflag = 1;
} else if (strcmp(skeywd.c_str(), "alpha") == 0) { } else if (skeywd == "alpha") {
alpha = utils::numeric(FLERR, skeyval.c_str(), false, lmp); alpha = utils::numeric(FLERR, skeyval, false, lmp);
alphaflag = 1; alphaflag = 1;
} else } else
error->all(FLERR, "Incorrect SO3 parameter file"); error->all(FLERR, "Incorrect SO3 parameter file");

View File

@ -440,7 +440,7 @@ void PairRANN::read_mass(const std::vector<std::string> &line1, const std::vecto
if (nelements == -1)error->one(filename,linenum-1,"atom types must be defined before mass in potential file."); if (nelements == -1)error->one(filename,linenum-1,"atom types must be defined before mass in potential file.");
for (int i=0;i<nelements;i++) { for (int i=0;i<nelements;i++) {
if (line1[1].compare(elements[i])==0) { if (line1[1].compare(elements[i])==0) {
mass[i]=utils::numeric(filename,linenum,line2[0].c_str(),true,lmp); mass[i]=utils::numeric(filename,linenum,line2[0],true,lmp);
return; return;
} }
} }
@ -452,7 +452,7 @@ void PairRANN::read_fpe(std::vector<std::string> line,std::vector<std::string> l
if (nelements == -1)error->one(filename,linenum-1,"atom types must be defined before fingerprints per element in potential file."); if (nelements == -1)error->one(filename,linenum-1,"atom types must be defined before fingerprints per element in potential file.");
for (i=0;i<nelementsp;i++) { for (i=0;i<nelementsp;i++) {
if (line[1].compare(elementsp[i])==0) { if (line[1].compare(elementsp[i])==0) {
fingerprintperelement[i] = utils::inumeric(filename,linenum,line1[0].c_str(),true,lmp); fingerprintperelement[i] = utils::inumeric(filename,linenum,line1[0],true,lmp);
fingerprints[i] = new RANN::Fingerprint *[fingerprintperelement[i]]; fingerprints[i] = new RANN::Fingerprint *[fingerprintperelement[i]];
for (int j=0;j<fingerprintperelement[i];j++) { for (int j=0;j<fingerprintperelement[i];j++) {
fingerprints[i][j]=new RANN::Fingerprint(this); fingerprints[i][j]=new RANN::Fingerprint(this);
@ -491,7 +491,7 @@ void PairRANN::read_fingerprints(std::vector<std::string> line,std::vector<std::
fingerprints[i][i1] = create_fingerprint(line1[k].c_str()); fingerprints[i][i1] = create_fingerprint(line1[k].c_str());
if (fingerprints[i][i1]->n_body_type!=nwords-1) {error->one(filename,linenum,"invalid fingerprint for element combination");} if (fingerprints[i][i1]->n_body_type!=nwords-1) {error->one(filename,linenum,"invalid fingerprint for element combination");}
k++; k++;
fingerprints[i][i1]->init(atomtypes,utils::inumeric(filename,linenum,line1[k++].c_str(),true,lmp)); fingerprints[i][i1]->init(atomtypes,utils::inumeric(filename,linenum,line1[k++],true,lmp));
fingerprintcount[i]++; fingerprintcount[i]++;
} }
delete[] atomtypes; delete[] atomtypes;
@ -523,7 +523,7 @@ void PairRANN::read_fingerprint_constants(std::vector<std::string> line,std::vec
for (j=0;j<n_body_type;j++) { for (j=0;j<n_body_type;j++) {
if (fingerprints[i][k]->atomtypes[j]!=atomtypes[j]) {break;} if (fingerprints[i][k]->atomtypes[j]!=atomtypes[j]) {break;}
if (j==n_body_type-1) { if (j==n_body_type-1) {
if (line[nwords-3].compare(fingerprints[i][k]->style)==0 && utils::inumeric(filename,linenum,line[nwords-2].c_str(),true,lmp)==fingerprints[i][k]->id) { if (line[nwords-3].compare(fingerprints[i][k]->style)==0 && utils::inumeric(filename,linenum,line[nwords-2],true,lmp)==fingerprints[i][k]->id) {
found=true; found=true;
i1 = k; i1 = k;
break; break;
@ -542,7 +542,7 @@ void PairRANN::read_network_layers(std::vector<std::string> line,std::vector<std
if (nelements == -1)error->one(filename,linenum-1,"atom types must be defined before network layers in potential file."); if (nelements == -1)error->one(filename,linenum-1,"atom types must be defined before network layers in potential file.");
for (i=0;i<nelements;i++) { for (i=0;i<nelements;i++) {
if (line[1].compare(elements[i])==0) { if (line[1].compare(elements[i])==0) {
net[i].layers = utils::inumeric(filename,linenum,line1[0].c_str(),true,lmp); net[i].layers = utils::inumeric(filename,linenum,line1[0],true,lmp);
if (net[i].layers < 1)error->one(filename,linenum,"invalid number of network layers"); if (net[i].layers < 1)error->one(filename,linenum,"invalid number of network layers");
delete[] net[i].dimensions; delete[] net[i].dimensions;
weightdefined[i] = new bool [net[i].layers]; weightdefined[i] = new bool [net[i].layers];
@ -570,9 +570,9 @@ void PairRANN::read_layer_size(std::vector<std::string> line,std::vector<std::st
for (i=0;i<nelements;i++) { for (i=0;i<nelements;i++) {
if (line[1].compare(elements[i])==0) { if (line[1].compare(elements[i])==0) {
if (net[i].layers==0)error->one(filename,linenum-1,"networklayers for each atom type must be defined before the corresponding layer sizes."); if (net[i].layers==0)error->one(filename,linenum-1,"networklayers for each atom type must be defined before the corresponding layer sizes.");
int j = utils::inumeric(filename,linenum,line[2].c_str(),true,lmp); int j = utils::inumeric(filename,linenum,line[2],true,lmp);
if (j>=net[i].layers || j<0) {error->one(filename,linenum,"invalid layer in layer size definition");}; if (j>=net[i].layers || j<0) {error->one(filename,linenum,"invalid layer in layer size definition");};
net[i].dimensions[j]= utils::inumeric(filename,linenum,line1[0].c_str(),true,lmp); net[i].dimensions[j]= utils::inumeric(filename,linenum,line1[0],true,lmp);
return; return;
} }
} }
@ -587,7 +587,7 @@ void PairRANN::read_weight(std::vector<std::string> line,std::vector<std::string
for (l=0;l<nelements;l++) { for (l=0;l<nelements;l++) {
if (line[1].compare(elements[l])==0) { if (line[1].compare(elements[l])==0) {
if (net[l].layers==0)error->one(filename,*linenum-1,"networklayers must be defined before weights."); if (net[l].layers==0)error->one(filename,*linenum-1,"networklayers must be defined before weights.");
i=utils::inumeric(filename,*linenum,line[2].c_str(),true,lmp); i=utils::inumeric(filename,*linenum,line[2],true,lmp);
if (i>=net[l].layers || i<0)error->one(filename,*linenum-1,"invalid weight layer"); if (i>=net[l].layers || i<0)error->one(filename,*linenum-1,"invalid weight layer");
if (net[l].dimensions[i]==0 || net[l].dimensions[i+1]==0) error->one(filename,*linenum-1,"network layer sizes must be defined before corresponding weight"); if (net[l].dimensions[i]==0 || net[l].dimensions[i+1]==0) error->one(filename,*linenum-1,"network layer sizes must be defined before corresponding weight");
net[l].Weights[i] = new double[net[l].dimensions[i]*net[l].dimensions[i+1]]; net[l].Weights[i] = new double[net[l].dimensions[i]*net[l].dimensions[i+1]];
@ -595,7 +595,7 @@ void PairRANN::read_weight(std::vector<std::string> line,std::vector<std::string
nwords = line1.size(); nwords = line1.size();
if (nwords != net[l].dimensions[i])error->one(filename,*linenum,"invalid weights per line"); if (nwords != net[l].dimensions[i])error->one(filename,*linenum,"invalid weights per line");
for (k=0;k<net[l].dimensions[i];k++) { for (k=0;k<net[l].dimensions[i];k++) {
net[l].Weights[i][k] = utils::numeric(filename,*linenum,line1[k].c_str(),true,lmp); net[l].Weights[i][k] = utils::numeric(filename,*linenum,line1[k],true,lmp);
} }
for (j=1;j<net[l].dimensions[i+1];j++) { for (j=1;j<net[l].dimensions[i+1];j++) {
ptr = fgets(linetemp,longline,fp); ptr = fgets(linetemp,longline,fp);
@ -606,7 +606,7 @@ void PairRANN::read_weight(std::vector<std::string> line,std::vector<std::string
nwords = line1.size(); nwords = line1.size();
if (nwords != net[l].dimensions[i])error->one(filename,*linenum,"invalid weights per line"); if (nwords != net[l].dimensions[i])error->one(filename,*linenum,"invalid weights per line");
for (k=0;k<net[l].dimensions[i];k++) { for (k=0;k<net[l].dimensions[i];k++) {
net[l].Weights[i][j*net[l].dimensions[i]+k] = utils::numeric(filename,*linenum,line1[k].c_str(),true,lmp); net[l].Weights[i][j*net[l].dimensions[i]+k] = utils::numeric(filename,*linenum,line1[k],true,lmp);
} }
} }
return; return;
@ -621,19 +621,19 @@ void PairRANN::read_bias(std::vector<std::string> line,std::vector<std::string>
for (l=0;l<nelements;l++) { for (l=0;l<nelements;l++) {
if (line[1].compare(elements[l])==0) { if (line[1].compare(elements[l])==0) {
if (net[l].layers==0)error->one(filename,*linenum-1,"networklayers must be defined before biases."); if (net[l].layers==0)error->one(filename,*linenum-1,"networklayers must be defined before biases.");
i=utils::inumeric(filename,*linenum,line[2].c_str(),true,lmp); i=utils::inumeric(filename,*linenum,line[2],true,lmp);
if (i>=net[l].layers || i<0)error->one(filename,*linenum-1,"invalid bias layer"); if (i>=net[l].layers || i<0)error->one(filename,*linenum-1,"invalid bias layer");
if (net[l].dimensions[i]==0) error->one(filename,*linenum-1,"network layer sizes must be defined before corresponding bias"); if (net[l].dimensions[i]==0) error->one(filename,*linenum-1,"network layer sizes must be defined before corresponding bias");
biasdefined[l][i] = true; biasdefined[l][i] = true;
net[l].Biases[i] = new double[net[l].dimensions[i+1]]; net[l].Biases[i] = new double[net[l].dimensions[i+1]];
net[l].Biases[i][0] = utils::numeric(filename,*linenum,line1[0].c_str(),true,lmp); net[l].Biases[i][0] = utils::numeric(filename,*linenum,line1[0],true,lmp);
for (j=1;j<net[l].dimensions[i+1];j++) { for (j=1;j<net[l].dimensions[i+1];j++) {
ptr=fgets(linetemp,MAXLINE,fp); ptr=fgets(linetemp,MAXLINE,fp);
if (ptr==nullptr)error->one(filename,*linenum,"unexpected end of potential file!"); if (ptr==nullptr)error->one(filename,*linenum,"unexpected end of potential file!");
(*linenum)++; (*linenum)++;
Tokenizer values1 = Tokenizer(linetemp,": ,\t_\n"); Tokenizer values1 = Tokenizer(linetemp,": ,\t_\n");
line1 = values1.as_vector(); line1 = values1.as_vector();
net[l].Biases[i][j] = utils::numeric(filename,*linenum,line1[0].c_str(),true,lmp); net[l].Biases[i][j] = utils::numeric(filename,*linenum,line1[0],true,lmp);
} }
return; return;
} }
@ -680,10 +680,10 @@ void PairRANN::read_screening(std::vector<std::string> line,std::vector<std::str
k = atomtypes[2]; k = atomtypes[2];
int index = i*nelements*nelements+j*nelements+k; int index = i*nelements*nelements+j*nelements+k;
if (line[4].compare("Cmin")==0) { if (line[4].compare("Cmin")==0) {
screening_min[index] = utils::numeric(filename,linenum,line1[0].c_str(),true,lmp); screening_min[index] = utils::numeric(filename,linenum,line1[0],true,lmp);
} }
else if (line[4].compare("Cmax")==0) { else if (line[4].compare("Cmax")==0) {
screening_max[index] = utils::numeric(filename,linenum,line1[0].c_str(),true,lmp); screening_max[index] = utils::numeric(filename,linenum,line1[0],true,lmp);
} }
else error->one(filename,linenum-1,"unrecognized screening keyword"); else error->one(filename,linenum-1,"unrecognized screening keyword");
delete[] atomtypes; delete[] atomtypes;

View File

@ -570,8 +570,8 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename)
else else
elementflags[jelem] = 1; elementflags[jelem] = 1;
radelem[jelem] = utils::numeric(FLERR,words[1].c_str(),false,lmp); radelem[jelem] = utils::numeric(FLERR,words[1],false,lmp);
wjelem[jelem] = utils::numeric(FLERR,words[2].c_str(),false,lmp); wjelem[jelem] = utils::numeric(FLERR,words[2],false,lmp);
if (comm->me == 0) if (comm->me == 0)
utils::logmesg(lmp,"SNAP Element = {}, Radius {}, Weight {}\n", utils::logmesg(lmp,"SNAP Element = {}, Radius {}, Weight {}\n",
@ -672,34 +672,33 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename)
utils::logmesg(lmp,"SNAP keyword {} {}\n",keywd,keyval); utils::logmesg(lmp,"SNAP keyword {} {}\n",keywd,keyval);
if (keywd == "rcutfac") { if (keywd == "rcutfac") {
rcutfac = utils::numeric(FLERR,keyval.c_str(),false,lmp); rcutfac = utils::numeric(FLERR,keyval,false,lmp);
rcutfacflag = 1; rcutfacflag = 1;
} else if (keywd == "twojmax") { } else if (keywd == "twojmax") {
twojmax = utils::inumeric(FLERR,keyval.c_str(),false,lmp); twojmax = utils::inumeric(FLERR,keyval,false,lmp);
twojmaxflag = 1; twojmaxflag = 1;
} else if (keywd == "rfac0") } else if (keywd == "rfac0")
rfac0 = utils::numeric(FLERR,keyval.c_str(),false,lmp); rfac0 = utils::numeric(FLERR,keyval,false,lmp);
else if (keywd == "rmin0") else if (keywd == "rmin0")
rmin0 = utils::numeric(FLERR,keyval.c_str(),false,lmp); rmin0 = utils::numeric(FLERR,keyval,false,lmp);
else if (keywd == "switchflag") else if (keywd == "switchflag")
switchflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); switchflag = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "bzeroflag") else if (keywd == "bzeroflag")
bzeroflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); bzeroflag = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "quadraticflag") else if (keywd == "quadraticflag")
quadraticflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); quadraticflag = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "chemflag") else if (keywd == "chemflag")
chemflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); chemflag = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "bnormflag") else if (keywd == "bnormflag")
bnormflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); bnormflag = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "wselfallflag") else if (keywd == "wselfallflag")
wselfallflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); wselfallflag = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "chunksize") else if (keywd == "chunksize")
chunksize = utils::inumeric(FLERR,keyval.c_str(),false,lmp); chunksize = utils::inumeric(FLERR,keyval,false,lmp);
else if (keywd == "parallelthresh") else if (keywd == "parallelthresh")
parallel_thresh = utils::inumeric(FLERR,keyval.c_str(),false,lmp); parallel_thresh = utils::inumeric(FLERR,keyval,false,lmp);
else else
error->all(FLERR,"Unknown parameter '{}' in SNAP " error->all(FLERR,"Unknown parameter '{}' in SNAP parameter file", keywd);
"parameter file", keywd);
} }
if (rcutfacflag == 0 || twojmaxflag == 0) if (rcutfacflag == 0 || twojmaxflag == 0)

View File

@ -29,6 +29,7 @@
#include "modify.h" #include "modify.h"
#include "molecule.h" #include "molecule.h"
#include "neighbor.h" #include "neighbor.h"
#include "tokenizer.h"
#include "update.h" #include "update.h"
#include "variable.h" #include "variable.h"
@ -1057,6 +1058,7 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
double *coord; double *coord;
char *next; char *next;
// use the first line to detect and validate the number of words/tokens per line
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0'; *next = '\0';
int nwords = utils::trim_and_count_words(buf); int nwords = utils::trim_and_count_words(buf);
@ -1065,8 +1067,6 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
if (nwords != avec->size_data_atom && nwords != avec->size_data_atom + 3) if (nwords != avec->size_data_atom && nwords != avec->size_data_atom + 3)
error->all(FLERR,"Incorrect atom format in data file"); error->all(FLERR,"Incorrect atom format in data file");
char **values = new char*[nwords];
// set bounds for my proc // set bounds for my proc
// if periodic and I am lo/hi proc, adjust bounds by EPSILON // if periodic and I am lo/hi proc, adjust bounds by EPSILON
// insures all data atoms will be owned even with round-off // insures all data atoms will be owned even with round-off
@ -1137,15 +1137,10 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0';
for (m = 0; m < nwords; m++) { auto values = Tokenizer(utils::trim_comment(buf)).as_vector();
buf += strspn(buf," \t\n\r\f"); if (values.size() != nwords)
buf[strcspn(buf," \t\n\r\f")] = '\0'; error->all(FLERR, "Incorrect atom format in data file: {}", utils::trim(buf));
if (strlen(buf) == 0)
error->all(FLERR,"Incorrect atom format in data file");
values[m] = buf;
buf += strlen(buf)+1;
}
int imx = 0, imy = 0, imz = 0; int imx = 0, imy = 0, imz = 0;
if (imageflag) { if (imageflag) {
@ -1192,7 +1187,6 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
buf = next + 1; buf = next + 1;
} }
delete [] values;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -1204,7 +1198,6 @@ void Atom::data_atoms(int n, char *buf, tagint id_offset, tagint mol_offset,
void Atom::data_vels(int n, char *buf, tagint id_offset) void Atom::data_vels(int n, char *buf, tagint id_offset)
{ {
int j,m; int j,m;
tagint tagdata;
char *next; char *next;
next = strchr(buf,'\n'); next = strchr(buf,'\n');
@ -1215,31 +1208,24 @@ void Atom::data_vels(int n, char *buf, tagint id_offset)
if (nwords != avec->size_data_vel) if (nwords != avec->size_data_vel)
error->all(FLERR,"Incorrect velocity format in data file"); error->all(FLERR,"Incorrect velocity format in data file");
char **values = new char*[nwords];
// loop over lines of atom velocities // loop over lines of atom velocities
// tokenize the line into values // tokenize the line into values
// if I own atom tag, unpack its values // if I own atom tag, unpack its values
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0';
auto values = Tokenizer(utils::trim_comment(buf)).as_vector();
if (values.size() != nwords)
error->all(FLERR, "Incorrect atom format in data file: {}", utils::trim(buf));
for (j = 0; j < nwords; j++) { tagint tagdata = utils::tnumeric(FLERR,values[0],false,lmp) + id_offset;
buf += strspn(buf," \t\n\r\f");
buf[strcspn(buf," \t\n\r\f")] = '\0';
values[j] = buf;
buf += strlen(buf)+1;
}
tagdata = ATOTAGINT(values[0]) + id_offset;
if (tagdata <= 0 || tagdata > map_tag_max) if (tagdata <= 0 || tagdata > map_tag_max)
error->one(FLERR,"Invalid atom ID in Velocities section of data file"); error->one(FLERR,"Invalid atom ID in Velocities section of data file");
if ((m = map(tagdata)) >= 0) avec->data_vel(m,&values[1]); if ((m = map(tagdata)) >= 0) avec->data_vel(m,values);
buf = next + 1; buf = next + 1;
} }
delete [] values;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -1252,18 +1238,25 @@ void Atom::data_vels(int n, char *buf, tagint id_offset)
void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset, void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset,
int type_offset) int type_offset)
{ {
int m,tmp,itype,rv; int m,itype;
tagint atom1,atom2; tagint atom1,atom2;
char *next; char *next;
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
auto location = "Bonds section of data file";
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0'; *next = '\0';
rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT, try {
&tmp,&itype,&atom1,&atom2); ValueTokenizer values(utils::trim_comment(buf));
if (rv != 4) values.next_int();
error->one(FLERR,"Incorrect format of Bonds section in data file"); itype = values.next_int();
atom1 = values.next_tagint();
atom2 = values.next_tagint();
if (values.has_next()) throw TokenizerException("Too many tokens","");
} catch (TokenizerException &e) {
error->one(FLERR,"{} in {}: {}", e.what(), location, utils::trim(buf));
}
if (id_offset) { if (id_offset) {
atom1 += id_offset; atom1 += id_offset;
atom2 += id_offset; atom2 += id_offset;
@ -1272,9 +1265,9 @@ void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset,
if ((atom1 <= 0) || (atom1 > map_tag_max) || if ((atom1 <= 0) || (atom1 > map_tag_max) ||
(atom2 <= 0) || (atom2 > map_tag_max) || (atom1 == atom2)) (atom2 <= 0) || (atom2 > map_tag_max) || (atom1 == atom2))
error->one(FLERR,"Invalid atom ID in Bonds section of data file"); error->one(FLERR,"Invalid atom ID in {}: {}", location, utils::trim(buf));
if (itype <= 0 || itype > nbondtypes) if (itype <= 0 || itype > nbondtypes)
error->one(FLERR,"Invalid bond type in Bonds section of data file"); error->one(FLERR,"Invalid bond type in {}: {}", location, utils::trim(buf));
if ((m = map(atom1)) >= 0) { if ((m = map(atom1)) >= 0) {
if (count) count[m]++; if (count) count[m]++;
else { else {
@ -1309,18 +1302,26 @@ void Atom::data_bonds(int n, char *buf, int *count, tagint id_offset,
void Atom::data_angles(int n, char *buf, int *count, tagint id_offset, void Atom::data_angles(int n, char *buf, int *count, tagint id_offset,
int type_offset) int type_offset)
{ {
int m,tmp,itype,rv; int m,itype;
tagint atom1,atom2,atom3; tagint atom1,atom2,atom3;
char *next; char *next;
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
auto location = "Angles section of data file";
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0'; *next = '\0';
rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, try {
&tmp,&itype,&atom1,&atom2,&atom3); ValueTokenizer values(utils::trim_comment(buf));
if (rv != 5) values.next_int();
error->one(FLERR,"Incorrect format of Angles section in data file"); itype = values.next_int();
atom1 = values.next_tagint();
atom2 = values.next_tagint();
atom3 = values.next_tagint();
if (values.has_next()) throw TokenizerException("Too many tokens","");
} catch (TokenizerException &e) {
error->one(FLERR,"{} in {}: {}", e.what(), location, utils::trim(buf));
}
if (id_offset) { if (id_offset) {
atom1 += id_offset; atom1 += id_offset;
atom2 += id_offset; atom2 += id_offset;
@ -1332,9 +1333,9 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset,
(atom2 <= 0) || (atom2 > map_tag_max) || (atom2 <= 0) || (atom2 > map_tag_max) ||
(atom3 <= 0) || (atom3 > map_tag_max) || (atom3 <= 0) || (atom3 > map_tag_max) ||
(atom1 == atom2) || (atom1 == atom3) || (atom2 == atom3)) (atom1 == atom2) || (atom1 == atom3) || (atom2 == atom3))
error->one(FLERR,"Invalid atom ID in Angles section of data file"); error->one(FLERR,"Invalid atom ID in {}: {}", location, utils::trim(buf));
if (itype <= 0 || itype > nangletypes) if (itype <= 0 || itype > nangletypes)
error->one(FLERR,"Invalid angle type in Angles section of data file"); error->one(FLERR,"Invalid angle type in {}: {}", location, utils::trim(buf));
if ((m = map(atom2)) >= 0) { if ((m = map(atom2)) >= 0) {
if (count) count[m]++; if (count) count[m]++;
else { else {
@ -1381,19 +1382,27 @@ void Atom::data_angles(int n, char *buf, int *count, tagint id_offset,
void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset, void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset,
int type_offset) int type_offset)
{ {
int m,tmp,itype,rv; int m,itype;
tagint atom1,atom2,atom3,atom4; tagint atom1,atom2,atom3,atom4;
char *next; char *next;
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
auto location = "Dihedrals section of data file";
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0'; *next = '\0';
rv = sscanf(buf,"%d %d " TAGINT_FORMAT " " TAGINT_FORMAT try {
" " TAGINT_FORMAT " " TAGINT_FORMAT, ValueTokenizer values(utils::trim_comment(buf));
&tmp,&itype,&atom1,&atom2,&atom3,&atom4); values.next_int();
if (rv != 6) itype = values.next_int();
error->one(FLERR,"Incorrect format of Dihedrals section in data file"); atom1 = values.next_tagint();
atom2 = values.next_tagint();
atom3 = values.next_tagint();
atom4 = values.next_tagint();
if (values.has_next()) throw TokenizerException("Too many tokens","");
} catch (TokenizerException &e) {
error->one(FLERR,"{} in {}: {}", e.what(), location, utils::trim(buf));
}
if (id_offset) { if (id_offset) {
atom1 += id_offset; atom1 += id_offset;
atom2 += id_offset; atom2 += id_offset;
@ -1408,10 +1417,9 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset,
(atom4 <= 0) || (atom4 > map_tag_max) || (atom4 <= 0) || (atom4 > map_tag_max) ||
(atom1 == atom2) || (atom1 == atom3) || (atom1 == atom4) || (atom1 == atom2) || (atom1 == atom3) || (atom1 == atom4) ||
(atom2 == atom3) || (atom2 == atom4) || (atom3 == atom4)) (atom2 == atom3) || (atom2 == atom4) || (atom3 == atom4))
error->one(FLERR,"Invalid atom ID in Dihedrals section of data file"); error->one(FLERR, "Invalid atom ID in {}: {}", location, utils::trim(buf));
if (itype <= 0 || itype > ndihedraltypes) if (itype <= 0 || itype > ndihedraltypes)
error->one(FLERR, error->one(FLERR, "Invalid dihedral type in {}: {}", location, utils::trim(buf));
"Invalid dihedral type in Dihedrals section of data file");
if ((m = map(atom2)) >= 0) { if ((m = map(atom2)) >= 0) {
if (count) count[m]++; if (count) count[m]++;
else { else {
@ -1472,19 +1480,27 @@ void Atom::data_dihedrals(int n, char *buf, int *count, tagint id_offset,
void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset, void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset,
int type_offset) int type_offset)
{ {
int m,tmp,itype,rv; int m,itype;
tagint atom1,atom2,atom3,atom4; tagint atom1,atom2,atom3,atom4;
char *next; char *next;
int newton_bond = force->newton_bond; int newton_bond = force->newton_bond;
auto location = "Impropers section of data file";
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0'; *next = '\0';
rv = sscanf(buf,"%d %d " try {
TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT, ValueTokenizer values(utils::trim_comment(buf));
&tmp,&itype,&atom1,&atom2,&atom3,&atom4); values.next_int();
if (rv != 6) itype = values.next_int();
error->one(FLERR,"Incorrect format of Impropers section in data file"); atom1 = values.next_tagint();
atom2 = values.next_tagint();
atom3 = values.next_tagint();
atom4 = values.next_tagint();
if (values.has_next()) throw TokenizerException("Too many tokens","");
} catch (TokenizerException &e) {
error->one(FLERR,"{} in {}: {}", e.what(), location, utils::trim(buf));
}
if (id_offset) { if (id_offset) {
atom1 += id_offset; atom1 += id_offset;
atom2 += id_offset; atom2 += id_offset;
@ -1499,10 +1515,9 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset,
(atom4 <= 0) || (atom4 > map_tag_max) || (atom4 <= 0) || (atom4 > map_tag_max) ||
(atom1 == atom2) || (atom1 == atom3) || (atom1 == atom4) || (atom1 == atom2) || (atom1 == atom3) || (atom1 == atom4) ||
(atom2 == atom3) || (atom2 == atom4) || (atom3 == atom4)) (atom2 == atom3) || (atom2 == atom4) || (atom3 == atom4))
error->one(FLERR,"Invalid atom ID in Impropers section of data file"); error->one(FLERR, "Invalid atom ID in {}: {}", location, utils::trim(buf));
if (itype <= 0 || itype > nimpropertypes) if (itype <= 0 || itype > nimpropertypes)
error->one(FLERR, error->one(FLERR, "Invalid improper type in {}: {}", location, utils::trim(buf));
"Invalid improper type in Impropers section of data file");
if ((m = map(atom2)) >= 0) { if ((m = map(atom2)) >= 0) {
if (count) count[m]++; if (count) count[m]++;
else { else {
@ -1561,7 +1576,7 @@ void Atom::data_impropers(int n, char *buf, int *count, tagint id_offset,
void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus, tagint id_offset) void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus, tagint id_offset)
{ {
int j,m,tagdata; int j,m;
char *next; char *next;
next = strchr(buf,'\n'); next = strchr(buf,'\n');
@ -1572,35 +1587,28 @@ void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus, tagint id_offset)
if (nwords != avec_bonus->size_data_bonus) if (nwords != avec_bonus->size_data_bonus)
error->all(FLERR,"Incorrect bonus data format in data file"); error->all(FLERR,"Incorrect bonus data format in data file");
char **values = new char*[nwords];
// loop over lines of bonus atom data // loop over lines of bonus atom data
// tokenize the line into values // tokenize the line into values
// if I own atom tag, unpack its values // if I own atom tag, unpack its values
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
next = strchr(buf,'\n'); next = strchr(buf,'\n');
*next = '\0';
auto values = Tokenizer(utils::trim_comment(buf)).as_vector();
if (values.size() != nwords)
error->all(FLERR, "Incorrect atom format in data file: {}", utils::trim(buf));
for (j = 0; j < nwords; j++) { tagint tagdata = utils::tnumeric(FLERR,values[0],false,lmp) + id_offset;
buf += strspn(buf," \t\n\r\f");
buf[strcspn(buf," \t\n\r\f")] = '\0';
values[j] = buf;
buf += strlen(buf)+1;
}
tagdata = ATOTAGINT(values[0]) + id_offset;
if (tagdata <= 0 || tagdata > map_tag_max) if (tagdata <= 0 || tagdata > map_tag_max)
error->one(FLERR,"Invalid atom ID in Bonus section of data file"); error->one(FLERR,"Invalid atom ID in Bonus section of data file");
// ok to call child's data_atom_bonus() method thru parent avec_bonus, // ok to call child's data_atom_bonus() method thru parent avec_bonus,
// since data_bonus() was called with child ptr, and method is virtual // since data_bonus() was called with child ptr, and method is virtual
if ((m = map(tagdata)) >= 0) avec_bonus->data_atom_bonus(m,&values[1]); if ((m = map(tagdata)) >= 0) avec_bonus->data_atom_bonus(m,values);
buf = next + 1; buf = next + 1;
} }
delete [] values;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -1612,12 +1620,8 @@ void Atom::data_bonus(int n, char *buf, AtomVec *avec_bonus, tagint id_offset)
void Atom::data_bodies(int n, char *buf, AtomVec *avec_body, tagint id_offset) void Atom::data_bodies(int n, char *buf, AtomVec *avec_body, tagint id_offset)
{ {
int j,m,nvalues,tagdata,ninteger,ndouble; std::vector<int> ivalues;
std::vector<double> dvalues;
int maxint = 0;
int maxdouble = 0;
int *ivalues = nullptr;
double *dvalues = nullptr;
if (!unique_tags) unique_tags = new std::set<tagint>; if (!unique_tags) unique_tags = new std::set<tagint>;
@ -1626,69 +1630,51 @@ void Atom::data_bodies(int n, char *buf, AtomVec *avec_body, tagint id_offset)
// else skip values // else skip values
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
buf += strspn(buf," \t\n\r\f"); char *next = strchr(buf,'\n');
buf[strcspn(buf," \t\n\r\f")] = '\0'; *next = '\0';
tagdata = utils::tnumeric(FLERR,buf,false,lmp) + id_offset;
buf += strlen(buf)+1;
if (tagdata <= 0 || tagdata > map_tag_max) auto values = Tokenizer(utils::trim_comment(buf)).as_vector();
error->one(FLERR,"Invalid atom ID in Bodies section of data file"); tagint tagdata = utils::tnumeric(FLERR,values[0],false,lmp) + id_offset;
int ninteger = utils::inumeric(FLERR,values[1],false,lmp);
int ndouble = utils::inumeric(FLERR,values[2],false,lmp);
if (unique_tags->find(tagdata) == unique_tags->end()) if (unique_tags->find(tagdata) == unique_tags->end())
unique_tags->insert(tagdata); unique_tags->insert(tagdata);
else else
error->one(FLERR,"Duplicate atom ID in Bodies section of data file"); error->one(FLERR,"Duplicate atom ID in Bodies section of data file");
buf += strspn(buf," \t\n\r\f"); buf = next + 1;
buf[strcspn(buf," \t\n\r\f")] = '\0'; int m = map(tagdata);
ninteger = utils::inumeric(FLERR,buf,false,lmp); if (m >= 0) {
buf += strlen(buf)+1; ivalues.resize(ninteger);
dvalues.resize(ndouble);
buf += strspn(buf," \t\n\r\f"); for (int j = 0; j < ninteger; j++) {
buf[strcspn(buf," \t\n\r\f")] = '\0';
ndouble = utils::inumeric(FLERR,buf,false,lmp);
buf += strlen(buf)+1;
if ((m = map(tagdata)) >= 0) {
if (ninteger > maxint) {
delete [] ivalues;
maxint = ninteger;
ivalues = new int[maxint];
}
if (ndouble > maxdouble) {
delete [] dvalues;
maxdouble = ndouble;
dvalues = new double[maxdouble];
}
for (j = 0; j < ninteger; j++) {
buf += strspn(buf," \t\n\r\f"); buf += strspn(buf," \t\n\r\f");
buf[strcspn(buf," \t\n\r\f")] = '\0'; buf[strcspn(buf," \t\n\r\f")] = '\0';
ivalues[j] = utils::inumeric(FLERR,buf,false,lmp); ivalues[j] = utils::inumeric(FLERR,buf,false,lmp);
buf += strlen(buf)+1; buf += strlen(buf)+1;
} }
for (j = 0; j < ndouble; j++) { for (int j = 0; j < ndouble; j++) {
buf += strspn(buf," \t\n\r\f"); buf += strspn(buf," \t\n\r\f");
buf[strcspn(buf," \t\n\r\f")] = '\0'; buf[strcspn(buf," \t\n\r\f")] = '\0';
dvalues[j] = utils::numeric(FLERR,buf,false,lmp); dvalues[j] = utils::numeric(FLERR,buf,false,lmp);
buf += strlen(buf)+1; buf += strlen(buf)+1;
} }
avec_body->data_body(m,ninteger,ndouble,ivalues,dvalues); avec_body->data_body(m,ninteger,ndouble,ivalues.data(),dvalues.data());
} else { } else {
nvalues = ninteger + ndouble; // number of values to skip int nvalues = ninteger + ndouble; // number of values to skip
for (j = 0; j < nvalues; j++) { for (int j = 0; j < nvalues; j++) {
buf += strspn(buf," \t\n\r\f"); buf += strspn(buf," \t\n\r\f");
buf[strcspn(buf," \t\n\r\f")] = '\0'; buf[strcspn(buf," \t\n\r\f")] = '\0';
buf += strlen(buf)+1; buf += strlen(buf)+1;
} }
} }
buf += strspn(buf," \t\n\r\f");
} }
delete [] ivalues;
delete [] dvalues;
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
@ -1743,17 +1729,20 @@ void Atom::set_mass(const char *file, int line, const char *str, int type_offset
int itype; int itype;
double mass_one; double mass_one;
int n = sscanf(str,"%d %lg",&itype,&mass_one); try {
if (n != 2) error->all(file,line,"Invalid mass line in data file"); ValueTokenizer values(utils::trim_comment(str));
itype += type_offset; itype = values.next_int() + type_offset;
mass_one = values.next_double();
if (values.has_next()) throw TokenizerException("Too many tokens", "");
if (itype < 1 || itype > ntypes) if (itype < 1 || itype > ntypes) throw TokenizerException("Invalid atom type", "");
error->all(file,line,"Invalid type for mass set"); if (mass_one <= 0.0) throw TokenizerException("Invalid mass value", "");
} catch (TokenizerException &e) {
error->all(file,line,"{} in Masses section of data file: {}", e.what(), utils::trim(str));
}
mass[itype] = mass_one; mass[itype] = mass_one;
mass_setflag[itype] = 1; mass_setflag[itype] = 1;
if (mass[itype] <= 0.0) error->all(file,line,"Invalid mass value");
} }
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------

View File

@ -1707,7 +1707,7 @@ void AtomVec::create_atom(int itype, double *coord)
initialize other peratom quantities initialize other peratom quantities
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVec::data_atom(double *coord, imageint imagetmp, char **values) void AtomVec::data_atom(double *coord, imageint imagetmp, const std::vector<std::string> &values)
{ {
int m,n,datatype,cols; int m,n,datatype,cols;
void *pdata; void *pdata;
@ -1890,18 +1890,18 @@ void AtomVec::write_data(FILE *fp, int n, double **buf)
unpack one line from Velocities section of data file unpack one line from Velocities section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVec::data_vel(int ilocal, char **values) void AtomVec::data_vel(int ilocal, const std::vector<std::string> &values)
{ {
int m,n,datatype,cols; int m,n,datatype,cols;
void *pdata; void *pdata;
double **v = atom->v; double **v = atom->v;
v[ilocal][0] = utils::numeric(FLERR,values[0],true,lmp); int ivalue = 1;
v[ilocal][1] = utils::numeric(FLERR,values[1],true,lmp); v[ilocal][0] = utils::numeric(FLERR,values[ivalue++],true,lmp);
v[ilocal][2] = utils::numeric(FLERR,values[2],true,lmp); v[ilocal][1] = utils::numeric(FLERR,values[ivalue++],true,lmp);
v[ilocal][2] = utils::numeric(FLERR,values[ivalue++],true,lmp);
if (ndata_vel > 2) { if (ndata_vel > 2) {
int ivalue = 3;
for (n = 2; n < ndata_vel; n++) { for (n = 2; n < ndata_vel; n++) {
pdata = mdata_vel.pdata[n]; pdata = mdata_vel.pdata[n];
datatype = mdata_vel.datatype[n]; datatype = mdata_vel.datatype[n];

View File

@ -124,9 +124,9 @@ class AtomVec : protected Pointers {
virtual void create_atom(int, double *); virtual void create_atom(int, double *);
virtual void create_atom_post(int) {} virtual void create_atom_post(int) {}
virtual void data_atom(double *, imageint, char **); virtual void data_atom(double *, imageint, const std::vector<std::string> &);
virtual void data_atom_post(int) {} virtual void data_atom_post(int) {}
virtual void data_atom_bonus(int, char **) {} virtual void data_atom_bonus(int, const std::vector<std::string> &) {}
virtual void data_body(int, int, int, int *, double *) {} virtual void data_body(int, int, int, int *, double *) {}
virtual void data_bonds_post(int, int, tagint, tagint, tagint) {} virtual void data_bonds_post(int, int, tagint, tagint, tagint) {}
@ -136,7 +136,7 @@ class AtomVec : protected Pointers {
virtual void pack_data_pre(int) {} virtual void pack_data_pre(int) {}
virtual void pack_data_post(int) {} virtual void pack_data_post(int) {}
virtual void data_vel(int, char **); virtual void data_vel(int, const std::vector<std::string> &);
virtual void pack_vel(double **); virtual void pack_vel(double **);
virtual void write_vel(FILE *, int, double **); virtual void write_vel(FILE *, int, double **);
@ -166,8 +166,8 @@ class AtomVec : protected Pointers {
virtual int unpack_reverse_hybrid(int, int *, double *) { return 0; } virtual int unpack_reverse_hybrid(int, int *, double *) { return 0; }
virtual int pack_border_hybrid(int, int *, double *) { return 0; } virtual int pack_border_hybrid(int, int *, double *) { return 0; }
virtual int unpack_border_hybrid(int, int, double *) { return 0; } virtual int unpack_border_hybrid(int, int, double *) { return 0; }
virtual int data_atom_hybrid(int, char **) { return 0; } virtual int data_atom_hybrid(int, const std::vector<std::string> &, int) { return 0; }
virtual int data_vel_hybrid(int, char **) { return 0; } virtual int data_vel_hybrid(int, const std::vector<std::string> &, int) { return 0; }
virtual int pack_data_hybrid(int, double *) { return 0; } virtual int pack_data_hybrid(int, double *) { return 0; }
virtual int write_data_hybrid(FILE *, double *) { return 0; } virtual int write_data_hybrid(FILE *, double *) { return 0; }
virtual int pack_vel_hybrid(int, double *) { return 0; } virtual int pack_vel_hybrid(int, double *) { return 0; }

View File

@ -381,7 +381,7 @@ int AtomVecEllipsoid::unpack_restart_bonus(int ilocal, double *buf)
unpack one line from Ellipsoids section of data file unpack one line from Ellipsoids section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecEllipsoid::data_atom_bonus(int m, char **values) void AtomVecEllipsoid::data_atom_bonus(int m, const std::vector<std::string> & values)
{ {
if (ellipsoid[m]) if (ellipsoid[m])
error->one(FLERR,"Assigning ellipsoid parameters to non-ellipsoid atom"); error->one(FLERR,"Assigning ellipsoid parameters to non-ellipsoid atom");
@ -389,17 +389,18 @@ void AtomVecEllipsoid::data_atom_bonus(int m, char **values)
if (nlocal_bonus == nmax_bonus) grow_bonus(); if (nlocal_bonus == nmax_bonus) grow_bonus();
double *shape = bonus[nlocal_bonus].shape; double *shape = bonus[nlocal_bonus].shape;
shape[0] = 0.5 * utils::numeric(FLERR,values[0],true,lmp); int ivalue = 1;
shape[1] = 0.5 * utils::numeric(FLERR,values[1],true,lmp); shape[0] = 0.5 * utils::numeric(FLERR,values[ivalue++],true,lmp);
shape[2] = 0.5 * utils::numeric(FLERR,values[2],true,lmp); shape[1] = 0.5 * utils::numeric(FLERR,values[ivalue++],true,lmp);
shape[2] = 0.5 * utils::numeric(FLERR,values[ivalue++],true,lmp);
if (shape[0] <= 0.0 || shape[1] <= 0.0 || shape[2] <= 0.0) if (shape[0] <= 0.0 || shape[1] <= 0.0 || shape[2] <= 0.0)
error->one(FLERR,"Invalid shape in Ellipsoids section of data file"); error->one(FLERR,"Invalid shape in Ellipsoids section of data file");
double *quat = bonus[nlocal_bonus].quat; double *quat = bonus[nlocal_bonus].quat;
quat[0] = utils::numeric(FLERR,values[3],true,lmp); quat[0] = utils::numeric(FLERR,values[ivalue++],true,lmp);
quat[1] = utils::numeric(FLERR,values[4],true,lmp); quat[1] = utils::numeric(FLERR,values[ivalue++],true,lmp);
quat[2] = utils::numeric(FLERR,values[5],true,lmp); quat[2] = utils::numeric(FLERR,values[ivalue++],true,lmp);
quat[3] = utils::numeric(FLERR,values[6],true,lmp); quat[3] = utils::numeric(FLERR,values[ivalue++],true,lmp);
MathExtra::qnormalize(quat); MathExtra::qnormalize(quat);
// reset ellipsoid mass // reset ellipsoid mass

View File

@ -48,7 +48,7 @@ class AtomVecEllipsoid : public AtomVec {
int size_restart_bonus(); int size_restart_bonus();
int pack_restart_bonus(int, double *); int pack_restart_bonus(int, double *);
int unpack_restart_bonus(int, double *); int unpack_restart_bonus(int, double *);
void data_atom_bonus(int, char **); void data_atom_bonus(int, const std::vector<std::string> &);
double memory_usage_bonus(); double memory_usage_bonus();
void create_atom_post(int); void create_atom_post(int);

View File

@ -337,16 +337,17 @@ int AtomVecLine::unpack_restart_bonus(int ilocal, double *buf)
unpack one line from Lines section of data file unpack one line from Lines section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecLine::data_atom_bonus(int m, char **values) void AtomVecLine::data_atom_bonus(int m, const std::vector<std::string> &values)
{ {
if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom"); if (line[m]) error->one(FLERR,"Assigning line parameters to non-line atom");
if (nlocal_bonus == nmax_bonus) grow_bonus(); if (nlocal_bonus == nmax_bonus) grow_bonus();
double x1 = utils::numeric(FLERR,values[0],true,lmp); int ivalue = 1;
double y1 = utils::numeric(FLERR,values[1],true,lmp); double x1 = utils::numeric(FLERR,values[ivalue++],true,lmp);
double x2 = utils::numeric(FLERR,values[2],true,lmp); double y1 = utils::numeric(FLERR,values[ivalue++],true,lmp);
double y2 = utils::numeric(FLERR,values[3],true,lmp); double x2 = utils::numeric(FLERR,values[ivalue++],true,lmp);
double y2 = utils::numeric(FLERR,values[ivalue++],true,lmp);
double dx = x2 - x1; double dx = x2 - x1;
double dy = y2 - y1; double dy = y2 - y1;
double length = sqrt(dx*dx + dy*dy); double length = sqrt(dx*dx + dy*dy);

View File

@ -48,7 +48,7 @@ class AtomVecLine : public AtomVec {
int size_restart_bonus(); int size_restart_bonus();
int pack_restart_bonus(int, double *); int pack_restart_bonus(int, double *);
int unpack_restart_bonus(int, double *); int unpack_restart_bonus(int, double *);
void data_atom_bonus(int, char **); void data_atom_bonus(int, const std::vector<std::string> &);
double memory_usage_bonus(); double memory_usage_bonus();
void create_atom_post(int); void create_atom_post(int);

View File

@ -470,22 +470,23 @@ int AtomVecTri::unpack_restart_bonus(int ilocal, double *buf)
unpack one line from Tris section of data file unpack one line from Tris section of data file
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void AtomVecTri::data_atom_bonus(int m, char **values) void AtomVecTri::data_atom_bonus(int m, const std::vector<std::string> &values)
{ {
if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom"); if (tri[m]) error->one(FLERR,"Assigning tri parameters to non-tri atom");
if (nlocal_bonus == nmax_bonus) grow_bonus(); if (nlocal_bonus == nmax_bonus) grow_bonus();
double c1[3],c2[3],c3[3]; double c1[3],c2[3],c3[3];
c1[0] = utils::numeric(FLERR,values[0],true,lmp); int ivalue = 1;
c1[1] = utils::numeric(FLERR,values[1],true,lmp); c1[0] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c1[2] = utils::numeric(FLERR,values[2],true,lmp); c1[1] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c2[0] = utils::numeric(FLERR,values[3],true,lmp); c1[2] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c2[1] = utils::numeric(FLERR,values[4],true,lmp); c2[0] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c2[2] = utils::numeric(FLERR,values[5],true,lmp); c2[1] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c3[0] = utils::numeric(FLERR,values[6],true,lmp); c2[2] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c3[1] = utils::numeric(FLERR,values[7],true,lmp); c3[0] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c3[2] = utils::numeric(FLERR,values[8],true,lmp); c3[1] = utils::numeric(FLERR,values[ivalue++],true,lmp);
c3[2] = utils::numeric(FLERR,values[ivalue++],true,lmp);
// check for duplicate points // check for duplicate points

View File

@ -50,7 +50,7 @@ class AtomVecTri : public AtomVec {
int size_restart_bonus(); int size_restart_bonus();
int pack_restart_bonus(int, double *); int pack_restart_bonus(int, double *);
int unpack_restart_bonus(int, double *); int unpack_restart_bonus(int, double *);
void data_atom_bonus(int, char **); void data_atom_bonus(int, const std::vector<std::string> &);
double memory_usage_bonus(); double memory_usage_bonus();
void create_atom_post(int); void create_atom_post(int);

View File

@ -35,6 +35,7 @@
#include "molecule.h" #include "molecule.h"
#include "pair.h" #include "pair.h"
#include "special.h" #include "special.h"
#include "tokenizer.h"
#include "update.h" #include "update.h"
#include <cctype> #include <cctype>
@ -1088,37 +1089,32 @@ void ReadData::header(int firstpass)
} else if (utils::strmatch(line,"^\\s*\\d+\\s+atom\\s+types\\s")) { } else if (utils::strmatch(line,"^\\s*\\d+\\s+atom\\s+types\\s")) {
rv = sscanf(line,"%d",&ntypes); rv = sscanf(line,"%d",&ntypes);
if (rv != 1) if (rv != 1)
error->all(FLERR,"Could not parse 'atom types' line " error->all(FLERR,"Could not parse 'atom types' line in data file header");
"in data file header");
if (addflag == NONE) atom->ntypes = ntypes + extra_atom_types; if (addflag == NONE) atom->ntypes = ntypes + extra_atom_types;
} else if (utils::strmatch(line,"\\s*\\d+\\s+bond\\s+types\\s")) { } else if (utils::strmatch(line,"\\s*\\d+\\s+bond\\s+types\\s")) {
rv = sscanf(line,"%d",&nbondtypes); rv = sscanf(line,"%d",&nbondtypes);
if (rv != 1) if (rv != 1)
error->all(FLERR,"Could not parse 'bond types' line " error->all(FLERR,"Could not parse 'bond types' line in data file header");
"in data file header");
if (addflag == NONE) atom->nbondtypes = nbondtypes + extra_bond_types; if (addflag == NONE) atom->nbondtypes = nbondtypes + extra_bond_types;
} else if (utils::strmatch(line,"^\\s*\\d+\\s+angle\\s+types\\s")) { } else if (utils::strmatch(line,"^\\s*\\d+\\s+angle\\s+types\\s")) {
rv = sscanf(line,"%d",&nangletypes); rv = sscanf(line,"%d",&nangletypes);
if (rv != 1) if (rv != 1)
error->all(FLERR,"Could not parse 'angle types' line " error->all(FLERR,"Could not parse 'angle types' line in data file header");
"in data file header");
if (addflag == NONE) atom->nangletypes = nangletypes + extra_angle_types; if (addflag == NONE) atom->nangletypes = nangletypes + extra_angle_types;
} else if (utils::strmatch(line,"^\\s*\\d+\\s+dihedral\\s+types\\s")) { } else if (utils::strmatch(line,"^\\s*\\d+\\s+dihedral\\s+types\\s")) {
rv = sscanf(line,"%d",&ndihedraltypes); rv = sscanf(line,"%d",&ndihedraltypes);
if (rv != 1) if (rv != 1)
error->all(FLERR,"Could not parse 'dihedral types' line " error->all(FLERR,"Could not parse 'dihedral types' line in data file header");
"in data file header");
if (addflag == NONE) if (addflag == NONE)
atom->ndihedraltypes = ndihedraltypes + extra_dihedral_types; atom->ndihedraltypes = ndihedraltypes + extra_dihedral_types;
} else if (utils::strmatch(line,"^\\s*\\d+\\s+improper\\s+types\\s")) { } else if (utils::strmatch(line,"^\\s*\\d+\\s+improper\\s+types\\s")) {
rv = sscanf(line,"%d",&nimpropertypes); rv = sscanf(line,"%d",&nimpropertypes);
if (rv != 1) if (rv != 1)
error->all(FLERR,"Could not parse 'improper types' line " error->all(FLERR,"Could not parse 'improper types' line in data file header");
"in data file header");
if (addflag == NONE) if (addflag == NONE)
atom->nimpropertypes = nimpropertypes + extra_improper_types; atom->nimpropertypes = nimpropertypes + extra_improper_types;
@ -1658,12 +1654,12 @@ void ReadData::bonus(bigint nbonus, AtomVec *ptr, const char *type)
read all body data read all body data
variable amount of info per body, described by ninteger and ndouble variable amount of info per body, described by ninteger and ndouble
to find atoms, must build atom map if not a molecular system to find atoms, must build atom map if not a molecular system
if not firstpass, just read past data, but no processing of data if not firstpass, just read past body data and only process body header
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
void ReadData::bodies(int firstpass, AtomVec *ptr) void ReadData::bodies(int firstpass, AtomVec *ptr)
{ {
int m,nchunk,nline,nmax,ninteger,ndouble,nword,ncount,onebody,tmp,rv; int m,nchunk,nline,nmax,ninteger,ndouble,nword,ncount,onebody;
char *eof; char *eof;
int mapflag = 0; int mapflag = 0;
@ -1677,11 +1673,11 @@ void ReadData::bodies(int firstpass, AtomVec *ptr)
// nchunk = actual # read // nchunk = actual # read
bigint nread = 0; bigint nread = 0;
bigint natoms = nbodies; bigint nblocks = nbodies;
while (nread < natoms) { while (nread < nblocks) {
if (natoms-nread > CHUNK) nmax = CHUNK; if (nblocks-nread > CHUNK) nmax = CHUNK;
else nmax = natoms-nread; else nmax = nblocks-nread;
if (me == 0) { if (me == 0) {
nchunk = 0; nchunk = 0;
@ -1690,11 +1686,25 @@ void ReadData::bodies(int firstpass, AtomVec *ptr)
while (nchunk < nmax && nline <= CHUNK-MAXBODY) { while (nchunk < nmax && nline <= CHUNK-MAXBODY) {
eof = utils::fgets_trunc(&buffer[m],MAXLINE,fp); eof = utils::fgets_trunc(&buffer[m],MAXLINE,fp);
const char *buf = &buffer[m];
if (eof == nullptr) error->one(FLERR,"Unexpected end of data file"); if (eof == nullptr) error->one(FLERR,"Unexpected end of data file");
rv = sscanf(&buffer[m],"%d %d %d",&tmp,&ninteger,&ndouble); try {
if (rv != 3) auto values = ValueTokenizer(utils::trim_comment(buf));
error->one(FLERR,"Incorrect format in Bodies section of data file"); tagint tagdata = values.next_tagint() + id_offset;
m += strlen(&buffer[m]); ninteger = values.next_int();
ndouble = values.next_double();
if (tagdata <= 0 || tagdata > atom->map_tag_max)
throw TokenizerException("Invalid atom ID in body header", utils::trim(buf));
if (ninteger < 0)
throw TokenizerException("Invalid number of integers", utils::trim(buf));
if (ndouble < 0)
throw TokenizerException("Invalid number of doubles", utils::trim(buf));
if (values.has_next())
throw TokenizerException("Too many tokens in body header", utils::trim(buf));
} catch (TokenizerException &e) {
error->one(FLERR,std::string(e.what()) + " while reading Bodies section of data file");
}
m += strlen(buf);
// read lines one at a time into buffer and count words // read lines one at a time into buffer and count words
// count to ninteger and ndouble until have enough lines // count to ninteger and ndouble until have enough lines
@ -1754,7 +1764,7 @@ void ReadData::bodies(int firstpass, AtomVec *ptr)
} }
if (me == 0 && firstpass) if (me == 0 && firstpass)
utils::logmesg(lmp," {} bodies\n",natoms); utils::logmesg(lmp," {} bodies\n",nblocks);
} }
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */

View File

@ -298,12 +298,9 @@ std::string utils::check_packages_for_style(const std::string &style, const std:
called by various commands to check validity of their arguments called by various commands to check validity of their arguments
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int utils::logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) int utils::logical(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
{ {
int n = 0; if (str.empty()) {
if (str) n = strlen(str);
if (n == 0) {
const char msg[] = "Expected boolean parameter instead of NULL or empty string " const char msg[] = "Expected boolean parameter instead of NULL or empty string "
"in input script or data file"; "in input script or data file";
if (do_abort) if (do_abort)
@ -332,18 +329,28 @@ int utils::logical(const char *file, int line, const char *str, bool do_abort, L
return rv; return rv;
} }
/* ----------------------------------------------------------------------
wrapper for logical() that accepts a char pointer instead of a string
------------------------------------------------------------------------- */
int utils::logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
{
if (str)
return logical(file, line, std::string(str), do_abort, lmp);
else
return logical(file, line, std::string(""), do_abort, lmp);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
read a floating point value from a string read a floating point value from a string
generate an error if not a legitimate floating point value generate an error if not a legitimate floating point value
called by various commands to check validity of their arguments called by various commands to check validity of their arguments
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
double utils::numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) double utils::numeric(const char *file, int line, const std::string &str, bool do_abort,
LAMMPS *lmp)
{ {
int n = 0; if (str.empty()) {
if (str) n = strlen(str);
if (n == 0) {
const char msg[] = "Expected floating point parameter instead of" const char msg[] = "Expected floating point parameter instead of"
" NULL or empty string in input script or data file"; " NULL or empty string in input script or data file";
if (do_abort) if (do_abort)
@ -367,18 +374,27 @@ double utils::numeric(const char *file, int line, const char *str, bool do_abort
return atof(buf.c_str()); return atof(buf.c_str());
} }
/* ----------------------------------------------------------------------
wrapper for numeric() that accepts a char pointer instead of a string
------------------------------------------------------------------------- */
double utils::numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
{
if (str)
return numeric(file, line, std::string(str), do_abort, lmp);
else
return numeric(file, line, std::string(""), do_abort, lmp);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
read an integer value from a string read an integer value from a string
generate an error if not a legitimate integer value generate an error if not a legitimate integer value
called by various commands to check validity of their arguments called by various commands to check validity of their arguments
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
int utils::inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) int utils::inumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp)
{ {
int n = 0; if (str.empty()) {
if (str) n = strlen(str);
if (n == 0) {
const char msg[] = "Expected integer parameter instead of" const char msg[] = "Expected integer parameter instead of"
" NULL or empty string in input script or data file"; " NULL or empty string in input script or data file";
if (do_abort) if (do_abort)
@ -402,18 +418,28 @@ int utils::inumeric(const char *file, int line, const char *str, bool do_abort,
return atoi(buf.c_str()); return atoi(buf.c_str());
} }
/* ----------------------------------------------------------------------
wrapper for inumeric() that accepts a char pointer instead of a string
------------------------------------------------------------------------- */
int utils::inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
{
if (str)
return inumeric(file, line, std::string(str), do_abort, lmp);
else
return inumeric(file, line, std::string(""), do_abort, lmp);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
read a big integer value from a string read a big integer value from a string
generate an error if not a legitimate integer value generate an error if not a legitimate integer value
called by various commands to check validity of their arguments called by various commands to check validity of their arguments
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
bigint utils::bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) bigint utils::bnumeric(const char *file, int line, const std::string &str, bool do_abort,
LAMMPS *lmp)
{ {
int n = 0; if (str.empty()) {
if (str) n = strlen(str);
if (n == 0) {
const char msg[] = "Expected integer parameter instead of" const char msg[] = "Expected integer parameter instead of"
" NULL or empty string in input script or data file"; " NULL or empty string in input script or data file";
if (do_abort) if (do_abort)
@ -437,18 +463,28 @@ bigint utils::bnumeric(const char *file, int line, const char *str, bool do_abor
return ATOBIGINT(buf.c_str()); return ATOBIGINT(buf.c_str());
} }
/* ----------------------------------------------------------------------
wrapper for bnumeric() that accepts a char pointer instead of a string
------------------------------------------------------------------------- */
bigint utils::bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
{
if (str)
return bnumeric(file, line, std::string(str), do_abort, lmp);
else
return bnumeric(file, line, std::string(""), do_abort, lmp);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
read a tag integer value from a string read a tag integer value from a string
generate an error if not a legitimate integer value generate an error if not a legitimate integer value
called by various commands to check validity of their arguments called by various commands to check validity of their arguments
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
tagint utils::tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp) tagint utils::tnumeric(const char *file, int line, const std::string &str, bool do_abort,
LAMMPS *lmp)
{ {
int n = 0; if (str.empty()) {
if (str) n = strlen(str);
if (n == 0) {
const char msg[] = "Expected integer parameter instead of" const char msg[] = "Expected integer parameter instead of"
" NULL or empty string in input script or data file"; " NULL or empty string in input script or data file";
if (do_abort) if (do_abort)
@ -472,6 +508,18 @@ tagint utils::tnumeric(const char *file, int line, const char *str, bool do_abor
return ATOTAGINT(buf.c_str()); return ATOTAGINT(buf.c_str());
} }
/* ----------------------------------------------------------------------
wrapper for tnumeric() that accepts a char pointer instead of a string
------------------------------------------------------------------------- */
tagint utils::tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp)
{
if (str)
return tnumeric(file, line, std::string(str), do_abort, lmp);
else
return tnumeric(file, line, std::string(""), do_abort, lmp);
}
/* ---------------------------------------------------------------------- /* ----------------------------------------------------------------------
compute bounds implied by numeric str with a possible wildcard asterisk compute bounds implied by numeric str with a possible wildcard asterisk
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */

View File

@ -169,6 +169,17 @@ namespace utils {
* \param lmp pointer to top-level LAMMPS class instance * \param lmp pointer to top-level LAMMPS class instance
* \return 1 if string resolves to "true", otherwise 0 */ * \return 1 if string resolves to "true", otherwise 0 */
int logical(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp);
/*! \overload
*
* \param file name of source file for error message
* \param line line number in source file for error message
* \param str string to be converted to logical
* \param do_abort determines whether to call Error::one() or Error::all()
* \param lmp pointer to top-level LAMMPS class instance
* \return 1 if string resolves to "true", otherwise 0 */
int logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp); int logical(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp);
/*! Convert a string to a floating point number while checking /*! Convert a string to a floating point number while checking
@ -181,6 +192,17 @@ namespace utils {
* \param lmp pointer to top-level LAMMPS class instance * \param lmp pointer to top-level LAMMPS class instance
* \return double precision floating point number */ * \return double precision floating point number */
double numeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp);
/*! \overload
*
* \param file name of source file for error message
* \param line line number in source file for error message
* \param str string to be converted to number
* \param do_abort determines whether to call Error::one() or Error::all()
* \param lmp pointer to top-level LAMMPS class instance
* \return double precision floating point number */
double numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp); double numeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp);
/*! Convert a string to an integer number while checking /*! Convert a string to an integer number while checking
@ -193,6 +215,17 @@ namespace utils {
* \param lmp pointer to top-level LAMMPS class instance * \param lmp pointer to top-level LAMMPS class instance
* \return integer number (regular int) */ * \return integer number (regular int) */
int inumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp);
/*! \overload
*
* \param file name of source file for error message
* \param line line number in source file for error message
* \param str string to be converted to number
* \param do_abort determines whether to call Error::one() or Error::all()
* \param lmp pointer to top-level LAMMPS class instance
* \return double precision floating point number */
int inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp); int inumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp);
/*! Convert a string to an integer number while checking /*! Convert a string to an integer number while checking
@ -205,6 +238,17 @@ namespace utils {
* \param lmp pointer to top-level LAMMPS class instance * \param lmp pointer to top-level LAMMPS class instance
* \return integer number (bigint) */ * \return integer number (bigint) */
bigint bnumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp);
/*! \overload
*
* \param file name of source file for error message
* \param line line number in source file for error message
* \param str string to be converted to number
* \param do_abort determines whether to call Error::one() or Error::all()
* \param lmp pointer to top-level LAMMPS class instance
* \return double precision floating point number */
bigint bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp); bigint bnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp);
/*! Convert a string to an integer number while checking /*! Convert a string to an integer number while checking
@ -217,6 +261,17 @@ namespace utils {
* \param lmp pointer to top-level LAMMPS class instance * \param lmp pointer to top-level LAMMPS class instance
* \return integer number (tagint) */ * \return integer number (tagint) */
tagint tnumeric(const char *file, int line, const std::string &str, bool do_abort, LAMMPS *lmp);
/*! \overload
*
* \param file name of source file for error message
* \param line line number in source file for error message
* \param str string to be converted to number
* \param do_abort determines whether to call Error::one() or Error::all()
* \param lmp pointer to top-level LAMMPS class instance
* \return double precision floating point number */
tagint tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp); tagint tnumeric(const char *file, int line, const char *str, bool do_abort, LAMMPS *lmp);
/*! Compute index bounds derived from a string with a possible wildcard /*! Compute index bounds derived from a string with a possible wildcard

View File

@ -49,6 +49,15 @@ TEST_F(InputConvertTest, logical)
EXPECT_EQ(utils::logical(FLERR, "off", false, lmp), 0); EXPECT_EQ(utils::logical(FLERR, "off", false, lmp), 0);
EXPECT_EQ(utils::logical(FLERR, "0", false, lmp), 0); EXPECT_EQ(utils::logical(FLERR, "0", false, lmp), 0);
EXPECT_EQ(utils::logical(FLERR, std::string("yes"), false, lmp), 1);
EXPECT_EQ(utils::logical(FLERR, std::string("true"), false, lmp), 1);
EXPECT_EQ(utils::logical(FLERR, std::string("on"), false, lmp), 1);
EXPECT_EQ(utils::logical(FLERR, std::string("1"), false, lmp), 1);
EXPECT_EQ(utils::logical(FLERR, std::string("no"), false, lmp), 0);
EXPECT_EQ(utils::logical(FLERR, std::string("false"), false, lmp), 0);
EXPECT_EQ(utils::logical(FLERR, std::string("off"), false, lmp), 0);
EXPECT_EQ(utils::logical(FLERR, std::string("0"), false, lmp), 0);
TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*", TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*",
utils::logical(FLERR, "YES", false, lmp);); utils::logical(FLERR, "YES", false, lmp););
TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*", TEST_FAILURE(".*ERROR: Expected boolean parameter instead of.*",
@ -94,6 +103,15 @@ TEST_F(InputConvertTest, numeric)
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "10000000000", false, lmp), 1e10); EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "10000000000", false, lmp), 1e10);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "2.56E+3", false, lmp), 2560); EXPECT_DOUBLE_EQ(utils::numeric(FLERR, "2.56E+3", false, lmp), 2560);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("0"), false, lmp), 0);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("0.1"), false, lmp), 0.1);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("-.232"), false, lmp), -0.232);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string(".2e5"), false, lmp), 20000.0);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("2.5e-10"), false, lmp), 2.5e-10);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("+0.3"), false, lmp), 0.3);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("10000000000"), false, lmp), 1e10);
EXPECT_DOUBLE_EQ(utils::numeric(FLERR, std::string("2.56E+3"), false, lmp), 2560);
TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "yay", false, lmp);); TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "yay", false, lmp););
TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "", false, lmp);); TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, "", false, lmp););
TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, nullptr, false, lmp);); TEST_FAILURE(".*ERROR: Expected floating point.*", utils::numeric(FLERR, nullptr, false, lmp););
@ -110,6 +128,13 @@ TEST_F(InputConvertTest, inumeric)
EXPECT_EQ(utils::inumeric(FLERR, "-0", false, lmp), 0); EXPECT_EQ(utils::inumeric(FLERR, "-0", false, lmp), 0);
EXPECT_EQ(utils::inumeric(FLERR, "0100", false, lmp), 100); EXPECT_EQ(utils::inumeric(FLERR, "0100", false, lmp), 100);
EXPECT_EQ(utils::inumeric(FLERR, std::string("0"), false, lmp), 0);
EXPECT_EQ(utils::inumeric(FLERR, std::string("-1"), false, lmp), -1);
EXPECT_EQ(utils::inumeric(FLERR, std::string("10000"), false, lmp), 10000);
EXPECT_EQ(utils::inumeric(FLERR, std::string("-532410"), false, lmp), -532410);
EXPECT_EQ(utils::inumeric(FLERR, std::string("-0"), false, lmp), 0);
EXPECT_EQ(utils::inumeric(FLERR, std::string("0100"), false, lmp), 100);
TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "yay", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "yay", false, lmp););
TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "0.1", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "0.1", false, lmp););
TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "1.1", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::inumeric(FLERR, "1.1", false, lmp););
@ -128,6 +153,13 @@ TEST_F(InputConvertTest, bnumeric)
EXPECT_EQ(utils::bnumeric(FLERR, "-0", false, lmp), 0); EXPECT_EQ(utils::bnumeric(FLERR, "-0", false, lmp), 0);
EXPECT_EQ(utils::bnumeric(FLERR, "0100", false, lmp), 100); EXPECT_EQ(utils::bnumeric(FLERR, "0100", false, lmp), 100);
EXPECT_EQ(utils::bnumeric(FLERR, std::string("0"), false, lmp), 0);
EXPECT_EQ(utils::bnumeric(FLERR, std::string("-1"), false, lmp), -1);
EXPECT_EQ(utils::bnumeric(FLERR, std::string("10000"), false, lmp), 10000);
EXPECT_EQ(utils::bnumeric(FLERR, std::string("-532410"), false, lmp), -532410);
EXPECT_EQ(utils::bnumeric(FLERR, std::string("-0"), false, lmp), 0);
EXPECT_EQ(utils::bnumeric(FLERR, std::string("0100"), false, lmp), 100);
TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "yay", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "yay", false, lmp););
TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "0.1", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "0.1", false, lmp););
TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "1.1", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::bnumeric(FLERR, "1.1", false, lmp););
@ -146,6 +178,13 @@ TEST_F(InputConvertTest, tnumeric)
EXPECT_EQ(utils::tnumeric(FLERR, "-0", false, lmp), 0); EXPECT_EQ(utils::tnumeric(FLERR, "-0", false, lmp), 0);
EXPECT_EQ(utils::tnumeric(FLERR, "0100", false, lmp), 100); EXPECT_EQ(utils::tnumeric(FLERR, "0100", false, lmp), 100);
EXPECT_EQ(utils::tnumeric(FLERR, std::string("0"), false, lmp), 0);
EXPECT_EQ(utils::tnumeric(FLERR, std::string("-1"), false, lmp), -1);
EXPECT_EQ(utils::tnumeric(FLERR, std::string("10000"), false, lmp), 10000);
EXPECT_EQ(utils::tnumeric(FLERR, std::string("-532410"), false, lmp), -532410);
EXPECT_EQ(utils::tnumeric(FLERR, std::string("-0"), false, lmp), 0);
EXPECT_EQ(utils::tnumeric(FLERR, std::string("0100"), false, lmp), 100);
TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "yay", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "yay", false, lmp););
TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "0.1", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "0.1", false, lmp););
TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "1.1", false, lmp);); TEST_FAILURE(".*ERROR: Expected integer.*", utils::tnumeric(FLERR, "1.1", false, lmp););