diff --git a/doc/src/pair_sw.rst b/doc/src/pair_sw.rst index 579e4c6f3f..dd612ac8a1 100644 --- a/doc/src/pair_sw.rst +++ b/doc/src/pair_sw.rst @@ -176,9 +176,13 @@ are placeholders for atom types that will be used with other potentials. .. note:: - When the *threebody off* keyword is used, multiple pair_coeff commands may - be used to specific the pairs of atoms which don't require three-body term. - In these cases, the first 2 arguments are not required to be \* \*. + When the *threebody off* keyword is used, multiple pair_coeff + commands may be used to specific the pairs of atoms which don't + require three-body term. In these cases, the first 2 arguments are + not required to be \* \*, the potential parameter file is only read + by the first :doc:`pair_coeff ` and the following element to + atom type mappings must be consistent across all *pair_coeff* + statements. Stillinger-Weber files in the *potentials* directory of the LAMMPS distribution have a ".sw" suffix. Lines that are not blank or diff --git a/src/MANYBODY/pair_sw.cpp b/src/MANYBODY/pair_sw.cpp index 5968c12bde..5e42c81004 100644 --- a/src/MANYBODY/pair_sw.cpp +++ b/src/MANYBODY/pair_sw.cpp @@ -46,6 +46,7 @@ PairSW::PairSW(LAMMPS *lmp) : Pair(lmp) centroidstressflag = CENTROID_NOTAVAIL; unit_convert_flag = utils::get_supported_conversions(utils::ENERGY); skip_threebody_flag = false; + params_mapped = 0; params = nullptr; @@ -225,12 +226,12 @@ void PairSW::compute(int eflag, int vflag) void PairSW::allocate() { allocated = 1; - int n = atom->ntypes; + int np1 = atom->ntypes + 1; - memory->create(setflag,n+1,n+1,"pair:setflag"); - memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(neighshort,maxshort,"pair:neighshort"); - map = new int[n+1]; + memory->create(setflag, np1, np1, "pair:setflag"); + memory->create(cutsq, np1, np1, "pair:cutsq"); + memory->create(neighshort, maxshort, "pair:neighshort"); + map = new int[np1]; } /* ---------------------------------------------------------------------- @@ -262,12 +263,39 @@ void PairSW::coeff(int narg, char **arg) { if (!allocated) allocate(); - map_element2type(narg-3,arg+3); + // read potential file and set up element maps only once + if (one_coeff || !params_mapped) { + map_element2type(narg-3, arg+3, (one_coeff != 0)); - // read potential file and initialize potential parameters + // read potential file and initialize potential parameters - read_file(arg[2]); - setup_params(); + read_file(arg[2]); + setup_params(); + params_mapped = 1; + } + + if (!one_coeff) { + int ilo, ihi, jlo, jhi; + utils::bounds(FLERR, arg[0], 1, atom->ntypes, ilo, ihi, error); + utils::bounds(FLERR, arg[1], 1, atom->ntypes, jlo, jhi, error); + + int count = 0; + for (int i = ilo; i <= ihi; i++) { + if (((map[i] >= 0) && (strcmp(arg[i+2], elements[map[i]]) != 0)) || + ((map[i] < 0) && (strcmp(arg[i+2], "NULL") != 0))) + error->all(FLERR, "Must use consistent type to element mappings with threebody off"); + if (map[i] < 0) error->all(FLERR, "Must not set pair_coeff mapped to NULL element"); + for (int j = MAX(jlo, i); j <= jhi; j++) { + if (((map[j] >= 0) && (strcmp(arg[j+2], elements[map[j]]) != 0)) || + ((map[j] < 0) && (strcmp(arg[j+2], "NULL") != 0))) + error->all(FLERR, "Must use consistent type to element mappings with threebody off"); + if (map[j] < 0) error->all(FLERR, "Must not set pair_coeff mapped to NULL element"); + setflag[i][j] = 1; + count++; + } + } + if (count == 0) error->all(FLERR, "Incorrect args for pair coefficients"); + } } /* ---------------------------------------------------------------------- diff --git a/src/MANYBODY/pair_sw.h b/src/MANYBODY/pair_sw.h index bf22ce6390..da25871040 100644 --- a/src/MANYBODY/pair_sw.h +++ b/src/MANYBODY/pair_sw.h @@ -54,6 +54,7 @@ class PairSW : public Pair { int maxshort; // size of short neighbor list array int *neighshort; // short neighbor list array int skip_threebody_flag; // whether to run threebody loop + int params_mapped; // whether parameters have been read and mapped to elements void settings(int, char **) override; virtual void allocate();