Merge pull request #2695 from akohlmey/collected-small-changes

Collected small changes and fixes
This commit is contained in:
Axel Kohlmeyer 2021-04-06 14:12:51 -04:00 committed by GitHub
commit 0b4d3588b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 390 additions and 97 deletions

View File

@ -24,7 +24,9 @@ jobs:
shell: bash
working-directory: ${{github.workspace}}/build
run: |
cmake -C $GITHUB_WORKSPACE/cmake/presets/most.cmake $GITHUB_WORKSPACE/cmake \
cmake -C $GITHUB_WORKSPACE/cmake/presets/clang.cmake \
-C $GITHUB_WORKSPACE/cmake/presets/most.cmake \
$GITHUB_WORKSPACE/cmake \
-DENABLE_TESTING=ON -DBUILD_SHARED_LIBS=ON -DLAMMPS_EXCEPTIONS=ON
cmake --build . --parallel 2

View File

@ -4,10 +4,10 @@ Adding tests for unit testing
This section discusses adding or expanding tests for the unit test
infrastructure included into the LAMMPS source code distribution.
Unlike example inputs, unit tests focus on testing the "local" behavior
of individual features, tend to run very fast, and should be set up to
cover as much of the added code as possible. When contributing code to
the distribution, the LAMMPS developers will appreciate if additions
to the integrated unit test facility are included.
of individual features, tend to run fast, and should be set up to cover
as much of the added code as possible. When contributing code to the
distribution, the LAMMPS developers will appreciate if additions to the
integrated unit test facility are included.
Given the complex nature of MD simulations where many operations can
only be performed when suitable "real" simulation environment has been
@ -50,6 +50,9 @@ available:
* - File name:
- Test name:
- Description:
* - ``test_argutils.cpp``
- ArgInfo
- Tests for ``ArgInfo`` class used by LAMMPS
* - ``test_fmtlib.cpp``
- FmtLib
- Tests for ``fmtlib::`` functions used by LAMMPS
@ -155,23 +158,27 @@ have the desired effect:
{
ASSERT_EQ(lmp->update->ntimestep, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_timestep 10");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_timestep 10");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->ntimestep, 10);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_timestep 0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_timestep 0");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->ntimestep, 0);
TEST_FAILURE(".*ERROR: Timestep must be >= 0.*", command("reset_timestep -10"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", command("reset_timestep"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", command("reset_timestep 10 10"););
TEST_FAILURE(".*ERROR: Expected integer .*", command("reset_timestep xxx"););
}
Please note the use of the (global) verbose variable to control whether
the LAMMPS command will be silent by capturing the output or not. In
the default case, verbose == false, the test output will be compact and
not mixed with LAMMPS output. However setting the verbose flag (via
setting the ``TEST_ARGS`` environment variable, ``TEST_ARGS=-v``) can be
helpful to understand why tests fail unexpectedly.
Please note the use of the ``BEGIN_HIDE_OUTPUT`` and ``END_HIDE_OUTPUT``
functions that will capture output from running LAMMPS. This is normally
discarded but by setting the verbose flag (via setting the ``TEST_ARGS``
environment variable, ``TEST_ARGS=-v``) it can be printed and used to
understand why tests fail unexpectedly.
Another complexity of these tests stems from the need to capture
situations where LAMMPS will stop with an error, i.e. handle so-called
@ -210,6 +217,12 @@ The following test programs are currently available:
* - ``test_lattice_region.cpp``
- LatticeRegion
- Tests to validate the :doc:`lattice <lattice>` and :doc:`region <region>` commands
* - ``test_groups.cpp``
- GroupTest
- Tests to validate the :doc:`group <group>` command
* - ``test_variables.cpp``
- VariableTest
- Tests to validate the :doc:`variable <variable>` command
* - ``test_kim_commands.cpp``
- KimCommands
- Tests for several commands from the :ref:`KIM package <PKG-KIM>`

View File

@ -71,6 +71,8 @@ package:
+----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+
| :ref:`PERI <PKG-PERI>` | Peridynamics models | :doc:`pair_style peri <pair_peri>` | peri | no |
+----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+
| :ref:`PLUGIN <PKG-PLUGIN>` | Plugin loader command | :doc:`plugin <plugin>` | plugins | no |
+----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+
| :ref:`POEMS <PKG-POEMS>` | coupled rigid body motion | :doc:`fix poems <fix_poems>` | rigid | int |
+----------------------------------+--------------------------------------+----------------------------------------------------+------------------------------------------------------+---------+
| :ref:`PYTHON <PKG-PYTHON>` | embed Python code in an input script | :doc:`python <python>` | python | sys |

View File

@ -15,7 +15,7 @@ Syntax
.. parsed-literal::
keyword = *first* or *last* or *every* or *skip* or *start* or *stop* or *dump*
keyword = *first* or *last* or *every* or *skip* or *start* or *stop* or *post* or *dump*
*first* args = Nfirst
Nfirst = dump timestep to start on
*last* args = Nlast
@ -28,6 +28,7 @@ Syntax
Nstart = timestep on which pseudo run will start
*stop* args = Nstop
Nstop = timestep to which pseudo run will end
*post* value = *yes* or *no*
*dump* args = same as :doc:`read_dump <read_dump>` command starting with its field arguments
Examples
@ -154,6 +155,10 @@ Also note that an error will occur if you read a snapshot from the
dump file with a timestep value larger than the *stop* setting you
have specified.
The *post* keyword can be used to minimize the output to the screen that
happens after a *rerun* command, similar to the post keyword of the
:doc:`run command <run>`. It is set to *no* by default.
The *dump* keyword is required and must be the last keyword specified.
Its arguments are passed internally to the :doc:`read_dump <read_dump>`
command. The first argument following the *dump* keyword should be
@ -226,4 +231,4 @@ Default
The option defaults are first = 0, last = a huge value (effectively
infinity), start = same as first, stop = same as last, every = 0, skip
= 1;
= 1, post = no;

View File

@ -17,21 +17,21 @@
#include "pair_lj_cut_coul_long.h"
#include <cmath>
#include <cstring>
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "force.h"
#include "kspace.h"
#include "update.h"
#include "respa.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "math_const.h"
#include "memory.h"
#include "error.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h"
#include "respa.h"
#include "update.h"
#include <cmath>
#include <cstring>
using namespace LAMMPS_NS;
using namespace MathConst;

View File

@ -25,10 +25,11 @@
----------------------------------------------------------------------*/
#include "reaxc_tool_box.h"
#include "reaxc_defs.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "reaxc_defs.h"
#include "error.h"
@ -49,62 +50,58 @@ int Tokenize( char* s, char*** tok )
return count;
}
/* safe malloc */
void *smalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, const char *name )
{
void *ptr;
char errmsg[256];
if (n <= 0) {
snprintf(errmsg, 256, "Trying to allocate %ld bytes for array %s. "
auto errmsg = fmt::format("Trying to allocate {} bytes for array {}. "
"returning NULL.", n, name);
if (error_ptr) error_ptr->one(FLERR,errmsg);
else fputs(errmsg,stderr);
else fputs(errmsg.c_str(),stderr);
return nullptr;
}
ptr = malloc( n );
if (ptr == nullptr) {
snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n, name);
auto errmsg = fmt::format("Failed to allocate {} bytes for array {}",
n, name);
if (error_ptr) error_ptr->one(FLERR,errmsg);
else fputs(errmsg,stderr);
else fputs(errmsg.c_str(),stderr);
}
return ptr;
}
/* safe calloc */
void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const char *name )
{
void *ptr;
char errmsg[256];
if (n <= 0) {
snprintf(errmsg, 256, "Trying to allocate %ld elements for array %s. "
"returning NULL.\n", n, name );
auto errmsg = fmt::format("Trying to allocate {} elements for array {}. "
"returning NULL.\n", n, name);
if (error_ptr) error_ptr->one(FLERR,errmsg);
else fputs(errmsg,stderr);
else fputs(errmsg.c_str(),stderr);
return nullptr;
}
if (size <= 0) {
snprintf(errmsg, 256, "Elements size for array %s is %ld. "
"returning NULL", name, size );
auto errmsg = fmt::format("Elements size for array {} is {}. "
"returning NULL", name, size);
if (error_ptr) error_ptr->one(FLERR,errmsg);
else fputs(errmsg,stderr);
else fputs(errmsg.c_str(),stderr);
return nullptr;
}
ptr = calloc( n, size );
if (ptr == nullptr) {
char errmsg[256];
snprintf(errmsg, 256, "Failed to allocate %ld bytes for array %s", n*size, name);
auto errmsg = fmt::format("Failed to allocate {} bytes for array {}",
n*size, name);
if (error_ptr) error_ptr->one(FLERR,errmsg);
else fputs(errmsg,stderr);
else fputs(errmsg.c_str(),stderr);
}
return ptr;
@ -115,14 +112,14 @@ void *scalloc( LAMMPS_NS::Error *error_ptr, rc_bigint n, rc_bigint size, const c
void sfree( LAMMPS_NS::Error* error_ptr, void *ptr, const char *name )
{
if (ptr == nullptr) {
char errmsg[256];
snprintf(errmsg, 256, "Trying to free the already NULL pointer %s", name );
auto errmsg = fmt::format("Trying to free the already free()'d pointer {}",
name);
if (error_ptr) error_ptr->one(FLERR,errmsg);
else fputs(errmsg,stderr);
else fputs(errmsg.c_str(),stderr);
return;
}
free( ptr );
free(ptr);
ptr = nullptr;
}

View File

@ -36,14 +36,18 @@
#define HEADER_LINE_LEN 62
#define STR_LINE "%-37s%-24s\n"
#define INT_LINE "%-37s%-24d\n"
#define BIGINT_LINE "%-37s%-24ld\n"
#if defined(LAMMPS_SMALLSMALL)
#define BIGINT_LINE "%-37s%-24d\n"
#else
#define BIGINT_LINE "%-37s%-24lld\n"
#endif
#define INT2_LINE "%-36s%-12d,%-12d\n"
#define REAL_LINE "%-37s%-24.3f\n"
#define SCI_LINE "%-37s%-24g\n"
#define REAL3_LINE "%-32s%9.3f,%9.3f,%9.3f\n"
#if defined(LAMMPS_BIGBIG)
#define INIT_DESC "%9ld%3d%9s%10.3f\n" //AtomID - AtomType, AtomName, AtomMass
#define INIT_DESC "%9lld%3d%9s%10.3f\n" //AtomID - AtomType, AtomName, AtomMass
#else
#define INIT_DESC "%9d%3d%9s%10.3f\n" //AtomID - AtomType, AtomName, AtomMass
#endif
@ -56,7 +60,7 @@
#define SIZE_INFO_LEN3 31
#if defined(LAMMPS_BIGBIG)
#define ATOM_BASIC "%9ld%10.3f%10.3f%10.3f%10.3f\n" //AtomID AtomType (X Y Z) Charge
#define ATOM_BASIC "%9lld%10.3f%10.3f%10.3f%10.3f\n" //AtomID AtomType (X Y Z) Charge
#define ATOM_wV "%9ld%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f\n" //AtomID (X Y Z) (Vx Vy Vz) Charge
#define ATOM_wF "%9ld%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f\n" //AtomID (X Y Z) (Fx Fy Fz) Charge
#define ATOM_FULL "%9ld%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f%10.3f\n" //AtomID (X Y Z) (Vx Vy Vz) (Fx Fy Fz) Charge
@ -72,9 +76,9 @@
#define ATOM_FULL_LEN 110
#if defined(LAMMPS_BIGBIG)
#define BOND_BASIC "%9ld%9ld%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO
#define BOND_FULL "%9ld%9ld%10.3f%10.3f%10.3f%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO BOs BOpi BOpi2
#define ANGLE_BASIC "%9ld%9ld%9ld%10.3f\n" // Atom1 Atom2 Atom3 Theta
#define BOND_BASIC "%9lld%9lld%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO
#define BOND_FULL "%9lld%9lld%10.3f%10.3f%10.3f%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO BOs BOpi BOpi2
#define ANGLE_BASIC "%9lld%9lld%9lld%10.3f\n" // Atom1 Atom2 Atom3 Theta
#else
#define BOND_BASIC "%9d%9d%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO
#define BOND_FULL "%9d%9d%10.3f%10.3f%10.3f%10.3f%10.3f\n" // Atom1 Atom2 Dist Total_BO BOs BOpi BOpi2

View File

@ -106,6 +106,7 @@ void PairLJSwitch3CoulGaussLong::compute(int eflag, int vflag)
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
qtmp = q[i];
@ -193,7 +194,7 @@ void PairLJSwitch3CoulGaussLong::compute(int eflag, int vflag)
offset[itype][jtype];
} else evdwl = 0.0;
// Truncation, see Yaff Switch33
// Truncation, see Yaff Switch3
if (truncw>0) {
if (rsq < cut_ljsq[itype][jtype]) {
if (r>cut_lj[itype][jtype]-truncw) {
@ -265,16 +266,15 @@ void PairLJSwitch3CoulGaussLong::settings(int narg, char **arg)
if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command");
cut_lj_global = utils::numeric(FLERR,arg[0],false,lmp);
if (narg == 2) {
cut_coul = cut_lj_global;
truncw = utils::numeric(FLERR,arg[1],false,lmp);
}
else {
} else {
cut_coul = utils::numeric(FLERR,arg[1],false,lmp);
truncw = utils::numeric(FLERR,arg[2],false,lmp);
}
if (truncw>0.0) truncwi = 1.0/truncw;
else truncwi = 0.0;
// reset cutoffs that have been explicitly set
if (allocated) {
@ -332,6 +332,9 @@ void PairLJSwitch3CoulGaussLong::init_style()
cut_coulsq = cut_coul * cut_coul;
if (truncw>0.0) truncwi = 1.0/truncw;
else truncwi = 0.0;
// insure use of KSpace long-range solver, set g_ewald
if (force->kspace == nullptr)
@ -375,8 +378,7 @@ double PairLJSwitch3CoulGaussLong::init_one(int i, int j)
double r6inv = r2inv*r2inv*r2inv;
double r12inv = r6inv*r6inv;
offset[i][j] = lj3[i][j]*r12inv-lj4[i][j]*r6inv;
}
else {offset[i][j] = 0.0;}
} else {offset[i][j] = 0.0;}
} else offset[i][j] = 0.0;
cut_ljsq[j][i] = cut_ljsq[i][j];
@ -431,8 +433,7 @@ double PairLJSwitch3CoulGaussLong::init_one(int i, int j)
double t71 = -0.4e1 * cg * (0.2e1 * t10 * t11 - 0.2e1 * t10 * t14 + (cg5 - 0.2e1 * cg1) * t58 * cg5) * t26 / t4 / t41 / t9;
etail_ij = 2.0*MY_PI*all[0]*all[1]*t71;
ptail_ij = 2.0*MY_PI*all[0]*all[1]*t71;
}
else {
} else {
double t1 = pow(cg3, 0.2e1);
double t2 = t1 * t1;
double t3 = t2 * t1;
@ -618,6 +619,7 @@ double PairLJSwitch3CoulGaussLong::single(int i, int j, int itype, int jtype,
expn2 = 0.0;
erfc2 = 0.0;
forcecoul2 = 0.0;
prefactor2 = 0.0;
} else {
r = sqrt(rsq);
rrij = lj2[itype][jtype]*r;

View File

@ -106,6 +106,7 @@ void PairMM3Switch3CoulGaussLong::compute(int eflag, int vflag)
firstneigh = list->firstneigh;
// loop over neighbors of my atoms
for (ii = 0; ii < inum; ii++) {
i = ilist[ii];
qtmp = q[i];
@ -170,6 +171,7 @@ void PairMM3Switch3CoulGaussLong::compute(int eflag, int vflag)
expn2 = 0.0;
erfc2 = 0.0;
forcecoul2 = 0.0;
prefactor2 = 0.0;
} else {
rrij = lj2[itype][jtype]*r;
expn2 = exp(-rrij*rrij);
@ -266,16 +268,15 @@ void PairMM3Switch3CoulGaussLong::settings(int narg, char **arg)
if (narg < 2 || narg > 3) error->all(FLERR,"Illegal pair_style command");
cut_lj_global = utils::numeric(FLERR,arg[0],false,lmp);
if (narg == 2) {
cut_coul = cut_lj_global;
truncw = utils::numeric(FLERR,arg[1],false,lmp);
}
else {
} else {
cut_coul = utils::numeric(FLERR,arg[1],false,lmp);
truncw = utils::numeric(FLERR,arg[2],false,lmp);
}
if (truncw>0.0) truncwi = 1.0/truncw;
else truncwi = 0.0;
// reset cutoffs that have been explicitly set
if (allocated) {
@ -333,6 +334,9 @@ void PairMM3Switch3CoulGaussLong::init_style()
cut_coulsq = cut_coul * cut_coul;
if (truncw>0.0) truncwi = 1.0/truncw;
else truncwi = 0.0;
// insure use of KSpace long-range solver, set g_ewald
if (force->kspace == nullptr)
@ -375,8 +379,7 @@ double PairMM3Switch3CoulGaussLong::init_one(int i, int j)
double r6inv = r2inv*r2inv*r2inv;
double expb = lj3[i][j]*exp(-lj1[i][j]*r);
offset[i][j] = expb-lj4[i][j]*r6inv;
}
else {offset[i][j] = 0.0;}
} else {offset[i][j] = 0.0;}
} else offset[i][j] = 0.0;
cut_ljsq[j][i] = cut_ljsq[i][j];
@ -426,8 +429,7 @@ double PairMM3Switch3CoulGaussLong::init_one(int i, int j)
double t64 = cg * (0.6388888889e3 * ((-t3 + (0.7e1 / 0.36e2 * cg5 - t5) * t1 - 0.2e1 / 0.3e1 * t8 * (cg5 - cg1 / 0.4e1) * cg3 + cg5 * t14) * t20 + t3 + (cg5 / 0.12e2 + t5) * t1 + (cg5 + cg1 / 0.3e1) * cg1 * cg3 / 0.2e1 + t30 * cg5) * t2 * t36 * t39 - 0.225e1 * (0.2e1 * t43 * t44 - 0.2e1 * t43 * t47 + cg5 * (cg5 - 0.2e1 * cg1)) * t54 * t1 / cg1 / t8 * t39);
etail_ij = 2.0*MY_PI*all[0]*all[1]*t64;
ptail_ij = 2.0*MY_PI*all[0]*all[1]*t64;
}
else {
} else {
double t2 = pow(cg3, 0.2e1);
double t3 = t2 * t2;
double t7 = 0.12e2 / cg3 * cg1;

View File

@ -136,13 +136,16 @@ double RanMars::gaussian(double mu, double sigma)
double RanMars::rayleigh(double sigma)
{
double first,v1;
double v1;
if (sigma <= 0) error->all(FLERR,"Invalid Rayleigh parameter");
if (sigma <= 0.0) error->all(FLERR,"Invalid Rayleigh parameter");
v1 = uniform();
first = sigma*sqrt(-2.0*log(v1));
return first;
// avoid a floating point exception due to log(0.0)
// and just return a very big number
if (v1 == 0.0) return 1.0e300;
return sigma*sqrt(-2.0*log(v1));
}
/* ----------------------------------------------------------------------

View File

@ -51,6 +51,7 @@ void Rerun::command(int narg, char **arg)
if (strcmp(arg[iarg],"start") == 0) break;
if (strcmp(arg[iarg],"stop") == 0) break;
if (strcmp(arg[iarg],"dump") == 0) break;
if (strcmp(arg[iarg],"post") == 0) break;
iarg++;
}
int nfile = iarg;
@ -65,6 +66,7 @@ void Rerun::command(int narg, char **arg)
int nskip = 1;
int startflag = 0;
int stopflag = 0;
int postflag = 0;
bigint start = -1;
bigint stop = -1;
@ -101,6 +103,14 @@ void Rerun::command(int narg, char **arg)
stop = utils::bnumeric(FLERR,arg[iarg+1],false,lmp);
if (stop < 0) error->all(FLERR,"Illegal rerun command");
iarg += 2;
} else if (strcmp(arg[iarg],"post") == 0) {
if (iarg+2 > narg) error->all(FLERR,"Illegal rerun command");
if (strcmp(arg[iarg+1],"yes") == 0) {
postflag = 1;
} else if (strcmp(arg[iarg+1],"no") == 0) {
postflag = 0;
} else error->all(FLERR,"Illegal rerun command");
iarg += 2;
} else if (strcmp(arg[iarg],"dump") == 0) {
break;
} else error->all(FLERR,"Illegal rerun command");
@ -182,7 +192,7 @@ void Rerun::command(int narg, char **arg)
update->nsteps = ndump;
Finish finish(lmp);
finish.end(1);
finish.end(postflag);
update->whichflag = 0;
update->firststep = update->laststep = 0;

View File

@ -41,7 +41,7 @@ public:
Tokenizer& operator=(Tokenizer&&) = default;
void reset();
void skip(int n);
void skip(int n=1);
bool has_next() const;
bool contains(const std::string &str) const;
std::string next();
@ -104,7 +104,7 @@ public:
bool has_next() const;
bool contains(const std::string &value) const;
void skip(int ntokens);
void skip(int ntokens=1);
size_t count();
};

View File

@ -108,7 +108,7 @@ void Velocity::command(int narg, char **arg)
int initcomm = 0;
if (style == ZERO && rfix >= 0 &&
utils::strmatch(modify->fix[rfix]->style,"^rigid/small")) initcomm = 1;
utils::strmatch(modify->fix[rfix]->style,"^rigid.*/small.*")) initcomm = 1;
if ((style == CREATE || style == SET) && temperature &&
strcmp(temperature->style,"temp/cs") == 0) initcomm = 1;

View File

@ -328,11 +328,7 @@ TEST_F(SimpleCommandsTest, Units)
#if defined(LMP_PLUGIN)
TEST_F(SimpleCommandsTest, Plugin)
{
#if defined(__APPLE__)
std::string loadfmt("plugin load {}plugin.dylib");
#else
std::string loadfmt("plugin load {}plugin.so");
#endif
::testing::internal::CaptureStdout();
lmp->input->one(fmt::format(loadfmt, "hello"));
auto text = ::testing::internal::GetCapturedStdout();

View File

@ -1,7 +1,7 @@
---
lammps_version: 10 Mar 2021
date_generated: Thu Mar 25 14:07:45 202
epsilon: 1e-14
epsilon: 5e-13
prerequisites: ! |
atom full
fix adapt

View File

@ -15,6 +15,8 @@
#include "../testing/systems/melt.h"
#include "../testing/utils.h"
#include "fmt/format.h"
#include "output.h"
#include "thermo.h"
#include "utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -46,7 +48,14 @@ public:
command(fmt::format("dump_modify id {}", dump_modify_options));
}
command(fmt::format("run {}", ntimesteps));
command(fmt::format("run {} post no", ntimesteps));
END_HIDE_OUTPUT();
}
void continue_dump(int ntimesteps)
{
BEGIN_HIDE_OUTPUT();
command(fmt::format("run {} pre no post no", ntimesteps));
END_HIDE_OUTPUT();
}
@ -62,7 +71,7 @@ public:
command(fmt::format("dump_modify id1 {}", dump_modify_options));
}
command(fmt::format("run {}", ntimesteps));
command(fmt::format("run {} post no", ntimesteps));
END_HIDE_OUTPUT();
}
@ -446,13 +455,16 @@ TEST_F(DumpAtomTest, binary_triclinic_with_image_run0)
delete_file(converted_file);
}
TEST_F(DumpAtomTest, run1)
TEST_F(DumpAtomTest, run1plus1)
{
auto dump_file = "dump_run1.melt";
auto dump_file = "dump_run1plus1.melt";
generate_dump(dump_file, "", 1);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 82);
continue_dump(1);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 123);
delete_file(dump_file);
}
@ -466,6 +478,34 @@ TEST_F(DumpAtomTest, run2)
delete_file(dump_file);
}
TEST_F(DumpAtomTest, rerun)
{
auto dump_file = "dump_rerun.melt";
HIDE_OUTPUT([&] {
command("fix 1 all nve");
});
generate_dump(dump_file, "format line \"%d %d %20.15g %20.15g %20.15g\"", 1);
double pe_1, pe_2, pe_rerun;
lmp->output->thermo->evaluate_keyword("pe", &pe_1);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 82);
continue_dump(1);
lmp->output->thermo->evaluate_keyword("pe", &pe_2);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 123);
HIDE_OUTPUT([&] {
command(fmt::format("rerun {} first 1 last 1 every 1 post no dump x y z", dump_file));
});
lmp->output->thermo->evaluate_keyword("pe", &pe_rerun);
ASSERT_DOUBLE_EQ(pe_1, pe_rerun);
HIDE_OUTPUT([&] {
command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file));
});
lmp->output->thermo->evaluate_keyword("pe", &pe_rerun);
ASSERT_DOUBLE_EQ(pe_2, pe_rerun);
delete_file(dump_file);
}
TEST_F(DumpAtomTest, multi_file_run1)
{
auto dump_file = "dump_run1_*.melt";

View File

@ -15,6 +15,8 @@
#include "../testing/systems/melt.h"
#include "../testing/utils.h"
#include "fmt/format.h"
#include "output.h"
#include "thermo.h"
#include "utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@ -45,7 +47,14 @@ public:
command(fmt::format("dump_modify id {}", dump_modify_options));
}
command(fmt::format("run {}", ntimesteps));
command(fmt::format("run {} post no", ntimesteps));
END_HIDE_OUTPUT();
}
void continue_dump(int ntimesteps)
{
BEGIN_HIDE_OUTPUT();
command(fmt::format("run {} pre no post no", ntimesteps));
END_HIDE_OUTPUT();
}
@ -62,7 +71,7 @@ public:
command(fmt::format("dump_modify id1 {}", dump_modify_options));
}
command(fmt::format("run {}", ntimesteps));
command(fmt::format("run {} post no", ntimesteps));
END_HIDE_OUTPUT();
}
@ -262,6 +271,64 @@ TEST_F(DumpCustomTest, with_variable_run1)
delete_file(dump_file);
}
TEST_F(DumpCustomTest, run1plus1)
{
auto dump_file = "dump_custom_run1plus1.melt";
auto fields = "id type x y z";
generate_dump(dump_file, fields, "units yes", 1);
ASSERT_FILE_EXISTS(dump_file);
auto lines = read_lines(dump_file);
ASSERT_EQ(lines.size(), 84);
continue_dump(1);
ASSERT_FILE_EXISTS(dump_file);
lines = read_lines(dump_file);
ASSERT_EQ(lines.size(), 125);
delete_file(dump_file);
}
TEST_F(DumpCustomTest, run2)
{
auto dump_file = "dump_custom_run2.melt";
auto fields = "id type x y z";
generate_dump(dump_file, fields, "", 2);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 123);
delete_file(dump_file);
}
TEST_F(DumpCustomTest, rerun)
{
auto dump_file = "dump_rerun.melt";
auto fields = "id type xs ys zs";
HIDE_OUTPUT([&] {
command("fix 1 all nve");
});
generate_dump(dump_file, fields, "format float %20.15g", 1);
double pe_1, pe_2, pe_rerun;
lmp->output->thermo->evaluate_keyword("pe", &pe_1);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 82);
continue_dump(1);
lmp->output->thermo->evaluate_keyword("pe", &pe_2);
ASSERT_FILE_EXISTS(dump_file);
ASSERT_EQ(count_lines(dump_file), 123);
HIDE_OUTPUT([&] {
command(fmt::format("rerun {} first 1 last 1 every 1 post no dump x y z", dump_file));
});
lmp->output->thermo->evaluate_keyword("pe", &pe_rerun);
ASSERT_DOUBLE_EQ(pe_1, pe_rerun);
HIDE_OUTPUT([&] {
command(fmt::format("rerun {} first 2 last 2 every 1 post yes dump x y z", dump_file));
});
lmp->output->thermo->evaluate_keyword("pe", &pe_rerun);
ASSERT_DOUBLE_EQ(pe_2, pe_rerun);
delete_file(dump_file);
}
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);

View File

@ -28,6 +28,7 @@
#include "potential_file_reader.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstring>
@ -257,6 +258,67 @@ TEST_F(PotentialFileReaderTest, UnitConvert)
delete reader;
}
class OpenPotentialTest : public LAMMPSTest {
};
// open for native units
TEST_F(OpenPotentialTest, Sw_native)
{
int convert_flag = utils::get_supported_conversions(utils::ENERGY);
BEGIN_CAPTURE_OUTPUT();
command("units metal");
FILE *fp = utils::open_potential("Si.sw", lmp, &convert_flag);
auto text = END_CAPTURE_OUTPUT();
double conv = utils::get_conversion_factor(utils::ENERGY, convert_flag);
ASSERT_NE(fp, nullptr);
ASSERT_DOUBLE_EQ(conv, 1.0);
fclose(fp);
}
// open with supported conversion enabled
TEST_F(OpenPotentialTest, Sw_conv)
{
int convert_flag = utils::get_supported_conversions(utils::ENERGY);
ASSERT_EQ(convert_flag, utils::METAL2REAL | utils::REAL2METAL);
BEGIN_HIDE_OUTPUT();
command("units real");
FILE *fp = utils::open_potential("Si.sw", lmp, &convert_flag);
auto text = END_CAPTURE_OUTPUT();
double conv = utils::get_conversion_factor(utils::ENERGY, convert_flag);
ASSERT_NE(fp, nullptr);
ASSERT_EQ(convert_flag, utils::METAL2REAL);
ASSERT_DOUBLE_EQ(conv, 23.060549);
fclose(fp);
}
// open with conversion disabled
TEST_F(OpenPotentialTest, Sw_noconv)
{
BEGIN_HIDE_OUTPUT();
command("units real");
END_HIDE_OUTPUT();
TEST_FAILURE(".*potential.*requires metal units but real.*",
utils::open_potential("Si.sw", lmp, nullptr););
BEGIN_HIDE_OUTPUT();
command("units lj");
END_HIDE_OUTPUT();
int convert_flag = utils::get_supported_conversions(utils::UNKNOWN);
ASSERT_EQ(convert_flag, utils::NOCONVERT);
}
// open non-existing potential
TEST_F(OpenPotentialTest, No_file)
{
int convert_flag = utils::get_supported_conversions(utils::ENERGY);
BEGIN_HIDE_OUTPUT();
command("units metal");
FILE *fp = utils::open_potential("Unknown.sw", lmp, &convert_flag);
END_HIDE_OUTPUT();
ASSERT_EQ(fp,nullptr);
}
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);

View File

@ -43,6 +43,18 @@ TEST(Tokenizer, two_words)
ASSERT_EQ(t.count(), 2);
}
TEST(Tokenizer, skip)
{
Tokenizer t("test word", " ");
ASSERT_TRUE(t.has_next());
t.skip();
ASSERT_TRUE(t.has_next());
t.skip(1);
ASSERT_FALSE(t.has_next());
ASSERT_EQ(t.count(), 2);
ASSERT_THROW(t.skip(), TokenizerException);
}
TEST(Tokenizer, prefix_separators)
{
Tokenizer t(" test word", " ");
@ -63,6 +75,18 @@ TEST(Tokenizer, iterate_words)
ASSERT_EQ(t.count(), 2);
}
TEST(Tokenizer, copy_constructor)
{
Tokenizer t(" test word ", " ");
ASSERT_THAT(t.next(), Eq("test"));
ASSERT_THAT(t.next(), Eq("word"));
ASSERT_EQ(t.count(), 2);
Tokenizer u(t);
ASSERT_THAT(u.next(), Eq("test"));
ASSERT_THAT(u.next(), Eq("word"));
ASSERT_EQ(u.count(), 2);
}
TEST(Tokenizer, no_separator_path)
{
Tokenizer t("one", ":");
@ -139,6 +163,26 @@ TEST(ValueTokenizer, empty_string)
ASSERT_FALSE(values.has_next());
}
TEST(ValueTokenizer, two_words)
{
ValueTokenizer t("test word", " ");
ASSERT_THAT(t.next_string(), Eq("test"));
ASSERT_THAT(t.next_string(), Eq("word"));
ASSERT_THROW(t.next_string(), TokenizerException);
}
TEST(ValueTokenizer, skip)
{
ValueTokenizer t("test word", " ");
ASSERT_TRUE(t.has_next());
t.skip();
ASSERT_TRUE(t.has_next());
t.skip(1);
ASSERT_FALSE(t.has_next());
ASSERT_EQ(t.count(), 2);
ASSERT_THROW(t.skip(), TokenizerException);
}
TEST(ValueTokenizer, bad_integer)
{
ValueTokenizer values("f10");

View File

@ -331,6 +331,11 @@ TEST(Utils, valid_id7)
ASSERT_TRUE(utils::is_id("___"));
}
TEST(Utils, empty_id)
{
ASSERT_FALSE(utils::is_id(""));
}
TEST(Utils, invalid_id1)
{
ASSERT_FALSE(utils::is_id("+abc"));
@ -780,6 +785,11 @@ TEST(Utils, unit_conversion)
ASSERT_DOUBLE_EQ(factor, 1.0 / 23.060549);
}
TEST(Utils, timespec2seconds_off)
{
ASSERT_DOUBLE_EQ(utils::timespec2seconds("off"), -1.0);
}
TEST(Utils, timespec2seconds_ss)
{
ASSERT_DOUBLE_EQ(utils::timespec2seconds("45"), 45.0);
@ -795,6 +805,11 @@ TEST(Utils, timespec2seconds_hhmmss)
ASSERT_DOUBLE_EQ(utils::timespec2seconds("2:10:45"), 7845.0);
}
TEST(Utils, timespec2seconds_invalid)
{
ASSERT_DOUBLE_EQ(utils::timespec2seconds("2:aa:45"), -1.0);
}
TEST(Utils, date2num)
{
ASSERT_EQ(utils::date2num("1Jan05"), 20050101);
@ -810,3 +825,32 @@ TEST(Utils, date2num)
ASSERT_EQ(utils::date2num("30November 02"), 20021130);
ASSERT_EQ(utils::date2num("31December100"), 1001231);
}
static int compare(int a, int b, void *)
{
if (a < b)
return -1;
else if (a > b)
return 1;
else
return 0;
}
TEST(Utils, merge_sort)
{
int data[] = {773, 405, 490, 830, 632, 96, 428, 728, 912, 840, 878, 745, 213, 219, 249, 380,
894, 758, 575, 690, 61, 849, 19, 577, 338, 569, 898, 873, 448, 940, 431, 780,
472, 289, 65, 491, 641, 37, 367, 33, 407, 854, 594, 611, 845, 136, 107, 592,
275, 865, 158, 626, 399, 703, 686, 734, 188, 559, 781, 558, 737, 281, 638, 664,
533, 529, 62, 969, 595, 661, 837, 463, 624, 568, 615, 936, 206, 637, 91, 694,
214, 872, 468, 66, 775, 949, 486, 576, 255, 961, 480, 138, 177, 509, 333, 705,
10, 375, 321, 952, 210, 111, 475, 268, 708, 864, 244, 121, 988, 540, 942, 682,
750, 473, 478, 714, 955, 911, 482, 384, 144, 757, 697, 791, 420, 605, 447, 320};
const int num = sizeof(data) / sizeof(int);
utils::merge_sort(data, num, nullptr, &compare);
bool sorted = true;
for (int i = 1; i < num; ++i)
if (data[i - 1] > data[i]) sorted = false;
ASSERT_TRUE(sorted);
}