diff --git a/doc/lammps.1 b/doc/lammps.1 index 9351ba5636..6ce463bfba 100644 --- a/doc/lammps.1 +++ b/doc/lammps.1 @@ -1,4 +1,4 @@ -.TH LAMMPS "10 February 2021" "2021-02-10" +.TH LAMMPS "10 March 2021" "2021-03-10" .SH NAME .B LAMMPS \- Molecular Dynamics Simulator. diff --git a/doc/src/pair_snap.rst b/doc/src/pair_snap.rst index a99331345e..22dea8e2fc 100644 --- a/doc/src/pair_snap.rst +++ b/doc/src/pair_snap.rst @@ -88,9 +88,12 @@ that will be used with other potentials. The name of the SNAP coefficient file usually ends in the ".snapcoeff" extension. It may contain coefficients -for many SNAP elements. The only requirement is that it -contain at least those element names appearing in the -LAMMPS mapping list. +for many SNAP elements. The only requirement is that +each of the unique element names appearing in the +LAMMPS pair_coeff command appear exactly once in +the SNAP coefficient file. It is okay if the SNAP coefficient file +contains additional elements not in the pair_coeff command, +except when using *chemflag* (see below). The name of the SNAP parameter file usually ends in the ".snapparam" extension. It contains a small number of parameters that define the overall form of the SNAP potential. @@ -129,7 +132,7 @@ line must contain two integers: This is followed by one block for each of the *nelem* elements. The first line of each block contains three entries: -* Element symbol (text string) +* Element name (text string) * R = Element radius (distance units) * w = Element weight (dimensionless) @@ -166,8 +169,8 @@ where :math:`\mathbf{B}_i` is the *K*-vector of bispectrum components, :math:`\boldsymbol{\beta}^{\mu_i}` is the *K*-vector of linear coefficients for element :math:`\mu_i`, and :math:`\boldsymbol{\alpha}^{\mu_i}` is the symmetric *K* by *K* matrix of quadratic coefficients. -The SNAP element file should contain *K*\ (\ *K*\ +1)/2 additional coefficients -for each element, the upper-triangular elements of :math:`\boldsymbol{\alpha}^{\mu_i}`. +The SNAP coefficient file should contain *K*\ (\ *K*\ +1)/2 additional coefficients +in each element block, the upper-triangular elements of :math:`\boldsymbol{\alpha}^{\mu_i}`. If *chemflag* is set to 1, then the energy expression is written in terms of explicit multi-element bispectrum components indexed on ordered triplets of elements, which has been shown to increase the ability of the SNAP @@ -181,8 +184,12 @@ at the expense of a significant increase in computational cost :ref:`(Cusentino) where :math:`\mathbf{B}^{\kappa\lambda\mu}_i` is the *K*-vector of bispectrum components for neighbors of elements :math:`\kappa`, :math:`\lambda`, and :math:`\mu` and :math:`\boldsymbol{\beta}^{\kappa\lambda\mu}_{\mu_i}` is the corresponding *K*-vector -of linear coefficients for element :math:`\mu_i`. The SNAP element file should contain -a total of :math:`K N_{elem}^3` coefficients for each of the :math:`N_{elem}` elements. +of linear coefficients for element :math:`\mu_i`. The SNAP coefficient file should contain +a total of :math:`K N_{elem}^3` coefficients in each element block, +where :math:`N_{elem}` is the number of elements in the SNAP coefficient file, +which must equal the number of unique elements appearing in the +LAMMPS pair_coeff command, to avoid ambiguity in the +number of coefficients. The keyword *chunksize* is only applicable when using the pair style *snap* with the KOKKOS package and is ignored otherwise. diff --git a/src/KIM/kim_init.cpp b/src/KIM/kim_init.cpp index 2eb5fcde48..2703ce24e0 100644 --- a/src/KIM/kim_init.cpp +++ b/src/KIM/kim_init.cpp @@ -108,7 +108,7 @@ void KimInit::command(int narg, char **arg) determine_model_type_and_units(model_name, user_units, &model_units, pkim); - write_log_cite(model_name); + write_log_cite(lmp, model_type, model_name); do_init(model_name, user_units, model_units, pkim); } @@ -488,7 +488,9 @@ void KimInit::do_variables(const std::string &from, const std::string &to) /* ---------------------------------------------------------------------- */ -void KimInit::write_log_cite(char *model_name) +void KimInit::write_log_cite(class LAMMPS *lmp, + KimInit::model_type_enum model_type, + char *model_name) { if (!lmp->citeme) return; @@ -496,50 +498,52 @@ void KimInit::write_log_cite(char *model_name) std::string re = "[MS][OM]_\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d\\d_\\d\\d\\d"; std::string kim_id = utils::strfind(model_name_str, re); - if (kim_id.empty()) return; - - KIM_Collections *collections; - int err = KIM_Collections_Create(&collections); - if (err) return; - - auto logID = fmt::format("{}_Collections", comm->me); - KIM_Collections_SetLogID(collections, logID.c_str()); - - int extent; - if (model_type == MO) { - err = KIM_Collections_CacheListOfItemMetadataFiles( - collections, KIM_COLLECTION_ITEM_TYPE_portableModel, - model_name, &extent); - } else if (model_type == SM) { - err = KIM_Collections_CacheListOfItemMetadataFiles( - collections, KIM_COLLECTION_ITEM_TYPE_simulatorModel, - model_name, &extent); + std::string cite_id; + if (kim_id.empty()) { + cite_id = fmt::format("KIM potential: unpublished, \"{}\"\n",model_name_str); } else { - error->all(FLERR, "Unknown model type"); - } + KIM_Collections *collections; + int err = KIM_Collections_Create(&collections); + if (err) return; - if (err) { + auto logID = fmt::format("{}_Collections", lmp->comm->me); + KIM_Collections_SetLogID(collections, logID.c_str()); + + int extent; + if (model_type == MO) { + err = KIM_Collections_CacheListOfItemMetadataFiles( + collections, KIM_COLLECTION_ITEM_TYPE_portableModel, + model_name, &extent); + } else if (model_type == SM) { + err = KIM_Collections_CacheListOfItemMetadataFiles( + collections, KIM_COLLECTION_ITEM_TYPE_simulatorModel, + model_name, &extent); + } else { + lmp->error->all(FLERR, "Unknown model type"); + } + + if (err) { + KIM_Collections_Destroy(&collections); + return; + } + + cite_id = fmt::format("OpenKIM potential: https://openkim.org/cite/" + "{}#item-citation\n\n",kim_id); + + for (int i = 0; i < extent; ++i) { + char const *fileName; + int availableAsString; + char const *fileString; + err = KIM_Collections_GetItemMetadataFile( + collections, i, &fileName, nullptr, nullptr, + &availableAsString, &fileString); + if (err) continue; + + if (utils::strmatch(fileName, "^kimcite") && availableAsString) + cite_id += fileString; + } KIM_Collections_Destroy(&collections); - return; - } - - auto cite_id = fmt::format("OpenKIM potential: https://openkim.org/cite/" - "{}#item-citation\n\n",kim_id); - - for (int i = 0; i < extent; ++i) { - char const *fileName; - int availableAsString; - char const *fileString; - err = KIM_Collections_GetItemMetadataFile( - collections, i, &fileName, nullptr, nullptr, - &availableAsString, &fileString); - if (err) continue; - - if (utils::strmatch(fileName, "^kimcite") && availableAsString) - cite_id += fileString; } lmp->citeme->add(cite_id); - - KIM_Collections_Destroy(&collections); } diff --git a/src/KIM/kim_init.h b/src/KIM/kim_init.h index 6937ab7677..a345340dc9 100644 --- a/src/KIM/kim_init.h +++ b/src/KIM/kim_init.h @@ -70,13 +70,13 @@ class KimInit : protected Pointers { public: KimInit(class LAMMPS *lmp) : Pointers(lmp) {}; void command(int, char **); - private: enum model_type_enum {MO, SM}; + static void write_log_cite(class LAMMPS *, model_type_enum, char *); + private: model_type_enum model_type; bool unit_conversion_mode; void determine_model_type_and_units(char *, char *, char **, KIM_Model *&); - void write_log_cite(char *); void do_init(char *, char *, char *, KIM_Model *&); void do_variables(const std::string &, const std::string &); }; diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index ccdf25116c..1b709a65c2 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -55,6 +55,7 @@ Designed for use with the kim-api-2.0.2 (and newer) package ------------------------------------------------------------------------- */ #include "pair_kim.h" +#include "kim_init.h" #include "atom.h" #include "citeme.h" @@ -336,6 +337,9 @@ void PairKIM::settings(int narg, char **arg) // initialize KIM Model kim_init(); + + // add citation + KimInit::write_log_cite(lmp, KimInit::MO, kim_modelname); } /* ---------------------------------------------------------------------- diff --git a/src/MLIAP/mliap_model_nn.cpp b/src/MLIAP/mliap_model_nn.cpp index c66b52ae65..158d2240c2 100644 --- a/src/MLIAP/mliap_model_nn.cpp +++ b/src/MLIAP/mliap_model_nn.cpp @@ -356,9 +356,9 @@ void MLIAPModelNN::compute_gradients(MLIAPData* data) delete bnodes[n]; } - delete nodes; - delete dnodes; - delete bnodes; + delete[] nodes; + delete[] dnodes; + delete[] bnodes; } } diff --git a/src/SNAP/pair_snap.cpp b/src/SNAP/pair_snap.cpp index 8673dd09af..7d57ca3673 100644 --- a/src/SNAP/pair_snap.cpp +++ b/src/SNAP/pair_snap.cpp @@ -13,19 +13,19 @@ #include "pair_snap.h" -#include - -#include #include "atom.h" -#include "force.h" #include "comm.h" -#include "neighbor.h" +#include "error.h" +#include "force.h" +#include "memory.h" #include "neigh_list.h" #include "neigh_request.h" +#include "neighbor.h" #include "sna.h" -#include "memory.h" -#include "error.h" +#include "tokenizer.h" +#include +#include using namespace LAMMPS_NS; @@ -381,17 +381,8 @@ void PairSNAP::settings(int narg, char ** /* arg */) void PairSNAP::coeff(int narg, char **arg) { - if (narg < 5) error->all(FLERR,"Incorrect args for pair coefficients"); if (!allocated) allocate(); - - if (nelements) { - for (int i = 0; i < nelements; i++) - delete[] elements[i]; - delete[] elements; - memory->destroy(radelem); - memory->destroy(wjelem); - memory->destroy(coeffelem); - } + if (narg != 4 + atom->ntypes) error->all(FLERR,"Incorrect args for pair coefficients"); char* type1 = arg[0]; char* type2 = arg[1]; @@ -404,6 +395,47 @@ void PairSNAP::coeff(int narg, char **arg) if (strcmp(type1,"*") != 0 || strcmp(type2,"*") != 0) error->all(FLERR,"Incorrect args for pair coefficients"); + // clean out old arrays + + if (elements) { + for (int i = 0; i < nelements; i++) + delete[] elements[i]; + delete[] elements; + memory->destroy(radelem); + memory->destroy(wjelem); + memory->destroy(coeffelem); + } + + // nelements = # of unique elements declared + // elements = list of unique element names + // allocate as ntypes >= nelements + + elements = new char*[atom->ntypes]; + for (int i = 0; i < atom->ntypes; i++) elements[i] = nullptr; + + // read args that map atom types to SNAP elements + // map[i] = which element the Ith atom type is, -1 if not mapped + // map[0] is not used + + nelements = 0; + for (int i = 1; i <= atom->ntypes; i++) { + char* elemstring = elemtypes[i-1]; + if (strcmp(elemstring,"NULL") == 0) { + map[i] = -1; + continue; + } + int j; + for (j = 0; j < nelements; j++) + if (strcmp(elemstring,elements[j]) == 0) break; + map[i] = j; + if (j == nelements) { + int n = strlen(elemstring) + 1; + elements[j] = new char[n]; + strcpy(elements[j],elemstring); + nelements++; + } + } + // read snapcoeff and snapparam files read_files(coefffilename,paramfilename); @@ -423,23 +455,6 @@ void PairSNAP::coeff(int narg, char **arg) } } - // read args that map atom types to SNAP elements - // map[i] = which element the Ith atom type is, -1 if not mapped - // map[0] is not used - - for (int i = 1; i <= atom->ntypes; i++) { - char* elemname = elemtypes[i-1]; - int jelem; - for (jelem = 0; jelem < nelements; jelem++) - if (strcmp(elemname,elements[jelem]) == 0) - break; - - if (jelem < nelements) - map[i] = jelem; - else if (strcmp(elemname,"NULL") == 0) map[i] = -1; - else error->all(FLERR,"Incorrect args for pair coefficients"); - } - // clear setflag since coeff() called once with I,J = * * int n = atom->ntypes; @@ -517,17 +532,13 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename) FILE *fpcoeff; if (comm->me == 0) { fpcoeff = utils::open_potential(coefffilename,lmp,nullptr); - if (fpcoeff == nullptr) { - char str[128]; - snprintf(str,128,"Cannot open SNAP coefficient file %s",coefffilename); - error->one(FLERR,str); - } + if (fpcoeff == nullptr) + error->one(FLERR,fmt::format("Cannot open SNAP coefficient file {}: ", + coefffilename, utils::getsyserror())); } char line[MAXLINE],*ptr; int eof = 0; - - int n; int nwords = 0; while (nwords == 0) { if (comm->me == 0) { @@ -535,113 +546,137 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename) if (ptr == nullptr) { eof = 1; fclose(fpcoeff); - } else n = strlen(line) + 1; + } } MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + MPI_Bcast(line,MAXLINE,MPI_CHAR,0,world); // strip comment, skip line if blank - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); + nwords = utils::count_words(utils::trim_comment(line)); } if (nwords != 2) error->all(FLERR,"Incorrect format in SNAP coefficient file"); - // words = ptrs to all words in line // strip single and double quotes from words - char* words[MAXWORD]; - int iword = 0; - words[iword] = strtok(line,"' \t\n\r\f"); - iword = 1; - words[iword] = strtok(nullptr,"' \t\n\r\f"); - - nelements = atoi(words[0]); - ncoeffall = atoi(words[1]); + int nelemtmp = 0; + try { + ValueTokenizer words(utils::trim_comment(line),"\"' \t\n\r\f"); + nelemtmp = words.next_int(); + ncoeffall = words.next_int(); + } catch (TokenizerException &e) { + error->all(FLERR,fmt::format("Incorrect format in SNAP coefficient " + "file: {}", e.what())); + } // set up element lists - elements = new char*[nelements]; memory->create(radelem,nelements,"pair:radelem"); memory->create(wjelem,nelements,"pair:wjelem"); memory->create(coeffelem,nelements,ncoeffall,"pair:coeffelem"); - // Loop over nelements blocks in the SNAP coefficient file + // initialize checklist for all required nelements - for (int ielem = 0; ielem < nelements; ielem++) { + int elementflags[nelements]; + for (int jelem = 0; jelem < nelements; jelem++) + elementflags[jelem] = 0; + + // loop over nelemtmp blocks in the SNAP coefficient file + + for (int ielem = 0; ielem < nelemtmp; ielem++) { if (comm->me == 0) { ptr = fgets(line,MAXLINE,fpcoeff); if (ptr == nullptr) { eof = 1; fclose(fpcoeff); - } else n = strlen(line) + 1; + } } MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) error->all(FLERR,"Incorrect format in SNAP coefficient file"); - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + MPI_Bcast(line,MAXLINE,MPI_CHAR,0,world); - nwords = utils::trim_and_count_words(line); - if (nwords != 3) + std::vector words; + try { + words = Tokenizer(utils::trim_comment(line),"\"' \t\n\r\f").as_vector(); + } catch (TokenizerException &e) { + // ignore + } + if (words.size() != 3) error->all(FLERR,"Incorrect format in SNAP coefficient file"); - iword = 0; - words[iword] = strtok(line,"' \t\n\r\f"); - iword = 1; - words[iword] = strtok(nullptr,"' \t\n\r\f"); - iword = 2; - words[iword] = strtok(nullptr,"' \t\n\r\f"); + int jelem; + for (jelem = 0; jelem < nelements; jelem++) + if (words[0] == elements[jelem]) break; - char* elemtmp = words[0]; - int n = strlen(elemtmp) + 1; - elements[ielem] = new char[n]; - strcpy(elements[ielem],elemtmp); + // if this element not needed, skip this block - radelem[ielem] = atof(words[1]); - wjelem[ielem] = atof(words[2]); - - - if (comm->me == 0) { - if (screen) fprintf(screen,"SNAP Element = %s, Radius %g, Weight %g \n", - elements[ielem], radelem[ielem], wjelem[ielem]); - if (logfile) fprintf(logfile,"SNAP Element = %s, Radius %g, Weight %g \n", - elements[ielem], radelem[ielem], wjelem[ielem]); + if (jelem == nelements) { + if (comm->me == 0) { + for (int icoeff = 0; icoeff < ncoeffall; icoeff++) { + ptr = fgets(line,MAXLINE,fpcoeff); + if (ptr == nullptr) { + eof = 1; + fclose(fpcoeff); + } + } + } + MPI_Bcast(&eof,1,MPI_INT,0,world); + if (eof) + error->all(FLERR,"Incorrect format in SNAP coefficient file"); + continue; } + if (elementflags[jelem] == 1) + error->all(FLERR,"Incorrect format in SNAP coefficient file"); + else + elementflags[jelem] = 1; + + radelem[jelem] = utils::numeric(FLERR,words[1].c_str(),false,lmp); + wjelem[jelem] = utils::numeric(FLERR,words[2].c_str(),false,lmp); + + if (comm->me == 0) + utils::logmesg(lmp,fmt::format("SNAP Element = {}, Radius {}, Weight {}\n", + elements[jelem], radelem[jelem], wjelem[jelem])); + for (int icoeff = 0; icoeff < ncoeffall; icoeff++) { if (comm->me == 0) { ptr = fgets(line,MAXLINE,fpcoeff); if (ptr == nullptr) { eof = 1; fclose(fpcoeff); - } else n = strlen(line) + 1; + } } MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) error->all(FLERR,"Incorrect format in SNAP coefficient file"); - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + MPI_Bcast(line,MAXLINE,MPI_CHAR,0,world); - nwords = utils::trim_and_count_words(line); - if (nwords != 1) - error->all(FLERR,"Incorrect format in SNAP coefficient file"); - - iword = 0; - words[iword] = strtok(line,"' \t\n\r\f"); - - coeffelem[ielem][icoeff] = atof(words[0]); + try { + ValueTokenizer coeff(utils::trim_comment(line)); + if (coeff.count() != 1) + error->all(FLERR,"Incorrect format in SNAP coefficient file"); + coeffelem[jelem][icoeff] = coeff.next_double(); + } catch (TokenizerException &e) { + error->all(FLERR,fmt::format("Incorrect format in SNAP coefficient " + "file: {}", e.what())); + } } } if (comm->me == 0) fclose(fpcoeff); + for (int jelem = 0; jelem < nelements; jelem++) { + if (elementflags[jelem] == 0) + error->all(FLERR,fmt::format("Element {} not found in SNAP coefficient " + "file", elements[jelem])); + } + // set flags for required keywords rcutfacflag = 0; @@ -664,11 +699,9 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename) FILE *fpparam; if (comm->me == 0) { fpparam = utils::open_potential(paramfilename,lmp,nullptr); - if (fpparam == nullptr) { - char str[128]; - snprintf(str,128,"Cannot open SNAP parameter file %s",paramfilename); - error->one(FLERR,str); - } + if (fpparam == nullptr) + error->one(FLERR,fmt::format("Cannot open SNAP parameter file {}: {}", + paramfilename, utils::getsyserror())); } eof = 0; @@ -678,64 +711,66 @@ void PairSNAP::read_files(char *coefffilename, char *paramfilename) if (ptr == nullptr) { eof = 1; fclose(fpparam); - } else n = strlen(line) + 1; + } } MPI_Bcast(&eof,1,MPI_INT,0,world); if (eof) break; - MPI_Bcast(&n,1,MPI_INT,0,world); - MPI_Bcast(line,n,MPI_CHAR,0,world); + MPI_Bcast(line,MAXLINE,MPI_CHAR,0,world); // strip comment, skip line if blank - if ((ptr = strchr(line,'#'))) *ptr = '\0'; - nwords = utils::count_words(line); - if (nwords == 0) continue; - - if (nwords != 2) - error->all(FLERR,"Incorrect format in SNAP parameter file"); - - // words = ptrs to all words in line - // strip single and double quotes from words - - char* keywd = strtok(line,"' \t\n\r\f"); - char* keyval = strtok(nullptr,"' \t\n\r\f"); - - if (comm->me == 0) { - if (screen) fprintf(screen,"SNAP keyword %s %s \n",keywd,keyval); - if (logfile) fprintf(logfile,"SNAP keyword %s %s \n",keywd,keyval); + std::vector words; + try { + words = Tokenizer(utils::trim_comment(line),"\"' \t\n\r\f").as_vector(); + } catch (TokenizerException &e) { + // ignore } - if (strcmp(keywd,"rcutfac") == 0) { - rcutfac = atof(keyval); + if (words.size() == 0) continue; + if (words.size() != 2) + error->all(FLERR,"Incorrect format in SNAP parameter file"); + + auto keywd = words[0]; + auto keyval = words[1]; + + if (comm->me == 0) + utils::logmesg(lmp,fmt::format("SNAP keyword {} {}\n",keywd,keyval)); + + if (keywd == "rcutfac") { + rcutfac = utils::numeric(FLERR,keyval.c_str(),false,lmp); rcutfacflag = 1; - } else if (strcmp(keywd,"twojmax") == 0) { - twojmax = atoi(keyval); + } else if (keywd == "twojmax") { + twojmax = utils::inumeric(FLERR,keyval.c_str(),false,lmp); twojmaxflag = 1; - } else if (strcmp(keywd,"rfac0") == 0) - rfac0 = atof(keyval); - else if (strcmp(keywd,"rmin0") == 0) - rmin0 = atof(keyval); - else if (strcmp(keywd,"switchflag") == 0) - switchflag = atoi(keyval); - else if (strcmp(keywd,"bzeroflag") == 0) - bzeroflag = atoi(keyval); - else if (strcmp(keywd,"quadraticflag") == 0) - quadraticflag = atoi(keyval); - else if (strcmp(keywd,"chemflag") == 0) - chemflag = atoi(keyval); - else if (strcmp(keywd,"bnormflag") == 0) - bnormflag = atoi(keyval); - else if (strcmp(keywd,"wselfallflag") == 0) - wselfallflag = atoi(keyval); - else if (strcmp(keywd,"chunksize") == 0) - chunksize = atoi(keyval); + } else if (keywd == "rfac0") + rfac0 = utils::numeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "rmin0") + rmin0 = utils::numeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "switchflag") + switchflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "bzeroflag") + bzeroflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "quadraticflag") + quadraticflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "chemflag") + chemflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "bnormflag") + bnormflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "wselfallflag") + wselfallflag = utils::inumeric(FLERR,keyval.c_str(),false,lmp); + else if (keywd == "chunksize") + chunksize = utils::inumeric(FLERR,keyval.c_str(),false,lmp); else - error->all(FLERR,"Incorrect SNAP parameter file"); + error->all(FLERR,fmt::format("Unknown parameter '{}' in SNAP " + "parameter file", keywd)); } if (rcutfacflag == 0 || twojmaxflag == 0) error->all(FLERR,"Incorrect SNAP parameter file"); + if (chemflag && nelemtmp != nelements) + error->all(FLERR,"Incorrect SNAP parameter file"); + } /* ---------------------------------------------------------------------- diff --git a/src/version.h b/src/version.h index 84541d4456..d16067e41c 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define LAMMPS_VERSION "10 Feb 2021" +#define LAMMPS_VERSION "10 Mar 2021"