implement "thermo_modify warn" to control amount of warnings

This commit is contained in:
Axel Kohlmeyer
2021-05-03 14:21:16 -04:00
parent b4a70880d9
commit f0cc70b29a
5 changed files with 73 additions and 16 deletions

View File

@ -11,12 +11,13 @@ Syntax
thermo_modify keyword value ... thermo_modify keyword value ...
* one or more keyword/value pairs may be listed * 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:: .. parsed-literal::
*lost* value = *error* or *warn* or *ignore* *lost* value = *error* or *warn* or *ignore*
*lost/bond* 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* *norm* value = *yes* or *no*
*flush* value = *yes* or *no* *flush* value = *yes* or *no*
*line* value = *one* or *multi* *line* value = *one* or *multi*
@ -75,6 +76,23 @@ are drifting out of the box through a fixed boundary condition (see
the :doc:`boundary <boundary>` command). In this case one atom may be the :doc:`boundary <boundary>` command). In this case one atom may be
deleted before the rest of the molecule is, on a later timestep. 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 The *norm* keyword determines whether various thermodynamic output
values are normalized by the number of atoms or not, depending on values are normalized by the number of atoms or not, depending on
whether it is set to *yes* or *no*\ . Different unit styles have whether it is set to *yes* or *no*\ . Different unit styles have

View File

@ -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 #ifdef LAMMPS_EXCEPTIONS
last_error_message.clear(); last_error_message.clear();
last_error_type = ERROR_NONE; 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) void Error::universe_warn(const std::string &file, int line, const std::string &str)
{ {
++numwarn;
if (universe->uscreen) if (universe->uscreen)
fmt::print(universe->uscreen,"WARNING on proc {}: {} ({}:{})\n", fmt::print(universe->uscreen,"WARNING on proc {}: {} ({}:{})\n",
universe->me,str,truncpath(file),line); 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) void Error::warning(const std::string &file, int line, const std::string &str, int logflag)
{ {
++numwarn;
std::string mesg = fmt::format("WARNING: {} ({}:{})\n", std::string mesg = fmt::format("WARNING: {} ({}:{})\n",
str,truncpath(file),line); str,truncpath(file),line);
if (screen) fputs(mesg.c_str(),screen); if (screen) fputs(mesg.c_str(),screen);

View File

@ -47,6 +47,12 @@ class Error : protected Pointers {
void message(const std::string &, int, const std::string &, int = 1); void message(const std::string &, int, const std::string &, int = 1);
[[ noreturn ]] void done(int = 0); // 1 would be fully backwards compatible [[ 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 #ifdef LAMMPS_EXCEPTIONS
std::string get_last_error() const; std::string get_last_error() const;
ErrorType get_last_error_type() const; ErrorType get_last_error_type() const;
@ -56,6 +62,7 @@ class Error : protected Pointers {
std::string last_error_message; std::string last_error_message;
ErrorType last_error_type; ErrorType last_error_type;
int numwarn, maxwarn, allwarn;
#endif #endif
private: private:
// internal versions that accept explicit fmtlib arguments // internal versions that accept explicit fmtlib arguments

View File

@ -92,7 +92,7 @@ Thermo::Thermo(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp)
normuserflag = 0; normuserflag = 0;
lineflag = ONELINE; lineflag = ONELINE;
lostflag = lostbond = Thermo::ERROR; lostflag = lostbond = Thermo::ERROR;
lostbefore = 0; lostbefore = warnbefore = 0;
flushflag = 0; flushflag = 0;
// set style and corresponding lineflag // 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 check for lost atoms, return current number of atoms
also could number of warnings across MPI ranks and update total
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
bigint Thermo::lost_check() bigint Thermo::lost_check()
{ {
// ntotal = current # of atoms // ntotal = current # of atoms, and Error class warnings
bigint ntotal; bigint nlocal[2], ntotal[2] = {0,0};
bigint nblocal = atom->nlocal; nlocal[0] = atom->nlocal;
MPI_Allreduce(&nblocal,&ntotal,1,MPI_LMP_BIGINT,MPI_SUM,world); nlocal[1] = error->get_numwarn();
if (ntotal < 0) MPI_Allreduce(nlocal,ntotal,2,MPI_LMP_BIGINT,MPI_SUM,world);
if (ntotal[0] < 0)
error->all(FLERR,"Too many total atoms"); 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 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) { if (lostflag == Thermo::WARN && lostbefore == 1) {
return ntotal; return ntotal[0];
} }
// error message // error message
if (lostflag == Thermo::ERROR) if (lostflag == Thermo::ERROR)
error->all(FLERR,"Lost atoms: original {} current {}", error->all(FLERR,"Lost atoms: original {} current {}",
atom->natoms,ntotal); atom->natoms,ntotal[0]);
// warning message // warning message
if (me == 0) if (me == 0)
error->warning(FLERR,fmt::format("Lost atoms: original {} current {}", error->warning(FLERR,fmt::format("Lost atoms: original {} current {}",
atom->natoms,ntotal),0); atom->natoms,ntotal[0]),0);
// reset total atom count // reset total atom count
atom->natoms = ntotal; atom->natoms = ntotal[0];
lostbefore = 1; 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"); else error->all(FLERR,"Illegal thermo_modify command");
iarg += 2; 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) { } else if (strcmp(arg[iarg],"norm") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command"); if (iarg+2 > narg) error->all(FLERR,"Illegal thermo_modify command");
normuserflag = 1; normuserflag = 1;

View File

@ -64,7 +64,7 @@ class Thermo : protected Pointers {
int normuser; int normuser;
int firststep; int firststep;
int lostbefore; int lostbefore, warnbefore;
int flushflag,lineflag; int flushflag,lineflag;
double last_tpcpu,last_spcpu; double last_tpcpu,last_spcpu;