diff --git a/doc/src/thermo_modify.rst b/doc/src/thermo_modify.rst index 4439f7732c..1563566895 100644 --- a/doc/src/thermo_modify.rst +++ b/doc/src/thermo_modify.rst @@ -11,12 +11,13 @@ Syntax thermo_modify keyword value ... * one or more keyword/value pairs may be listed -* keyword = *lost* or *lost/bond* or *norm* or *flush* or *line* or *format* or *temp* or *press* +* keyword = *lost* or *lost/bond* or *warn* or *norm* or *flush* or *line* or *format* or *temp* or *press* .. parsed-literal:: *lost* value = *error* or *warn* or *ignore* *lost/bond* value = *error* or *warn* or *ignore* + *warn* value = *ignore* or *reset* or *default* or a number *norm* value = *yes* or *no* *flush* value = *yes* or *no* *line* value = *one* or *multi* @@ -75,6 +76,23 @@ are drifting out of the box through a fixed boundary condition (see the :doc:`boundary ` command). In this case one atom may be deleted before the rest of the molecule is, on a later timestep. +The *warn* keyword determines whether LAMMPS will print warning +messages and how many of them. Certain warning messages can be +quite verbose and thus quickly blow up the size of the log file +and screen output. Thus a limit of 100 warnings messages is applied +by default. If there are more warnings, LAMMPS will print one final +warning that it will not print any additional warning messages. +Any number after the keyword *warn* will change the warning limit +accordingly. With the value *ignore* all warnings will be suppressed, +with the value *always* no limit will be applied and warnings will +always be printed, with the value *reset* the internal warning +counter will be reset to zero, and with the value *default*, all +settings will be reset to their defaults and the counter reset. +An example usage of this keyword would be that during equilibration +warnings would be ignored while the system is still adjusting, but +then one would reset everything to the defaults for the production +run. + The *norm* keyword determines whether various thermodynamic output values are normalized by the number of atoms or not, depending on whether it is set to *yes* or *no*\ . Different unit styles have diff --git a/src/error.cpp b/src/error.cpp index a6aaf5a360..e41c2886d5 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -36,7 +36,9 @@ static std::string truncpath(const std::string &path) /* ---------------------------------------------------------------------- */ -Error::Error(LAMMPS *lmp) : Pointers(lmp) { +Error::Error(LAMMPS *lmp) + : Pointers(lmp), numwarn(0), maxwarn(100), allwarn(0) +{ #ifdef LAMMPS_EXCEPTIONS last_error_message.clear(); last_error_type = ERROR_NONE; @@ -116,6 +118,7 @@ void Error::universe_one(const std::string &file, int line, const std::string &s void Error::universe_warn(const std::string &file, int line, const std::string &str) { + ++numwarn; if (universe->uscreen) fmt::print(universe->uscreen,"WARNING on proc {}: {} ({}:{})\n", universe->me,str,truncpath(file),line); @@ -246,6 +249,7 @@ void Error::_one(const std::string &file, int line, fmt::string_view format, void Error::warning(const std::string &file, int line, const std::string &str, int logflag) { + ++numwarn; std::string mesg = fmt::format("WARNING: {} ({}:{})\n", str,truncpath(file),line); if (screen) fputs(mesg.c_str(),screen); diff --git a/src/error.h b/src/error.h index 85e255f24f..09e07c5d56 100644 --- a/src/error.h +++ b/src/error.h @@ -47,6 +47,12 @@ class Error : protected Pointers { void message(const std::string &, int, const std::string &, int = 1); [[ noreturn ]] void done(int = 0); // 1 would be fully backwards compatible + int get_numwarn() const { return numwarn; } + int get_maxwarn() const { return maxwarn; } + void set_numwarn(int val) { numwarn = val; } + void set_maxwarn(int val) { maxwarn = val; } + void set_allwarn(int val) { allwarn = val; } + #ifdef LAMMPS_EXCEPTIONS std::string get_last_error() const; ErrorType get_last_error_type() const; @@ -56,6 +62,7 @@ class Error : protected Pointers { std::string last_error_message; ErrorType last_error_type; + int numwarn, maxwarn, allwarn; #endif private: // internal versions that accept explicit fmtlib arguments diff --git a/src/thermo.cpp b/src/thermo.cpp index 2229b2efbd..29a851f66c 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -92,7 +92,7 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) normuserflag = 0; lineflag = ONELINE; lostflag = lostbond = Thermo::ERROR; - lostbefore = 0; + lostbefore = warnbefore = 0; flushflag = 0; // set style and corresponding lineflag @@ -400,42 +400,56 @@ void Thermo::call_vfunc(int ifield_in) /* ---------------------------------------------------------------------- check for lost atoms, return current number of atoms + also could number of warnings across MPI ranks and update total ------------------------------------------------------------------------- */ bigint Thermo::lost_check() { - // ntotal = current # of atoms + // ntotal = current # of atoms, and Error class warnings - bigint ntotal; - bigint nblocal = atom->nlocal; - MPI_Allreduce(&nblocal,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world); - if (ntotal < 0) + bigint nlocal[2], ntotal[2] = {0,0}; + nlocal[0] = atom->nlocal; + nlocal[1] = error->get_numwarn(); + MPI_Allreduce(nlocal,ntotal,2,MPI_LMP_BIGINT,MPI_SUM,world); + if (ntotal[0] < 0) error->all(FLERR,"Too many total atoms"); - if (ntotal == atom->natoms) return ntotal; + + // print notification, if future warnings will be ignored + error->set_allwarn(ntotal[1]); + int maxwarn = error->get_maxwarn(); + if ((maxwarn > 0) && (warnbefore == 0) && (ntotal[1] > maxwarn)) { + warnbefore = 1; + error->warning(FLERR,fmt::format("Too many warnings: {} vs {}. All " + "future warnings will be suppressed.\n", + ntotal[1],maxwarn),0); + } + + // no lost atoms, nothing else to do. + if (ntotal[0] == atom->natoms) return ntotal[0]; // if not checking or already warned, just return - if (lostflag == Thermo::IGNORE) return ntotal; + if (lostflag == Thermo::IGNORE) return ntotal[0]; if (lostflag == Thermo::WARN && lostbefore == 1) { - return ntotal; + return ntotal[0]; } // error message if (lostflag == Thermo::ERROR) error->all(FLERR,"Lost atoms: original {} current {}", - atom->natoms,ntotal); + atom->natoms,ntotal[0]); // warning message if (me == 0) error->warning(FLERR,fmt::format("Lost atoms: original {} current {}", - atom->natoms,ntotal),0); + atom->natoms,ntotal[0]),0); // reset total atom count - atom->natoms = ntotal; + atom->natoms = ntotal[0]; lostbefore = 1; - return ntotal; + return ntotal[0]; } /* ---------------------------------------------------------------------- @@ -525,6 +539,20 @@ void Thermo::modify_params(int narg, char **arg) else error->all(FLERR,"Illegal thermo_modify command"); iarg += 2; + } else if (strcmp(arg[iarg],"warn") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); + if (strcmp(arg[iarg+1],"ignore") == 0) error->set_maxwarn(-1); + if (strcmp(arg[iarg+1],"always") == 0) error->set_maxwarn(0); + else if (strcmp(arg[iarg+1],"reset") == 0) { + error->set_numwarn(0); + warnbefore = 0; + } else if (strcmp(arg[iarg+1],"default") == 0) { + warnbefore = 0; + error->set_numwarn(0); + error->set_maxwarn(100); + } else error->set_maxwarn(utils::inumeric(FLERR,arg[iarg+1],false,lmp)); + iarg += 2; + } else if (strcmp(arg[iarg],"norm") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); normuserflag = 1; diff --git a/src/thermo.h b/src/thermo.h index 427266952b..a7e849ca51 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -64,7 +64,7 @@ class Thermo : protected Pointers { int normuser; int firststep; - int lostbefore; + int lostbefore, warnbefore; int flushflag,lineflag; double last_tpcpu,last_spcpu;