Update to latest changes from upstream

This commit is contained in:
Axel Kohlmeyer
2021-05-11 17:49:03 -04:00
5027 changed files with 286731 additions and 199007 deletions

View File

@ -1,5 +1,31 @@
include(GTest)
# check if we can run the compiled executable and whether it prints
# the LAMMPS version header in the output for an empty input
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/in.empty "")
add_test(NAME RunLammps
COMMAND $<TARGET_FILE:lmp> -log none -echo none -in in.empty
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(RunLammps PROPERTIES
ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1"
PASS_REGULAR_EXPRESSION "^LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]\\)")
# check if the compiled executable will print the help message
add_test(NAME HelpMessage
COMMAND $<TARGET_FILE:lmp> -h
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(HelpMessage PROPERTIES
ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1"
PASS_REGULAR_EXPRESSION ".*Large-scale Atomic/Molecular Massively Parallel Simulator -.*Usage example:.*")
# check if the compiled executable will error out on an invalid command line flag
add_test(NAME InvalidFlag
COMMAND $<TARGET_FILE:lmp> -xxx
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(InvalidFlag PROPERTIES
ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1"
PASS_REGULAR_EXPRESSION "ERROR: Invalid command-line argument.*")
if(BUILD_MPI)
function(add_mpi_test)
set(MPI_TEST_NUM_PROCS 1)

View File

@ -11,6 +11,7 @@ add_executable(test_library_properties test_library_properties.cpp test_main.cpp
target_link_libraries(test_library_properties PRIVATE lammps GTest::GTest GTest::GMock)
target_compile_definitions(test_library_properties PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR})
add_test(LibraryProperties test_library_properties)
set_tests_properties(LibraryProperties PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR}")
set(TEST_CONFIG_DEFS "-DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR};-DLAMMPS_${LAMMPS_SIZES}")
set(PKG_COUNT 0)
@ -56,7 +57,7 @@ target_link_libraries(test_library_config PRIVATE lammps GTest::GTest GTest::GMo
target_compile_definitions(test_library_config PRIVATE ${TEST_CONFIG_DEFS})
add_test(LibraryConfig test_library_config)
if (BUILD_MPI)
if(BUILD_MPI)
add_executable(test_library_mpi test_library_mpi.cpp)
target_link_libraries(test_library_mpi PRIVATE lammps GTest::GTest GTest::GMock)
target_compile_definitions(test_library_mpi PRIVATE ${TEST_CONFIG_DEFS})

View File

@ -118,4 +118,24 @@ TEST_F(LibraryCommands, from_string)
lammps_commands_string(lmp, cmds.c_str());
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_EQ(lammps_get_natoms(lmp), 2);
// repeat test with DOS/Windows style CR-LF line endings
if (!verbose) ::testing::internal::CaptureStdout();
lammps_command(lmp, "clear");
if (!verbose) ::testing::internal::GetCapturedStdout();
cmds.clear();
for (unsigned int i = 0; i < sizeof(demo_input) / sizeof(char *); ++i) {
cmds += demo_input[i];
cmds += "\r\n";
}
for (unsigned int i = 0; i < sizeof(cont_input) / sizeof(char *); ++i) {
cmds += cont_input[i];
cmds += "\r\n";
}
EXPECT_EQ(lammps_get_natoms(lmp), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lammps_commands_string(lmp, cmds.c_str());
if (!verbose) ::testing::internal::GetCapturedStdout();
EXPECT_EQ(lammps_get_natoms(lmp), 2);
};

View File

@ -74,7 +74,7 @@ TEST(LAMMPSConfig, package_name)
EXPECT_EQ(lammps_config_package_name(numpkgs + 10, buf, 128), 0);
EXPECT_THAT(buf, StrEq(""));
} else {
EXPECT_EQ(lammps_config_package_name(0, buf, 128), 1);
EXPECT_EQ(lammps_config_package_name(0, buf, 128), 0);
EXPECT_THAT(buf, StrEq(""));
}
};
@ -200,7 +200,10 @@ TEST(LAMMPSConfig, exceptions)
TEST(LAMMPSConfig, mpi_support)
{
EXPECT_EQ(lammps_config_has_mpi_support(), LAMMPS_HAS_MPI);
if (LAMMPS_HAS_MPI)
EXPECT_GT(lammps_config_has_mpi_support(), 0);
else
EXPECT_EQ(lammps_config_has_mpi_support(), 0);
};
TEST(LAMMPSConfig, png_support)

View File

@ -173,7 +173,7 @@ TEST(MPI, multi_partition)
MPI_Comm_size(MPI_COMM_WORLD, &nprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &me);
const char *args[] = {"LAMMPS_test", "-log", "none", "-partition", "2x2",
const char *args[] = {"LAMMPS_test", "-log", "none", "-partition", "4x1",
"-echo", "screen", "-nocite", "-in", "none"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
@ -183,19 +183,15 @@ TEST(MPI, multi_partition)
lammps_command(lmp, "atom_style atomic");
lammps_command(lmp, "region box block 0 2 0 2 0 2");
lammps_command(lmp, "create_box 1 box");
lammps_command(lmp, "variable partition universe 1 2");
lammps_command(lmp, "variable partition universe 1 2 3 4");
EXPECT_EQ(lammps_extract_setting(lmp, "universe_size"), nprocs);
EXPECT_EQ(lammps_extract_setting(lmp, "universe_rank"), me);
EXPECT_EQ(lammps_extract_setting(lmp, "world_size"), nprocs / 2);
EXPECT_EQ(lammps_extract_setting(lmp, "world_rank"), me % 2);
EXPECT_EQ(lammps_extract_setting(lmp, "world_size"), 1);
EXPECT_EQ(lammps_extract_setting(lmp, "world_rank"), 0);
char *part_id = (char *)lammps_extract_variable(lmp, "partition", nullptr);
if (me < 2) {
ASSERT_THAT(part_id, StrEq("1"));
} else {
ASSERT_THAT(part_id, StrEq("2"));
}
ASSERT_THAT(part_id, StrEq(std::to_string(me + 1)));
lammps_close(lmp);
};

View File

@ -72,6 +72,7 @@ TEST(lammps_open, with_args)
output = ::testing::internal::GetCapturedStdout();
EXPECT_THAT(output, HasSubstr("Total wall time:"));
if (verbose) std::cout << output;
MPI_Comm_free(&mycomm);
}
TEST(lammps_open, with_kokkos)
@ -195,4 +196,5 @@ TEST(lammps_open_fortran, no_args)
output = ::testing::internal::GetCapturedStdout();
EXPECT_THAT(output, HasSubstr("Total wall time:"));
if (verbose) std::cout << output;
MPI_Comm_free(&mycomm);
}

View File

@ -65,7 +65,9 @@ TEST_F(LibraryProperties, memory_usage)
#if defined(__linux__) || defined(_WIN32)
EXPECT_GE(meminfo[1], 0.0);
#endif
#if !defined(__INTEL_LLVM_COMPILER)
EXPECT_GT(meminfo[2], 0.0);
#endif
};
TEST_F(LibraryProperties, get_mpi_comm)
@ -158,7 +160,9 @@ TEST_F(LibraryProperties, box)
boxlo[0] = -6.1;
boxhi[1] = 7.3;
xy = 0.1;
if (!verbose) ::testing::internal::CaptureStdout();
lammps_reset_box(lmp, boxlo, boxhi, xy, yz, xz);
if (!verbose) ::testing::internal::GetCapturedStdout();
lammps_extract_box(lmp, boxlo, boxhi, &xy, &yz, &xz, pflags, &boxflag);
EXPECT_DOUBLE_EQ(boxlo[0], -6.1);
EXPECT_DOUBLE_EQ(boxlo[1], -7.692866);
@ -289,33 +293,143 @@ TEST_F(LibraryProperties, global)
lammps_command(lmp, "run 2 post no");
if (!verbose) ::testing::internal::GetCapturedStdout();
int64_t *b_ptr;
char *c_ptr;
double *d_ptr;
int *i_ptr;
EXPECT_EQ(lammps_extract_global_datatype(lmp, "UNKNOWN"), -1);
EXPECT_EQ(lammps_extract_global(lmp, "UNKNOWN"), nullptr);
EXPECT_EQ(lammps_extract_global_datatype(lmp, "units"), LAMMPS_STRING);
c_ptr = (char *)lammps_extract_global(lmp, "units");
char *c_ptr = (char *)lammps_extract_global(lmp, "units");
EXPECT_THAT(c_ptr, StrEq("real"));
#if defined(LAMMPS_SMALLSMALL)
EXPECT_EQ(lammps_extract_global_datatype(lmp, "ntimestep"), LAMMPS_INT);
i_ptr = (int *)lammps_extract_global(lmp, "ntimestep");
int *i_ptr = (int *)lammps_extract_global(lmp, "ntimestep");
EXPECT_EQ((*i_ptr), 2);
#else
EXPECT_EQ(lammps_extract_global_datatype(lmp, "ntimestep"), LAMMPS_INT64);
b_ptr = (int64_t *)lammps_extract_global(lmp, "ntimestep");
int64_t *b_ptr = (int64_t *)lammps_extract_global(lmp, "ntimestep");
EXPECT_EQ((*b_ptr), 2);
#endif
EXPECT_EQ(lammps_extract_global_datatype(lmp, "dt"), LAMMPS_DOUBLE);
d_ptr = (double *)lammps_extract_global(lmp, "dt");
double *d_ptr = (double *)lammps_extract_global(lmp, "dt");
EXPECT_DOUBLE_EQ((*d_ptr), 0.1);
};
TEST_F(LibraryProperties, neighlist)
{
if (!lammps_has_style(lmp, "pair", "sw")) GTEST_SKIP();
const char sysinit[] = "boundary f f f\n"
"units real\n"
"region box block -5 5 -5 5 -5 5\n"
"create_box 2 box\n"
"mass 1 1.0\n"
"mass 2 1.0\n"
"pair_style hybrid/overlay lj/cut 4.0 lj/cut 4.0 morse 4.0 sw\n"
"pair_coeff * * sw Si.sw Si NULL\n"
"pair_coeff 1 2 morse 0.2 2.0 2.0\n"
"pair_coeff 2 2 lj/cut 1 0.1 2.0\n"
"pair_coeff * * lj/cut 2 0.01 2.0\n"
"compute dist all pair/local dist\n"
"fix dist all ave/histo 1 1 1 0.0 3.0 4 c_dist mode vector\n"
"thermo_style custom f_dist[*]";
const double pos[] = {0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1,
0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.1, 0.0, 0.0, 1.0};
const tagint ids[] = {1, 2, 3, 4, 5, 6, 7};
const int types[] = {1, 1, 1, 1, 2, 2, 2};
const int numatoms = sizeof(ids) / sizeof(tagint);
if (!verbose) ::testing::internal::CaptureStdout();
lammps_commands_string(lmp, sysinit);
lammps_create_atoms(lmp, numatoms, ids, types, pos, nullptr, nullptr, 0);
lammps_command(lmp, "run 0 post no");
if (!verbose) ::testing::internal::GetCapturedStdout();
int nhisto =
*(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 0, 0);
int nskip = *(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 1, 0);
double minval =
*(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 2, 0);
double maxval =
*(double *)lammps_extract_fix(lmp, "dist", LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR, 3, 0);
// 21 pair distances counted, none skipped, smallest 1.0, largest 2.1
EXPECT_EQ(nhisto, 21);
EXPECT_EQ(nskip, 0);
EXPECT_DOUBLE_EQ(minval, 1.0);
EXPECT_DOUBLE_EQ(maxval, 2.1);
const int nlocal = lammps_extract_setting(lmp, "nlocal");
EXPECT_EQ(nlocal, numatoms);
EXPECT_NE(lammps_find_pair_neighlist(lmp, "sw", 1, 0, 0), -1);
EXPECT_NE(lammps_find_pair_neighlist(lmp, "morse", 1, 0, 0), -1);
EXPECT_NE(lammps_find_pair_neighlist(lmp, "lj/cut", 1, 1, 0), -1);
EXPECT_NE(lammps_find_pair_neighlist(lmp, "lj/cut", 1, 2, 0), -1);
EXPECT_EQ(lammps_find_pair_neighlist(lmp, "lj/cut", 1, 0, 0), -1);
EXPECT_EQ(lammps_find_pair_neighlist(lmp, "hybrid/overlay", 1, 0, 0), -1);
EXPECT_NE(lammps_find_compute_neighlist(lmp, "dist", 0), -1);
EXPECT_EQ(lammps_find_fix_neighlist(lmp, "dist", 0), -1);
EXPECT_EQ(lammps_find_compute_neighlist(lmp, "xxx", 0), -1);
// full neighbor list for 4 type 1 atoms
// all have 3 type 1 atom neighbors
int idx = lammps_find_pair_neighlist(lmp, "sw", 1, 0, 0);
int num = lammps_neighlist_num_elements(lmp, idx);
EXPECT_EQ(num, 4);
int iatom, inum, *neighbors;
for (int i = 0; i < num; ++i) {
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
EXPECT_EQ(iatom, i);
EXPECT_EQ(inum, 3);
EXPECT_NE(neighbors, nullptr);
}
// half neighbor list for all pairs between type 1 and type 2
// 4 type 1 atoms with 3 type 2 neighbors and 3 type 2 atoms without neighbors
idx = lammps_find_pair_neighlist(lmp, "morse", 0, 0, 0);
num = lammps_neighlist_num_elements(lmp, idx);
EXPECT_EQ(num, nlocal);
for (int i = 0; i < num; ++i) {
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
if (i < 4)
EXPECT_EQ(inum, 3);
else
EXPECT_EQ(inum, 0);
EXPECT_NE(neighbors, nullptr);
}
// half neighbor list between type 2 atoms only
// 3 pairs with 2, 1, 0 neighbors
idx = lammps_find_pair_neighlist(lmp, "lj/cut", 1, 1, 0);
num = lammps_neighlist_num_elements(lmp, idx);
EXPECT_EQ(num, 3);
for (int i = 0; i < num; ++i) {
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
EXPECT_EQ(inum, 2 - i);
EXPECT_NE(neighbors, nullptr);
}
// half neighbor list between all pairs. same as simple lj/cut case
idx = lammps_find_pair_neighlist(lmp, "lj/cut", 1, 2, 0);
num = lammps_neighlist_num_elements(lmp, idx);
EXPECT_EQ(num, nlocal);
for (int i = 0; i < num; ++i) {
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
EXPECT_EQ(inum, nlocal - 1 - i);
EXPECT_NE(neighbors, nullptr);
}
// the compute has a half neighbor list
idx = lammps_find_compute_neighlist(lmp, "dist", 0);
num = lammps_neighlist_num_elements(lmp, idx);
EXPECT_EQ(num, nlocal);
for (int i = 0; i < num; ++i) {
lammps_neighlist_element_neighbors(lmp, idx, i, &iatom, &inum, &neighbors);
EXPECT_EQ(inum, nlocal - 1 - i);
EXPECT_NE(neighbors, nullptr);
}
};
class AtomProperties : public ::testing::Test {
protected:
void *lmp;

View File

@ -1,5 +1,31 @@
# build LAMMPS plugins, but not on Windows
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows" AND PKG_PLUGIN)
ExternalProject_Add(plugins
SOURCE_DIR "${LAMMPS_DIR}/examples/plugins"
BINARY_DIR ${CMAKE_BINARY_DIR}/build-plugins
INSTALL_DIR ${CMAKE_BINARY_DIR}
CMAKE_ARGS ${CMAKE_REQUEST_PIC}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}
BUILD_BYPRODUCTS <BINARY_DIR>/morse2plugin${CMAKE_SHARED_MODULE_SUFFIX}
<BINARY_DIR>/nve2plugin${CMAKE_SHARED_MODULE_SUFFIX}
<BINARY_DIR>/helloplugin${CMAKE_SHARED_MODULE_SUFFIX}
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_if_different
<BINARY_DIR>/morse2plugin${CMAKE_SHARED_MODULE_SUFFIX}
<BINARY_DIR>/nve2plugin${CMAKE_SHARED_MODULE_SUFFIX}
<BINARY_DIR>/helloplugin${CMAKE_SHARED_MODULE_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}
TEST_COMMAND "")
endif()
add_executable(test_simple_commands test_simple_commands.cpp)
if(PKG_PLUGIN)
add_dependencies(test_simple_commands plugins)
endif()
target_link_libraries(test_simple_commands PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME SimpleCommands COMMAND test_simple_commands WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
@ -7,7 +33,22 @@ add_executable(test_lattice_region test_lattice_region.cpp)
target_link_libraries(test_lattice_region PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME LatticeRegion COMMAND test_lattice_region WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(test_groups test_groups.cpp)
target_link_libraries(test_groups PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME Groups COMMAND test_groups WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(test_variables test_variables.cpp)
target_link_libraries(test_variables PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME Variables COMMAND test_variables WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
add_executable(test_kim_commands test_kim_commands.cpp)
if(KIM_EXTRA_UNITTESTS)
if(CURL_FOUND)
target_compile_definitions(test_kim_commands PRIVATE -DKIM_EXTRA_UNITTESTS)
else()
message(FATAL_ERROR "CURL not found. Enabling KIM extra unit tests requires to have libcurl installed.")
endif()
endif()
target_link_libraries(test_kim_commands PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME KimCommands COMMAND test_kim_commands WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
@ -15,3 +56,10 @@ add_executable(test_reset_ids test_reset_ids.cpp)
target_compile_definitions(test_reset_ids PRIVATE -DTEST_INPUT_FOLDER=${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(test_reset_ids PRIVATE lammps GTest::GMock GTest::GTest)
add_test(NAME ResetIDs COMMAND test_reset_ids WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(BUILD_MPI)
add_executable(test_mpi_load_balancing test_mpi_load_balancing.cpp)
target_link_libraries(test_mpi_load_balancing PRIVATE lammps GTest::GTest GTest::GMock)
target_compile_definitions(test_mpi_load_balancing PRIVATE ${TEST_CONFIG_DEFS})
add_mpi_test(NAME MPILoadBalancing NUM_PROCS 4 COMMAND $<TARGET_FILE:test_mpi_load_balancing>)
endif()

View File

@ -0,0 +1,338 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://lammps.sandia.gov/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "lammps.h"
#include "atom.h"
#include "domain.h"
#include "group.h"
#include "info.h"
#include "input.h"
#include "region.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstring>
#include <vector>
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
class GroupTest : public LAMMPSTest {
protected:
Group *group;
Domain *domain;
void SetUp() override
{
testbinary = "GroupTest";
LAMMPSTest::SetUp();
group = lmp->group;
domain = lmp->domain;
}
void atomic_system()
{
BEGIN_HIDE_OUTPUT();
command("units real");
command("lattice sc 1.0 origin 0.125 0.125 0.125");
command("region box block -2 2 -2 2 -2 2");
command("create_box 8 box");
command("create_atoms 1 box");
command("mass * 1.0");
command("region left block -2.0 -1.0 INF INF INF INF");
command("region right block 0.5 2.0 INF INF INF INF");
command("region top block INF INF -2.0 -1.0 INF INF");
command("set region left type 2");
command("set region right type 3");
END_HIDE_OUTPUT();
}
void molecular_system()
{
BEGIN_HIDE_OUTPUT();
command("fix props all property/atom mol rmass q");
END_HIDE_OUTPUT();
atomic_system();
BEGIN_HIDE_OUTPUT();
command("variable molid atom floor(id/4)+1");
command("variable charge atom 2.0*sin(PI/32*id)");
command("set atom * mol v_molid");
command("set atom * charge v_charge");
command("set type 1 mass 0.5");
command("set type 2*4 mass 2.0");
END_HIDE_OUTPUT();
}
};
TEST_F(GroupTest, NoBox)
{
ASSERT_EQ(group->ngroup, 1);
TEST_FAILURE(".*ERROR: Group command before simulation box.*", command("group none empty"););
}
TEST_F(GroupTest, EmptyDelete)
{
atomic_system();
BEGIN_HIDE_OUTPUT();
command("group new1 empty");
command("group new2 empty");
command("group new2 empty");
command("group new3 empty");
command("group new4 empty");
command("group new5 empty");
command("group new6 empty");
command("fix 1 new2 nve");
command("compute 1 new3 ke");
command("dump 1 new4 atom 50 dump.melt");
command("atom_modify first new5");
END_HIDE_OUTPUT();
ASSERT_EQ(group->ngroup, 7);
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new3 xxx"););
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new3 empty xxx"););
TEST_FAILURE(".*ERROR: Group command requires atom attribute molecule.*",
command("group new2 include molecule"););
BEGIN_HIDE_OUTPUT();
group->assign("new1 delete");
END_HIDE_OUTPUT();
ASSERT_EQ(group->ngroup, 6);
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group new2 delete xxx"););
TEST_FAILURE(".*ERROR: Cannot delete group all.*", command("group all delete"););
TEST_FAILURE(".*ERROR: Could not find group delete.*", command("group new0 delete"););
TEST_FAILURE(".*ERROR: Cannot delete group currently used by a fix.*",
command("group new2 delete"););
TEST_FAILURE(".*ERROR: Cannot delete group currently used by a compute.*",
command("group new3 delete"););
TEST_FAILURE(".*ERROR: Cannot delete group currently used by a dump.*",
command("group new4 delete"););
TEST_FAILURE(".*ERROR: Cannot delete group currently used by atom_modify.*",
command("group new5 delete"););
}
TEST_F(GroupTest, RegionClear)
{
atomic_system();
BEGIN_HIDE_OUTPUT();
command("group one region left");
command("group two region right");
command("group three empty");
command("group four region left");
command("group four region right");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 0);
ASSERT_EQ(group->count(group->find("four")), 32);
ASSERT_EQ(group->count(group->find("all")), lmp->atom->natoms);
ASSERT_EQ(group->count_all(), lmp->atom->natoms);
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three region left xxx"););
TEST_FAILURE(".*ERROR: Group region ID does not exist.*", command("group four region dummy"););
BEGIN_HIDE_OUTPUT();
command("group one clear");
command("group two clear");
command("group three clear");
command("group four clear");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 0);
ASSERT_EQ(group->count(group->find("two")), 0);
ASSERT_EQ(group->count(group->find("three")), 0);
ASSERT_EQ(group->count(group->find("four")), 0);
BEGIN_HIDE_OUTPUT();
command("delete_atoms region box");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("all")), 0);
}
TEST_F(GroupTest, SelectRestart)
{
atomic_system();
int *flags = new int[lmp->atom->natoms];
for (int i = 0; i < lmp->atom->natoms; ++i)
flags[i] = i & 1;
BEGIN_HIDE_OUTPUT();
command("group one region left");
command("group two region right");
group->create("half", flags);
group->find_or_create("three");
group->find_or_create("one");
command("group four union one two");
command("group five subtract all half four");
command("group top region top");
command("group six intersect half top");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 0);
ASSERT_EQ(group->count(group->find("half")), 32);
ASSERT_EQ(group->count(group->find("four")), 32);
ASSERT_EQ(group->count(group->find("five")), 16);
ASSERT_EQ(group->count(group->find("six")), 8);
ASSERT_EQ(group->count(group->find("half"), domain->find_region("top")), 8);
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->find_region("top")), 8.0);
BEGIN_HIDE_OUTPUT();
command("write_restart group.restart");
command("clear");
command("read_restart group.restart");
unlink("group.restart");
END_HIDE_OUTPUT();
group = lmp->group;
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 0);
ASSERT_EQ(group->count(group->find("half")), 32);
ASSERT_EQ(group->count(group->find("four")), 32);
ASSERT_EQ(group->count(group->find("five")), 16);
ASSERT_DOUBLE_EQ(group->mass(group->find("six")), 8.0);
BEGIN_HIDE_OUTPUT();
command("group four clear");
command("group five clear");
command("group six clear");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Group ID does not exist.*", command("group four union one two xxx"););
TEST_FAILURE(".*ERROR: Group ID does not exist.*",
command("group five subtract all half xxx"););
TEST_FAILURE(".*ERROR: Group ID does not exist.*",
command("group five intersect half top xxx"););
}
TEST_F(GroupTest, Molecular)
{
molecular_system();
BEGIN_HIDE_OUTPUT();
command("group one region left");
command("group two region right");
command("group half id 1:1000:2");
command("group top region top");
command("group three intersect half top");
command("group three include molecule");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("one")), 16);
ASSERT_EQ(group->count(group->find("two")), 16);
ASSERT_EQ(group->count(group->find("three")), 15);
ASSERT_DOUBLE_EQ(group->mass(group->find("half")), 40);
ASSERT_DOUBLE_EQ(group->mass(group->find("half"), domain->find_region("top")), 10);
ASSERT_DOUBLE_EQ(group->charge(group->find("top")), 0);
ASSERT_DOUBLE_EQ(group->charge(group->find("right"), domain->find_region("top")), 0);
TEST_FAILURE(".*ERROR: Illegal group command.*", command("group three include xxx"););
}
TEST_F(GroupTest, Dynamic)
{
atomic_system();
BEGIN_HIDE_OUTPUT();
command("variable step atom id<=step");
command("group half id 1:1000:2");
command("group grow dynamic half var step every 1");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 0);
BEGIN_HIDE_OUTPUT();
command("run 10 post no");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 5);
BEGIN_HIDE_OUTPUT();
command("group grow dynamic half var step every 1");
command("run 10 post no");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 10);
BEGIN_HIDE_OUTPUT();
command("group grow static");
command("run 10 post no");
command("group part variable step");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 10);
ASSERT_EQ(group->count(group->find("part")), 30);
BEGIN_HIDE_OUTPUT();
command("group grow dynamic half var step every 1");
command("run 10 post no");
END_HIDE_OUTPUT();
ASSERT_EQ(group->count(group->find("grow")), 20);
TEST_FAILURE(".*ERROR: Cannot subtract groups using a dynamic group.*",
command("group chunk subtract half grow"););
TEST_FAILURE(".*ERROR: Cannot union groups using a dynamic group.*",
command("group chunk union half grow"););
TEST_FAILURE(".*ERROR: Cannot intersect groups using a dynamic group.*",
command("group chunk intersect half grow"););
BEGIN_HIDE_OUTPUT();
command("group grow delete");
command("variable ramp equal step");
END_HIDE_OUTPUT();
ASSERT_EQ(group->ngroup, 3);
TEST_FAILURE(".*ERROR: Group dynamic cannot reference itself.*",
command("group half dynamic half region top"););
TEST_FAILURE(".*ERROR: Group dynamic parent group does not exist.*",
command("group half dynamic dummy region top"););
TEST_FAILURE(".*ERROR: Variable for group is invalid style.*",
command("group ramp variable ramp"););
TEST_FAILURE(".*ERROR: Variable name for group does not exist.*",
command("group ramp variable grow"););
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);
for (auto arg : env) {
if (arg == "-v") {
verbose = true;
}
}
}
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
int rv = RUN_ALL_TESTS();
MPI_Finalize();
return rv;
}

View File

@ -22,6 +22,7 @@
#include "variable.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstdlib>
#include <mpi.h>
@ -29,82 +30,61 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class KimCommandsTest : public ::testing::Test {
class KimCommandsTest : public LAMMPSTest {
protected:
LAMMPS *lmp;
Variable *variable;
void SetUp() override
{
const char *args[] = {"KimCommandsTest", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
testbinary = "KimCommandsTest";
LAMMPSTest::SetUp();
variable = lmp->input->variable;
}
};
TEST_F(KimCommandsTest, kim)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim command.*", command("kim"););
TEST_FAILURE(".*ERROR: Unknown kim subcommand.*", command("kim unknown"););
TEST_FAILURE(".*kim_init.*has been renamed to.*", command("kim_init"););
TEST_FAILURE(".*kim_interactions.*has been renamed to.*", command("kim_interactions"););
TEST_FAILURE(".*kim_param.*has been renamed to.*", command("kim_param"););
TEST_FAILURE(".*kim_property.*has been renamed to.*", command("kim_property"););
TEST_FAILURE(".*kim_query.*has been renamed to.*", command("kim_query"););
}
TEST_F(KimCommandsTest, kim_init)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim_init command.*",
lmp->input->one("kim_init"););
TEST_FAILURE(".*ERROR: Illegal kim_init command.*",
lmp->input->one("kim_init LennardJones_Ar real si"););
TEST_FAILURE(".*ERROR: Illegal 'kim init' command.*", command("kim init"););
TEST_FAILURE(".*ERROR: Illegal 'kim init' command.*",
command("kim init LennardJones_Ar real si"););
TEST_FAILURE(".*ERROR: LAMMPS unit_style lj not supported by KIM models.*",
lmp->input->one("kim_init LennardJones_Ar lj"););
command("kim init LennardJones_Ar lj"););
TEST_FAILURE(".*ERROR: LAMMPS unit_style micro not supported by KIM models.*",
lmp->input->one("kim_init LennardJones_Ar micro"););
command("kim init LennardJones_Ar micro"););
TEST_FAILURE(".*ERROR: LAMMPS unit_style nano not supported by KIM models.*",
lmp->input->one("kim_init LennardJones_Ar nano"););
TEST_FAILURE(".*ERROR: Unknown unit_style.*",
lmp->input->one("kim_init LennardJones_Ar new_style"););
TEST_FAILURE(".*ERROR: KIM Model name not found.*",
lmp->input->one("kim_init Unknown_Model real"););
command("kim init LennardJones_Ar nano"););
TEST_FAILURE(".*ERROR: Unknown unit_style.*", command("kim init LennardJones_Ar new_style"););
TEST_FAILURE(".*ERROR: KIM Model name not found.*", command("kim init Unknown_Model real"););
TEST_FAILURE(".*ERROR: Incompatible units for KIM Simulator Model, required units = metal.*",
lmp->input->one("kim_init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu real"););
command("kim init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu real"););
// TEST_FAILURE(".*ERROR: KIM Model does not support the requested unit system.*",
// lmp->input->one("kim_init ex_model_Ar_P_Morse real"););
// command("kim init ex_model_Ar_P_Morse real"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("kim_init LennardJones_Ar real");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("kim init LennardJones_Ar real");
END_HIDE_OUTPUT();
int ifix = lmp->modify->find_fix("KIM_MODEL_STORE");
ASSERT_GE(ifix, 0);
@ -114,205 +94,311 @@ TEST_F(KimCommandsTest, kim_interactions)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim_interactions command.*",
lmp->input->one("kim_interactions"););
TEST_FAILURE(".*ERROR: Illegal 'kim interactions' command.*", command("kim interactions"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("kim_init LennardJones_Ar real");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("kim init LennardJones_Ar real");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Must use 'kim_interactions' command "
TEST_FAILURE(".*ERROR: Must use 'kim interactions' command "
"after simulation box is defined.*",
lmp->input->one("kim_interactions Ar"););
command("kim interactions Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("kim_init LennardJones_Ar real");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("kim init LennardJones_Ar real");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Illegal kim_interactions command.*",
lmp->input->one("kim_interactions Ar Ar"););
TEST_FAILURE(".*ERROR: Illegal 'kim interactions' command.*",
command("kim interactions Ar Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 20 0 20 0 20");
lmp->input->one("create_box 4 box");
lmp->input->one("create_atoms 4 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("lattice fcc 4.4300");
command("region box block 0 20 0 20 0 20");
command("create_box 4 box");
command("create_atoms 4 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Illegal kim_interactions command.*",
lmp->input->one("kim_interactions Ar Ar"););
TEST_FAILURE(".*ERROR: Illegal 'kim interactions' command.*",
command("kim interactions Ar Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Must use 'kim_init' before 'kim_interactions'.*",
lmp->input->one("kim_interactions Ar"););
TEST_FAILURE(".*ERROR: Must use 'kim init' before 'kim interactions'.*",
command("kim interactions Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones_Ar real");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init LennardJones_Ar real");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: fixed_types cannot be used with a KIM Portable Model.*",
lmp->input->one("kim_interactions fixed_types"););
command("kim interactions fixed_types"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("units real");
lmp->input->one("pair_style kim LennardJones_Ar");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 4 box");
lmp->input->one("pair_coeff * * Ar Ar Ar Ar");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("units real");
command("pair_style kim LennardJones_Ar");
command("region box block 0 1 0 1 0 1");
command("create_box 4 box");
command("pair_coeff * * Ar Ar Ar Ar");
END_HIDE_OUTPUT();
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
lmp->input->one("lattice fcc 4.920");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
command("lattice fcc 4.920");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Species 'Ar' is not supported by this KIM Simulator Model.*",
lmp->input->one("kim_interactions Ar"););
command("kim interactions Ar"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
lmp->input->one("lattice fcc 4.08");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
lmp->input->one("kim_interactions Au");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
command("lattice fcc 4.08");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
command("kim interactions Au");
END_HIDE_OUTPUT();
// ASSERT_EQ(lmp->output->var_kim_periodic, 1);
// TEST_FAILURE(".*ERROR: Incompatible units for KIM Simulator Model.*",
// lmp->input->one("kim_interactions Au"););
// command("kim interactions Au"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones_Ar real");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
lmp->input->one("kim_interactions Ar");
lmp->input->one("mass 1 39.95");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init LennardJones_Ar real");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
command("kim interactions Ar");
command("mass 1 39.95");
END_HIDE_OUTPUT();
int ifix = lmp->modify->find_fix("KIM_MODEL_STORE");
ASSERT_GE(ifix, 0);
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init LennardJones_Ar real");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
command("kim interactions Ar");
command("mass 1 39.95");
command("run 1");
command("kim interactions Ar");
command("run 1");
END_HIDE_OUTPUT();
}
TEST_F(KimCommandsTest, kim_param)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim_param command.*", lmp->input->one("kim_param"););
TEST_FAILURE(".*ERROR: Incorrect arguments in kim_param command.\n"
"'kim_param get/set' is mandatory.*",
lmp->input->one("kim_param unknown shift 1 shift"););
TEST_FAILURE(".*ERROR: Must use 'kim_init' before 'kim_param'.*",
lmp->input->one("kim_param get shift 1 shift"););
TEST_FAILURE(".*ERROR: Illegal 'kim param' command.*", command("kim param"););
TEST_FAILURE(".*ERROR: Incorrect arguments in 'kim param' command.\n"
"'kim param get/set' is mandatory.*",
command("kim param unknown shift 1 shift"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init Sim_LAMMPS_LJcut_AkersonElliott_Alchemy_PbAu metal");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: kim_param can only be used with a KIM Portable Model.*",
lmp->input->one("kim_param get shift 1 shift"););
TEST_FAILURE(".*ERROR: 'kim param' can only be used with a KIM Portable Model.*",
command("kim param get shift 1 shift"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones612_UniversalShifted__MO_959249795837_003 real");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init LennardJones612_UniversalShifted__MO_959249795837_003 real");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Illegal 'kim param get' command.\nTo get the new "
"parameter values, pair style must be assigned.\nMust use 'kim"
" interactions' or 'pair_style kim' before 'kim param get'.*",
command("kim param get shift 1 shift"););
TEST_FAILURE(".*ERROR: Illegal 'kim param set' command.\nTo set the new "
"parameter values, pair style must be assigned.\nMust use 'kim"
" interactions' or 'pair_style kim' before 'kim param set'.*",
command("kim param set shift 1 2"););
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init LennardJones612_UniversalShifted__MO_959249795837_003 real");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
command("kim interactions Ar");
command("mass 1 39.95");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Illegal index '0' for "
"'shift' parameter with the extent of '1'.*",
lmp->input->one("kim_param get shift 0 shift"););
command("kim param get shift 0 shift"););
TEST_FAILURE(".*ERROR: Illegal index '2' for "
"'shift' parameter with the extent of '1'.*",
lmp->input->one("kim_param get shift 2 shift"););
command("kim param get shift 2 shift"););
TEST_FAILURE(".*ERROR: Illegal index_range.\nExpected integer "
"parameter\\(s\\) instead of '1.' in index_range.*",
lmp->input->one("kim_param get shift 1. shift"););
command("kim param get shift 1. shift"););
TEST_FAILURE(".*ERROR: Illegal index_range '1-2' for 'shift' "
"parameter with the extent of '1'.*",
lmp->input->one("kim_param get shift 1:2 shift"););
command("kim param get shift 1:2 shift"););
TEST_FAILURE(".*ERROR: Illegal index_range.\nExpected integer "
"parameter\\(s\\) instead of '1-2' in index_range.*",
lmp->input->one("kim_param get shift 1-2 shift"););
TEST_FAILURE(".*ERROR: Wrong number of arguments in 'kim_param "
command("kim param get shift 1-2 shift"););
TEST_FAILURE(".*ERROR: Wrong number of arguments in 'kim param "
"get' command.\nThe LAMMPS '3' variable names or "
"'s1 split' is mandatory.*",
lmp->input->one("kim_param get sigmas 1:3 s1 s2"););
TEST_FAILURE(".*ERROR: Wrong argument in kim_param get command.\nThis "
command("kim param get sigmas 1:3 s1 s2"););
TEST_FAILURE(".*ERROR: Wrong argument in 'kim param get' command.\nThis "
"Model does not have the requested 'unknown' parameter.*",
lmp->input->one("kim_param get unknown 1 unknown"););
TEST_FAILURE(".*ERROR: Wrong 'kim_param set' command.\n"
"To set the new parameter values, pair style must "
"be assigned.\nMust use 'kim_interactions' or"
"'pair_style kim' before 'kim_param set'.*",
lmp->input->one("kim_param set shift 1 2"););
command("kim param get unknown 1 unknown"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("kim_param get shift 1 shift");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("kim param get shift 1 shift");
END_HIDE_OUTPUT();
ASSERT_FALSE(lmp->input->variable->find("shift") == -1);
ASSERT_TRUE(std::string(lmp->input->variable->retrieve("shift")) == std::string("1"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones612_UniversalShifted__MO_959249795837_003 real");
lmp->input->one("lattice fcc 4.4300");
lmp->input->one("region box block 0 10 0 10 0 10");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
lmp->input->one("kim_interactions Ar");
lmp->input->one("mass 1 39.95");
if (!verbose) ::testing::internal::GetCapturedStdout();
ASSERT_FALSE(variable->find("shift") == -1);
ASSERT_THAT(variable->retrieve("shift"), StrEq("1"));
TEST_FAILURE(".*ERROR: Illegal index '2' for "
"'shift' parameter with the extent of '1'.*",
lmp->input->one("kim_param set shift 2 2"););
command("kim param set shift 2 2"););
TEST_FAILURE(".*ERROR: Illegal index_range.\nExpected integer "
"parameter\\(s\\) instead of '1.' in index_range.*",
lmp->input->one("kim_param set shift 1. shift"););
command("kim param set shift 1. shift"););
TEST_FAILURE(".*ERROR: Illegal index_range '1-2' for "
"'shift' parameter with the extent of '1'.*",
lmp->input->one("kim_param set shift 1:2 2"););
command("kim param set shift 1:2 2"););
TEST_FAILURE(".*ERROR: Wrong number of variable values for pair coefficients.*",
lmp->input->one("kim_param set sigmas 1:3 0.5523570 0.4989030"););
command("kim param set sigmas 1:3 0.5523570 0.4989030"););
TEST_FAILURE(".*ERROR: Wrong argument for pair coefficients.\nThis "
"Model does not have the requested '0.4989030' parameter.*",
lmp->input->one("kim_param set sigmas 1:1 0.5523570 0.4989030"););
command("kim param set sigmas 1:1 0.5523570 0.4989030"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("variable new_shift equal 2");
lmp->input->one("kim_param set shift 1 ${new_shift}");
lmp->input->one("kim_param get shift 1 shift");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("variable new_shift equal 2");
command("kim param set shift 1 ${new_shift}");
command("kim param get shift 1 shift");
END_HIDE_OUTPUT();
ASSERT_TRUE(std::string(lmp->input->variable->retrieve("shift")) == std::string("2"));
ASSERT_THAT(variable->retrieve("shift"), StrEq("2"));
TEST_FAILURE(".*ERROR: Illegal variable name in 'kim param get'.*",
command("kim param get cutoffs 1:3 list"););
TEST_FAILURE(".*ERROR: Illegal variable name in 'kim param get'.*",
command("kim param get cutoffs 1:3 cutoffs_1 cutoffs_2 list"););
TEST_FAILURE(".*ERROR: Illegal variable name in 'kim param get'.*",
command("kim param get cutoffs 1:3 split"););
TEST_FAILURE(".*ERROR: Illegal variable name in 'kim param get'.*",
command("kim param get cutoffs 1:3 cutoffs_1 cutoffs_2 split"););
TEST_FAILURE(".*ERROR: Illegal variable name in 'kim param get'.*",
command("kim param get cutoffs 1:3 explicit"););
TEST_FAILURE(".*ERROR: Illegal variable name in 'kim param get'.*",
command("kim param get cutoffs 1:3 cutoffs_1 cutoffs_2 explicit"););
TEST_FAILURE(".*ERROR: Wrong number of arguments in 'kim param get' "
"command.\nThe LAMMPS '3' variable names or 'cutoffs "
"split/list' is mandatory.*",
command("kim param get cutoffs 1:3 cutoffs"););
TEST_FAILURE(".*ERROR: Wrong number of arguments in 'kim param get' "
"command.\nThe LAMMPS '3' variable names or 'cutoffs_1 "
"split' is mandatory.*",
command("kim param get cutoffs 1:3 cutoffs_1 cutoffs_2"););
BEGIN_HIDE_OUTPUT();
command("kim param get cutoffs 1:3 cutoffs_1 cutoffs_2 cutoffs_3");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("cutoffs_1"), StrEq("2.20943"));
ASSERT_THAT(variable->retrieve("cutoffs_2"), StrEq("2.10252"));
ASSERT_THAT(variable->retrieve("cutoffs_3"), StrEq("5.666115"));
BEGIN_HIDE_OUTPUT();
command("kim param get cutoffs 1:3 cutoffs_1 cutoffs_2 cutoffs_3 explicit");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("cutoffs_1"), StrEq("2.20943"));
ASSERT_THAT(variable->retrieve("cutoffs_2"), StrEq("2.10252"));
ASSERT_THAT(variable->retrieve("cutoffs_3"), StrEq("5.666115"));
BEGIN_HIDE_OUTPUT();
command("kim param get cutoffs 1:3 cutoffs split");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("cutoffs_1"), StrEq("2.20943"));
ASSERT_THAT(variable->retrieve("cutoffs_2"), StrEq("2.10252"));
ASSERT_THAT(variable->retrieve("cutoffs_3"), StrEq("5.666115"));
BEGIN_HIDE_OUTPUT();
command("kim param get cutoffs 1:3 cutoffs list");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("cutoffs"), StrEq("2.20943 2.10252 5.666115"));
BEGIN_HIDE_OUTPUT();
command("kim param set cutoffs 1 2.21 cutoffs 2 2.11");
command("kim param get cutoffs 1:2 cutoffs list");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("cutoffs"), StrEq("2.21 2.11"));
BEGIN_HIDE_OUTPUT();
command("kim param set cutoffs 1:3 2.3 2.2 5.7");
command("kim param get cutoffs 1:3 cutoffs list");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("cutoffs"), StrEq("2.3 2.2 5.7"));
BEGIN_HIDE_OUTPUT();
command("clear");
command("units real");
command("lattice fcc 4.4300");
command("region box block 0 10 0 10 0 10");
command("create_box 1 box");
command("create_atoms 1 box");
command("mass 1 39.95");
command("pair_style kim LennardJones612_UniversalShifted__MO_959249795837_003");
command("pair_coeff * * Ar");
END_HIDE_OUTPUT();
BEGIN_HIDE_OUTPUT();
command("kim param get shift 1 shift");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("shift"), StrEq("1"));
BEGIN_HIDE_OUTPUT();
command("variable new_shift equal 2");
command("kim param set shift 1 ${new_shift}");
command("kim param get shift 1 shift");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("shift"), StrEq("2"));
}
TEST_F(KimCommandsTest, kim_property)
@ -324,144 +410,273 @@ TEST_F(KimCommandsTest, kim_property)
TEST_FAILURE(".*ERROR: Invalid Python version.\n"
"The kim-property Python package requires Python "
"3 >= 3.6 support.*",
lmp->input->one("kim_property"););
command("kim property"););
} else {
TEST_FAILURE(".*ERROR: Invalid kim_property command.*", lmp->input->one("kim_property"););
TEST_FAILURE(".*ERROR: Invalid kim_property command.*",
lmp->input->one("kim_property create"););
TEST_FAILURE(".*ERROR: Incorrect arguments in kim_property command.\n"
"'kim_property create/destroy/modify/remove/dump' "
TEST_FAILURE(".*ERROR: Invalid 'kim property' command.*", command("kim property"););
TEST_FAILURE(".*ERROR: Invalid 'kim property' command.*", command("kim property create"););
TEST_FAILURE(".*ERROR: Incorrect arguments in 'kim property' command."
"\n'kim property create/destroy/modify/remove/dump' "
"is mandatory.*",
lmp->input->one("kim_property unknown 1 atomic-mass"););
command("kim property unknown 1 atomic-mass"););
}
#if defined(KIM_EXTRA_UNITTESTS)
TEST_FAILURE(".*ERROR: Invalid 'kim property create' command.*",
command("kim property create 1"););
TEST_FAILURE(".*ERROR: Invalid 'kim property destroy' command.*",
command("kim property destroy 1 cohesive-potential-energy-cubic-crystal"););
TEST_FAILURE(".*ERROR: Invalid 'kim property modify' command.*",
command("kim property modify 1 key short-name"););
TEST_FAILURE(".*ERROR: There is no property instance to modify the content.*",
command("kim property modify 1 key short-name source-value 1 fcc"););
TEST_FAILURE(".*ERROR: Invalid 'kim property remove' command.*",
command("kim property remove 1 key"););
TEST_FAILURE(".*ERROR: There is no property instance to remove the content.*",
command("kim property remove 1 key short-name"););
TEST_FAILURE(".*ERROR: There is no property instance to dump the content.*",
command("kim property dump results.edn"););
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init LennardJones612_UniversalShifted__MO_959249795837_003 real");
command("kim property create 1 cohesive-potential-energy-cubic-crystal");
command("kim property modify 1 key short-name source-value 1 fcc");
command("kim property destroy 1");
END_HIDE_OUTPUT();
#endif
}
TEST_F(KimCommandsTest, kim_query)
{
if (!LAMMPS::is_installed_pkg("KIM")) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal kim_query command.*",
lmp->input->one("kim_query"););
TEST_FAILURE(".*ERROR: Must use 'kim_init' before 'kim_query'.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("kim_init LennardJones612_UniversalShifted__MO_959249795837_003 real");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Illegal kim_query command.\nThe keyword 'split' "
"must be followed by the name of the query function.*",
lmp->input->one("kim_query a0 split"););
TEST_FAILURE(".*ERROR: Illegal kim_query command.\nThe 'list' keyword "
"can not be used after 'split'.*",
lmp->input->one("kim_query a0 split list"););
TEST_FAILURE(".*ERROR: Illegal kim_query command.\nThe 'list' keyword "
"must be followed by \\('split' and\\) the name of the query "
"function.*", lmp->input->one("kim_query a0 list"););
TEST_FAILURE(".*ERROR: Illegal 'model' key in kim_query command.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"model=[MO_959249795837_003]"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.*", command("kim query"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe keyword 'split' "
"must be followed by the name of the query function.*",
command("kim query a0 split"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe keyword 'list' "
"must be followed by the name of the query function.*",
command("kim query a0 list"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe keyword 'index' "
"must be followed by the name of the query function.*",
command("kim query a0 index"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe 'list' keyword "
"can not be used after 'split'.*",
command("kim query a0 split list"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe 'index' keyword "
"can not be used after 'split'.*",
command("kim query a0 split index"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe 'split' keyword "
"can not be used after 'list'.*",
command("kim query a0 list split"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe 'index' keyword "
"can not be used after 'list'.*",
command("kim query a0 list index"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe 'list' keyword "
"can not be used after 'index'.*",
command("kim query a0 index list"););
TEST_FAILURE(".*ERROR: Illegal 'kim query' command.\nThe 'split' keyword "
"can not be used after 'index'.*",
command("kim query a0 index split"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `crystal` "
"to kim_query is wrong. The query format is the "
"to 'kim query' is wrong. The query format is the "
"keyword=\\[value\\], where value is always an array of one "
"or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal"););
"or more comma-separated items.*",
command("kim query a0 get_lattice_constant_cubic "
"crystal"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=fcc` to kim_query is wrong. The query format is the "
"crystal=fcc` to 'kim query' is wrong. The query format is the "
"keyword=\\[value\\], where value is always an array of one "
"or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal=fcc"););
"or more comma-separated items.*",
command("kim query a0 get_lattice_constant_cubic "
"crystal=fcc"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=\\[fcc` to kim_query is wrong. The query format is "
"crystal=\\[fcc` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal=[fcc"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=fcc\\]` to kim_query is wrong. The query format is "
"one or more comma-separated items.*",
command("kim query a0 get_lattice_constant_cubic "
"crystal=[fcc"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `"
"crystal=fcc\\]` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one("kim_query a0 get_lattice_constant_cubic "
"crystal=fcc]"););
std::string squery("kim_query a0 get_lattice_constant_cubic ");
squery += "crystal=[\"fcc\"] species=\"Al\",\"Ni\" units=[\"angstrom\"]";
"one or more comma-separated items.*",
command("kim query a0 get_lattice_constant_cubic "
"crystal=fcc]"););
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\"Al\",\"Ni\"` to kim_query is wrong. The query format is "
std::string squery = "kim query a0 get_lattice_constant_cubic "
"crystal=[\"fcc\"] species=\"Al\",\"Ni\" units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\"Al\",\"Ni\"` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one(squery););
"one or more comma-separated items.*",
command(squery););
squery = "kim_query a0 get_lattice_constant_cubic ";
squery += "crystal=[\"fcc\"] species=\"Al\",\"Ni\", units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\"Al\",\"Ni\",` to kim_query is wrong. The query format is "
squery = "kim query a0 get_lattice_constant_cubic crystal=[fcc] species=Al,Ni units=[angstrom]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"Al,Ni` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
lmp->input->one(squery););
"one or more comma-separated items.*",
command(squery););
squery = "kim_query a0 get_lattice_constant_cubic crystal=[fcc] "
"species=[Al]";
TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
squery =
"kim query a0 get_lattice_constant_cubic crystal=[fcc] species=Al,Ni, units=[angstrom]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"Al,Ni,` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
command(squery););
squery = "kim_query a0 get_lattice_constant_cubic crystal=[fcc] "
"units=[\"angstrom\"]";
TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
squery =
"kim query a0 get_lattice_constant_cubic crystal=[fcc] species=[Al,Ni, units=[angstrom]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\\[Al,Ni,` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
command(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
// squery = "kim_query latconst split get_lattice_constant_hexagonal ";
// squery += "crystal=[\"hcp\"] species=[\"Zr\"] units=[\"angstrom\"]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
squery =
"kim query a0 get_lattice_constant_cubic crystal=[fcc] species=Al,Ni], units=[angstrom]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"Al,Ni\\],` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
command(squery););
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_1")) ==
// std::string("3.234055244384789")));
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst_2")) ==
// std::string("5.167650199630013")));
squery = "kim query a0 get_lattice_constant_cubic crystal=[fcc] species=Al,\"Ni\"], "
"units=[angstrom]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"Al,\"Ni\"\\],` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
command(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_Mendelev_2007_Zr__MO_848899341753_000 metal");
// squery = "kim_query latconst list get_lattice_constant_hexagonal ";
// squery += "crystal=[hcp] species=[Zr] units=[angstrom]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
squery = "kim query a0 get_lattice_constant_cubic crystal=[fcc] species=\"Al\",Ni], "
"units=[angstrom]";
TEST_FAILURE(".*ERROR: Illegal query format.\nInput argument of `species="
"\"Al\",Ni\\],` to 'kim query' is wrong. The query format is "
"the keyword=\\[value\\], where value is always an array of "
"one or more comma-separated items.*",
command(squery););
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("latconst")) ==
// std::string("3.234055244384789 5.167650199630013")));
squery = "kim query a0 get_lattice_constant_cubic crystal=[\"fcc\"] species=[\"Al\"]";
TEST_FAILURE(".*ERROR: Illegal query format.\nMust use 'kim init' before "
"'kim query' or must provide the model name after query "
"function with the format of 'model=\\[model_name\\]'.*",
command(squery););
// squery = "kim_query latconst list get_lattice_constant_hexagonal ";
// squery += "crystal=[bcc] species=[Zr] units=[angstrom]";
// TEST_FAILURE(".*ERROR: OpenKIM query failed:.*", lmp->input->one(squery););
squery = "kim query a0 get_lattice_constant_cubic crystal=[fcc] species=[Al]";
TEST_FAILURE(".*ERROR: Illegal query format.\nMust use 'kim init' before "
"'kim query' or must provide the model name after query "
"function with the format of 'model=\\[model_name\\]'.*",
command(squery););
// if (!verbose) ::testing::internal::CaptureStdout();
// lmp->input->one("clear");
// lmp->input->one("kim_init EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005 metal");
// squery = "kim_query alpha get_linear_thermal_expansion_coefficient_cubic ";
// squery += "crystal=[fcc] species=[Al] units=[1/K] temperature=[293.15] ";
// squery += "temperature_units=[K]";
// lmp->input->one(squery);
// if (!verbose) ::testing::internal::GetCapturedStdout();
squery = "kim query a0 get_lattice_constant_cubic crystal=[\"fcc\"] species=[Al]";
TEST_FAILURE(".*ERROR: Illegal query format.\nMust use 'kim init' before "
"'kim query' or must provide the model name after query "
"function with the format of 'model=\\[model_name\\]'.*",
command(squery););
// ASSERT_TRUE((std::string(lmp->input->variable->retrieve("alpha")) ==
// std::string("1.654960564704273e-05")));
#if defined(KIM_EXTRA_UNITTESTS)
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim query latconst_1 get_lattice_constant_cubic "
"crystal=[fcc] species=[Al] units=[angstrom] "
"model=[EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005]");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("latconst_1"), StrEq("4.032082033157349"));
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005 metal");
command("kim query latconst_1 get_lattice_constant_cubic crystal=[fcc] species=[Al] "
"units=[angstrom]");
command("kim query latconst_2 get_lattice_constant_cubic crystal=[fcc] species=[Al] "
"units=[angstrom] "
"model=[LennardJones612_UniversalShifted__MO_959249795837_003]");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("latconst_1"), StrEq("4.032082033157349"));
ASSERT_THAT(variable->retrieve("latconst_2"), StrEq("3.328125931322575"));
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init EAM_Dynamo_MendelevAckland_2007v3_Zr__MO_004835508849_000 metal");
command("kim query latconst split get_lattice_constant_hexagonal crystal=[hcp] species=[Zr] "
"units=[angstrom]");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("latconst_1"), StrEq("3.234055244384789"));
ASSERT_THAT(variable->retrieve("latconst_2"), StrEq("5.167650199630013"));
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim query latconst index get_lattice_constant_hexagonal "
"crystal=[hcp] species=[Zr] units=[angstrom] "
"model=[EAM_Dynamo_MendelevAckland_2007v3_Zr__MO_004835508849_000]");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("latconst"), StrEq("3.234055244384789"));
BEGIN_HIDE_OUTPUT();
command("variable latconst delete");
command("clear");
command("kim init EAM_Dynamo_MendelevAckland_2007v3_Zr__MO_004835508849_000 metal");
command("kim query latconst list get_lattice_constant_hexagonal crystal=[hcp] species=[Zr] "
"units=[angstrom]");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("latconst"), StrEq("3.234055244384789 5.167650199630013"));
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim init EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005 metal");
command("kim query alpha get_linear_thermal_expansion_coefficient_cubic "
"crystal=[fcc] species=[Al] units=[1/K] temperature=[293.15] "
"temperature_units=[K]");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("alpha"), StrEq("1.654960564704273e-05"));
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim query model_list list get_available_models species=[Al]");
END_HIDE_OUTPUT();
std::string model_list = variable->retrieve("model_list");
auto n = model_list.find("EAM_Dynamo_ErcolessiAdams_1994_Al__MO_123629422045_005");
ASSERT_TRUE(n != std::string::npos);
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim query model_name index get_available_models species=[Al]");
command("variable model_name delete");
END_HIDE_OUTPUT();
BEGIN_HIDE_OUTPUT();
command("clear");
command("kim query model_name index get_available_models "
"species=[Al] potential_type=[eam,meam]");
command("variable model_name delete");
command("kim query model_name index get_available_models "
"species=[Al] potential_type=[\"eam\",\"meam\"]");
command("variable model_name delete");
command("kim query model_name index get_available_models "
"species=[Al] potential_type=[eam,\"meam\"]");
command("variable model_name delete");
command("kim query model_name index get_available_models "
"species=[Al] potential_type=[\"eam\",meam]");
command("variable model_name delete");
END_HIDE_OUTPUT();
#endif
}
} // namespace LAMMPS_NS
@ -470,7 +685,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -22,6 +22,7 @@
#include "utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstdio>
#include <cstring>
@ -32,12 +33,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -45,49 +40,22 @@ using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class LatticeRegionTest : public ::testing::Test {
class LatticeRegionTest : public LAMMPSTest {
protected:
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {"LatticeRegionTest", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
lmp->input->one("units metal");
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
testbinary = "LatticeRegionTest";
LAMMPSTest::SetUp();
command("units metal");
}
};
TEST_F(LatticeRegionTest, lattice_none)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice none 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice none 2.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::NONE);
ASSERT_EQ(lattice->xlattice, 2.0);
@ -96,15 +64,15 @@ TEST_F(LatticeRegionTest, lattice_none)
ASSERT_EQ(lattice->nbasis, 0);
ASSERT_EQ(lattice->basis, nullptr);
TEST_FAILURE(".*ERROR: Illegal lattice command.*", lmp->input->one("lattice"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", lmp->input->one("lattice xxx"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", lmp->input->one("lattice none 1.0 origin"););
TEST_FAILURE(".*ERROR: Expected floating point.*", lmp->input->one("lattice none xxx"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice xxx"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice none 1.0 origin"););
TEST_FAILURE(".*ERROR: Expected floating point.*", command("lattice none xxx"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("units lj");
lmp->input->one("lattice none 1.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("units lj");
command("lattice none 1.0");
END_HIDE_OUTPUT();
lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->xlattice, 1.0);
ASSERT_EQ(lattice->ylattice, 1.0);
@ -113,10 +81,9 @@ TEST_F(LatticeRegionTest, lattice_none)
TEST_F(LatticeRegionTest, lattice_sc)
{
::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 1.0 spacing 1.5 2.0 3.0");
auto output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
BEGIN_CAPTURE_OUTPUT();
command("lattice sc 1.0 spacing 1.5 2.0 3.0");
auto output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 1.50* 2.0* 3.0*.*"));
auto lattice = lmp->domain->lattice;
@ -124,10 +91,9 @@ TEST_F(LatticeRegionTest, lattice_sc)
ASSERT_EQ(lattice->ylattice, 2.0);
ASSERT_EQ(lattice->zlattice, 3.0);
::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 2.0");
output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
BEGIN_CAPTURE_OUTPUT();
command("lattice sc 2.0");
output = END_CAPTURE_OUTPUT();
ASSERT_THAT(output, MatchesRegex(".*Lattice spacing in x,y,z = 2.0* 2.0* 2.0*.*"));
lattice = lmp->domain->lattice;
@ -151,43 +117,42 @@ TEST_F(LatticeRegionTest, lattice_sc)
ASSERT_EQ(lattice->basis[0][2], 0.0);
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice sc 1.0 origin 1.0 1.0 1.0"););
command("lattice sc 1.0 origin 1.0 1.0 1.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice sc 1.0 origin 1.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice sc 1.0 origin 1.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice sc 1.0 origin 0.0 0.0 0.0 xxx"););
command("lattice sc 1.0 origin 0.0 0.0 0.0 xxx"););
TEST_FAILURE(".*ERROR: Expected floating point.*",
lmp->input->one("lattice sc 1.0 origin xxx 1.0 1.0"););
command("lattice sc 1.0 origin xxx 1.0 1.0"););
TEST_FAILURE(".*ERROR: Lattice orient vectors are not orthogonal.*",
lmp->input->one("lattice sc 1.0 orient x 2 2 0"););
command("lattice sc 1.0 orient x 2 2 0"););
TEST_FAILURE(".*ERROR: Lattice orient vectors are not right-handed.*",
lmp->input->one("lattice sc 1.0 orient y 0 -1 0"););
command("lattice sc 1.0 orient y 0 -1 0"););
TEST_FAILURE(".*ERROR: Lattice spacings are invalid.*",
lmp->input->one("lattice sc 1.0 spacing 0.0 1.0 1.0"););
command("lattice sc 1.0 spacing 0.0 1.0 1.0"););
TEST_FAILURE(".*ERROR: Lattice spacings are invalid.*",
lmp->input->one("lattice sc 1.0 spacing 1.0 -0.1 1.0"););
command("lattice sc 1.0 spacing 1.0 -0.1 1.0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("units lj");
lmp->input->one("lattice sc 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("units lj");
command("lattice sc 2.0");
END_HIDE_OUTPUT();
lattice = lmp->domain->lattice;
ASSERT_DOUBLE_EQ(lattice->xlattice, pow(0.5, 1.0 / 3.0));
ASSERT_DOUBLE_EQ(lattice->ylattice, pow(0.5, 1.0 / 3.0));
ASSERT_DOUBLE_EQ(lattice->zlattice, pow(0.5, 1.0 / 3.0));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice sc 1.0"););
command("lattice sc 1.0"););
}
TEST_F(LatticeRegionTest, lattice_bcc)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice bcc 4.2 orient x 1 1 0 orient y -1 1 0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice bcc 4.2 orient x 1 1 0 orient y -1 1 0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::BCC);
ASSERT_DOUBLE_EQ(lattice->xlattice, sqrt(2.0) * 4.2);
@ -201,18 +166,18 @@ TEST_F(LatticeRegionTest, lattice_bcc)
ASSERT_EQ(lattice->basis[1][1], 0.5);
ASSERT_EQ(lattice->basis[1][2], 0.5);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice bcc 1.0"););
command("lattice bcc 1.0"););
}
TEST_F(LatticeRegionTest, lattice_fcc)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 3.5 origin 0.5 0.5 0.5");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 3.5 origin 0.5 0.5 0.5");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::FCC);
ASSERT_DOUBLE_EQ(lattice->xlattice, 3.5);
@ -233,24 +198,23 @@ TEST_F(LatticeRegionTest, lattice_fcc)
ASSERT_EQ(lattice->basis[3][2], 0.5);
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice fcc 1.0 basis 0.0 0.0 0.0"););
command("lattice fcc 1.0 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice fcc 1.0 a1 0.0 1.0 0.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice fcc 1.0 orient w 1 0 0"););
command("lattice fcc 1.0 a1 0.0 1.0 0.0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*", command("lattice fcc 1.0 orient w 1 0 0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice fcc 1.0"););
command("lattice fcc 1.0"););
}
TEST_F(LatticeRegionTest, lattice_hcp)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice hcp 3.0 orient z 0 0 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice hcp 3.0 orient z 0 0 1");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::HCP);
ASSERT_DOUBLE_EQ(lattice->xlattice, 3.0);
@ -280,21 +244,21 @@ TEST_F(LatticeRegionTest, lattice_hcp)
ASSERT_DOUBLE_EQ(lattice->a3[2], sqrt(8.0 / 3.0));
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice hcp 1.0 a2 0.0 1.0 0.0"););
command("lattice hcp 1.0 a2 0.0 1.0 0.0"););
TEST_FAILURE(".*ERROR: Invalid option in lattice command for non-custom style.*",
lmp->input->one("lattice hcp 1.0 a3 0.0 1.0 0.0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
command("lattice hcp 1.0 a3 0.0 1.0 0.0"););
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice hcp 1.0"););
command("lattice hcp 1.0"););
}
TEST_F(LatticeRegionTest, lattice_diamond)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice diamond 4.1 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice diamond 4.1 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::DIAMOND);
ASSERT_DOUBLE_EQ(lattice->xlattice, 6.6952719636073539);
@ -335,19 +299,19 @@ TEST_F(LatticeRegionTest, lattice_diamond)
ASSERT_EQ(lattice->a3[1], 0.0);
ASSERT_EQ(lattice->a3[2], 1.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice diamond 1.0"););
command("lattice diamond 1.0"););
}
TEST_F(LatticeRegionTest, lattice_sq)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
lmp->input->one("lattice sq 3.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
command("lattice sq 3.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::SQ);
ASSERT_DOUBLE_EQ(lattice->xlattice, 3.0);
@ -358,23 +322,22 @@ TEST_F(LatticeRegionTest, lattice_sq)
ASSERT_EQ(lattice->basis[0][1], 0.0);
ASSERT_EQ(lattice->basis[0][2], 0.0);
TEST_FAILURE(
".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice sq 1.0 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
command("lattice sq 1.0 orient x 1 1 2 orient y -1 1 0 orient z -1 -1 1"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 3");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice sq 1.0"););
command("lattice sq 1.0"););
}
TEST_F(LatticeRegionTest, lattice_sq2)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
lmp->input->one("lattice sq2 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
command("lattice sq2 2.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::SQ2);
ASSERT_DOUBLE_EQ(lattice->xlattice, 2.0);
@ -388,19 +351,19 @@ TEST_F(LatticeRegionTest, lattice_sq2)
ASSERT_EQ(lattice->basis[1][1], 0.5);
ASSERT_EQ(lattice->basis[1][2], 0.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 3");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice sq2 1.0"););
command("lattice sq2 1.0"););
}
TEST_F(LatticeRegionTest, lattice_hex)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
lmp->input->one("lattice hex 2.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 2");
command("lattice hex 2.0");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::HEX);
ASSERT_DOUBLE_EQ(lattice->xlattice, 2.0);
@ -423,34 +386,34 @@ TEST_F(LatticeRegionTest, lattice_hex)
ASSERT_EQ(lattice->a3[1], 0.0);
ASSERT_EQ(lattice->a3[2], 1.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 3");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("dimension 3");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Lattice style incompatible with simulation dimension.*",
lmp->input->one("lattice hex 1.0"););
command("lattice hex 1.0"););
}
TEST_F(LatticeRegionTest, lattice_custom)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("variable a equal 4.34");
lmp->input->one("variable b equal $a*sqrt(3.0)");
lmp->input->one("variable c equal $a*sqrt(8.0/3.0)");
lmp->input->one("variable t equal 1.0/3.0");
lmp->input->one("variable f equal 5.0/6.0");
lmp->input->one("lattice custom 1.0 "
"a1 $a 0.0 0.0 "
"a2 0.0 $b 0.0 "
"a3 0.0 0.0 $c "
"basis 0.0 0.0 0.0 "
"basis 0.5 0.5 0.0 "
"basis $t 0.0 0.5 "
"basis $f 0.5 0.5 "
"basis 0.0 0.0 0.625 "
"basis 0.5 0.5 0.625 "
"basis $t 0.0 0.125 "
"basis $f 0.5 0.125 ");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("variable a equal 4.34");
command("variable b equal $a*sqrt(3.0)");
command("variable c equal $a*sqrt(8.0/3.0)");
command("variable t equal 1.0/3.0");
command("variable f equal 5.0/6.0");
command("lattice custom 1.0 "
"a1 $a 0.0 0.0 "
"a2 0.0 $b 0.0 "
"a3 0.0 0.0 $c "
"basis 0.0 0.0 0.0 "
"basis 0.5 0.5 0.0 "
"basis $t 0.0 0.5 "
"basis $f 0.5 0.5 "
"basis 0.0 0.0 0.625 "
"basis 0.5 0.5 0.625 "
"basis $t 0.0 0.125 "
"basis $f 0.5 0.125 ");
END_HIDE_OUTPUT();
auto lattice = lmp->domain->lattice;
ASSERT_EQ(lattice->style, Lattice::CUSTOM);
ASSERT_DOUBLE_EQ(lattice->xlattice, 4.34);
@ -492,48 +455,48 @@ TEST_F(LatticeRegionTest, lattice_custom)
ASSERT_DOUBLE_EQ(lattice->a3[2], 4.34 * sqrt(8.0 / 3.0));
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice custom 1.0 basis -0.1 0 0"););
command("lattice custom 1.0 basis -0.1 0 0"););
TEST_FAILURE(".*ERROR: Illegal lattice command.*",
lmp->input->one("lattice custom 1.0 basis 0.0 1.0 0"););
command("lattice custom 1.0 basis 0.0 1.0 0"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("dimension 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: No basis atoms in lattice.*", lmp->input->one("lattice custom 1.0"););
BEGIN_HIDE_OUTPUT();
command("dimension 2");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: No basis atoms in lattice.*", command("lattice custom 1.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 origin 0.5 0.5 0.5 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 origin 0.5 0.5 0.5 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 a1 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 a1 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 a2 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 a2 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
TEST_FAILURE(".*ERROR: Lattice settings are not compatible with 2d simulation.*",
lmp->input->one("lattice custom 1.0 a3 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
command("lattice custom 1.0 a3 1.0 1.0 1.0 basis 0.0 0.0 0.0"););
}
TEST_F(LatticeRegionTest, region_fail)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice none 2.0");
lmp->input->one("region box block 0 1 0 1 0 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice none 2.0");
command("region box block 0 1 0 1 0 1");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Create_atoms command before simulation box is defined.*",
lmp->input->one("create_atoms 1 box"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("create_box 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
command("create_atoms 1 box"););
BEGIN_HIDE_OUTPUT();
command("create_box 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Cannot create atoms with undefined lattice.*",
lmp->input->one("create_atoms 1 box"););
command("create_atoms 1 box"););
}
TEST_F(LatticeRegionTest, region_block_lattice)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 1.5");
lmp->input->one("region box block 0 2 0 2 0 2 units lattice");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice sc 1.5");
command("region box block 0 2 0 2 0 2 units lattice");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
auto x = lmp->atom->x;
@ -554,12 +517,12 @@ TEST_F(LatticeRegionTest, region_block_lattice)
TEST_F(LatticeRegionTest, region_block_box)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice sc 1.5 origin 0.75 0.75 0.75");
lmp->input->one("region box block 0 2 0 2 0 2 units box");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice sc 1.5 origin 0.75 0.75 0.75");
command("region box block 0 2 0 2 0 2 units box");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
auto x = lmp->atom->x;
@ -571,93 +534,93 @@ TEST_F(LatticeRegionTest, region_block_box)
TEST_F(LatticeRegionTest, region_cone)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box cone x 1.0 1.0 0.5 2.1 0.0 2.0");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
lmp->input->one("write_dump all atom init.lammpstrj");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box cone x 1.0 1.0 0.5 2.1 0.0 2.0");
command("create_box 1 box");
command("create_atoms 1 region box");
command("write_dump all atom init.lammpstrj");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 42);
}
TEST_F(LatticeRegionTest, region_cylinder)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box cylinder z 1.0 1.0 2.1 0.0 2.0 ");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box cylinder z 1.0 1.0 2.1 0.0 2.0 ");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 114);
}
TEST_F(LatticeRegionTest, region_prism)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice bcc 2.5 origin 0.75 0.75 0.75");
lmp->input->one("region box prism 0 2 0 2 0 2 0.5 0.0 0.0");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice bcc 2.5 origin 0.75 0.75 0.75");
command("region box prism 0 2 0 2 0 2 0.5 0.0 0.0");
command("create_box 1 box");
command("create_atoms 1 box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 1);
ASSERT_EQ(lmp->atom->natoms, 16);
}
TEST_F(LatticeRegionTest, region_sphere)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box sphere 1.0 1.0 1.0 1.1");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box sphere 1.0 1.0 1.0 1.1");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 14);
}
TEST_F(LatticeRegionTest, region_union)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region part1 sphere 2.0 1.0 1.0 1.1");
lmp->input->one("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
lmp->input->one("region box union 2 part1 part2");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region part1 sphere 2.0 1.0 1.0 1.1");
command("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
command("region box union 2 part1 part2");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 67);
}
TEST_F(LatticeRegionTest, region_intersect)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region part1 sphere 2.0 1.0 1.0 1.8");
lmp->input->one("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
lmp->input->one("region box intersect 2 part1 part2");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region box");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region part1 sphere 2.0 1.0 1.0 1.8");
command("region part2 block 0.0 2.0 0.0 2.0 0.0 2.0");
command("region box intersect 2 part1 part2");
command("create_box 1 box");
command("create_atoms 1 region box");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 21);
}
TEST_F(LatticeRegionTest, region_plane)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("lattice fcc 2.5 origin 0.5 0.5 0.5");
lmp->input->one("region box block 0.0 2.0 0.0 2.0 0.0 2.0");
lmp->input->one("region part1 plane 0.5 1.0 0.0 0.75 0.0 0.0");
lmp->input->one("region part2 plane 1.5 1.0 0.0 0.75 0.0 0.0 side out");
lmp->input->one("region atoms intersect 2 part1 part2");
lmp->input->one("create_box 1 box");
lmp->input->one("create_atoms 1 region atoms");
lmp->input->one("write_dump all atom init.lammpstrj");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("lattice fcc 2.5 origin 0.5 0.5 0.5");
command("region box block 0.0 2.0 0.0 2.0 0.0 2.0");
command("region part1 plane 0.5 1.0 0.0 0.75 0.0 0.0");
command("region part2 plane 1.5 1.0 0.0 0.75 0.0 0.0 side out");
command("region atoms intersect 2 part1 part2");
command("create_box 1 box");
command("create_atoms 1 region atoms");
command("write_dump all atom init.lammpstrj");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->domain->triclinic, 0);
ASSERT_EQ(lmp->atom->natoms, 16);
}
@ -669,7 +632,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -0,0 +1,257 @@
// unit tests for checking LAMMPS MPI load balancing
#define LAMMPS_LIB_MPI 1
#include "lammps.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "neighbor.h"
#include "input.h"
#include "timer.h"
#include "info.h"
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/test_mpi_main.h"
using ::testing::ExitedWithCode;
using ::testing::HasSubstr;
using ::testing::StartsWith;
using ::testing::StrEq;
namespace LAMMPS_NS
{
class MPILoadBalanceTest : public ::testing::Test {
public:
void command(const std::string &line) { lmp->input->one(line); }
protected:
const char *testbinary = "LAMMPSTest";
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {testbinary, "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
InitSystem();
if (!verbose) ::testing::internal::GetCapturedStdout();
}
virtual void InitSystem()
{
command("boundary f f f");
command("units lj");
command("atom_style atomic");
command("atom_modify map yes");
command("region box block 0 20 0 20 0 20");
command("create_box 1 box");
command("mass 1 1.0");
command("pair_style lj/cut 2.5");
command("pair_coeff 1 1 1.0 1.0 2.5");
command("neighbor 0.3 bin");
command("neigh_modify every 20 delay 0 check no");
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
lmp = nullptr;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
};
TEST_F(MPILoadBalanceTest, grid_yz)
{
command("create_atoms 1 single 0 0 0");
command("create_atoms 1 single 0 0 5");
command("create_atoms 1 single 0 5 0");
command("create_atoms 1 single 0 5 5");
command("create_atoms 1 single 5 0 0");
command("create_atoms 1 single 5 0 5");
command("create_atoms 1 single 5 5 0");
command("create_atoms 1 single 5 5 5");
ASSERT_EQ(lmp->atom->natoms, 8);
ASSERT_EQ(lmp->comm->nprocs, 4);
// initial state
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 8);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
}
command("balance 1 x uniform y 0.125 z uniform");
// state after balance command
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 4);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 4);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
}
command("balance 1 x uniform y 0.125 z 0.125");
// state after second balance command
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
}
}
TEST_F(MPILoadBalanceTest, rcb)
{
command("comm_style tiled");
command("create_atoms 1 single 0 0 0");
command("create_atoms 1 single 0 0 5");
command("create_atoms 1 single 0 5 0");
command("create_atoms 1 single 0 5 5");
command("create_atoms 1 single 5 0 0");
command("create_atoms 1 single 5 0 5");
command("create_atoms 1 single 5 5 0");
command("create_atoms 1 single 5 5 5");
// initial state
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 8);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
}
command("balance 1 rcb");
// state after balance command
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 2);
break;
}
// box dimensions should have minimal size
double dx = lmp->domain->subhi[0] - lmp->domain->sublo[0];
double dy = lmp->domain->subhi[1] - lmp->domain->sublo[1];
double dz = lmp->domain->subhi[2] - lmp->domain->sublo[2];
ASSERT_GT(dx, lmp->neighbor->skin);
ASSERT_GT(dy, lmp->neighbor->skin);
ASSERT_GT(dz, lmp->neighbor->skin);
}
TEST_F(MPILoadBalanceTest, rcb_min_size)
{
GTEST_SKIP();
// TODO minimum domain size is not enforced right now
// skipping for now to allow other MPI tests to get merged
command("comm_style tiled");
command("create_atoms 1 single 0 0 0");
command("create_atoms 1 single 0 0 0.25");
command("create_atoms 1 single 0 0.25 0");
command("create_atoms 1 single 0 0.25 0.25");
command("create_atoms 1 single 0.25 0 0");
command("create_atoms 1 single 0.25 0 0.25");
command("create_atoms 1 single 0.25 0.25 0");
command("create_atoms 1 single 0.25 0.25 0.25");
// initial state
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 8);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
}
// this should fail and not change the boxes
// or keep them at a minimum size
command("balance 1 rcb");
// state after balance command
switch(lmp->comm->me) {
case 0:
ASSERT_EQ(lmp->atom->nlocal, 8);
break;
case 1:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 2:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
case 3:
ASSERT_EQ(lmp->atom->nlocal, 0);
break;
}
// box dimensions should have minimal size
double dx = lmp->domain->subhi[0] - lmp->domain->sublo[0];
double dy = lmp->domain->subhi[1] - lmp->domain->sublo[1];
double dz = lmp->domain->subhi[2] - lmp->domain->sublo[2];
ASSERT_GT(dx, lmp->neighbor->skin);
ASSERT_GT(dy, lmp->neighbor->skin);
ASSERT_GT(dz, lmp->neighbor->skin);
}
}

View File

@ -21,6 +21,7 @@
#include "utils.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstdio>
#include <mpi.h>
@ -28,12 +29,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
@ -41,49 +36,22 @@ using ::testing::MatchesRegex;
#define GETIDX(i) lmp->atom->map(i)
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
#define STRINGIFY(val) XSTR(val)
#define XSTR(val) #val
class ResetIDsTest : public ::testing::Test {
class ResetIDsTest : public LAMMPSTest {
protected:
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {"ResetIDsTest", "-log", "none", "-nocite", "-echo", "screen"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
Info *info = new Info(lmp);
testbinary = "ResetIDsTest";
LAMMPSTest::SetUp();
if (info->has_style("atom", "full")) {
lmp->input->one("variable input_dir index " STRINGIFY(TEST_INPUT_FOLDER));
lmp->input->one("include ${input_dir}/in.fourmol");
BEGIN_HIDE_OUTPUT();
command("variable input_dir index " STRINGIFY(TEST_INPUT_FOLDER));
command("include ${input_dir}/in.fourmol");
END_HIDE_OUTPUT();
}
delete info;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
};
@ -124,9 +92,9 @@ TEST_F(ResetIDsTest, MolIDAll)
// the original data file has two different molecule IDs
// for two residues of the same molecule/fragment.
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids all");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids all");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(1)], 1);
ASSERT_EQ(molid[GETIDX(2)], 1);
@ -166,12 +134,12 @@ TEST_F(ResetIDsTest, DeletePlusAtomID)
auto molid = lmp->atom->molecule;
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group twowater molecule 4:6:2");
lmp->input->one("delete_atoms group twowater compress no bond yes");
lmp->input->one("reset_mol_ids all");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group twowater molecule 4:6:2");
command("delete_atoms group twowater compress no bond yes");
command("reset_mol_ids all");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 23);
ASSERT_EQ(lmp->atom->map_tag_max, 26);
@ -228,9 +196,9 @@ TEST_F(ResetIDsTest, DeletePlusAtomID)
ASSERT_GE(GETIDX(25), 0);
ASSERT_GE(GETIDX(26), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_atom_ids");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->map_tag_max, 23);
for (int i = 1; i <= 23; ++i)
@ -244,11 +212,11 @@ TEST_F(ResetIDsTest, PartialOffset)
auto molid = lmp->atom->molecule;
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group nowater subtract all allwater");
lmp->input->one("reset_mol_ids allwater offset 4");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group nowater subtract all allwater");
command("reset_mol_ids allwater offset 4");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 29);
ASSERT_EQ(lmp->atom->map_tag_max, 29);
@ -282,9 +250,9 @@ TEST_F(ResetIDsTest, PartialOffset)
ASSERT_EQ(molid[GETIDX(28)], 8);
ASSERT_EQ(molid[GETIDX(29)], 8);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids nowater offset 0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids nowater offset 0");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(1)], 1);
ASSERT_EQ(molid[GETIDX(2)], 1);
@ -324,13 +292,13 @@ TEST_F(ResetIDsTest, DeleteAdd)
auto molid = lmp->atom->molecule;
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group twowater molecule 4:6:2");
lmp->input->one("group nowater subtract all allwater");
lmp->input->one("delete_atoms group twowater compress no bond yes mol yes");
lmp->input->one("reset_mol_ids allwater");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group twowater molecule 4:6:2");
command("group nowater subtract all allwater");
command("delete_atoms group twowater compress no bond yes mol yes");
command("reset_mol_ids allwater");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 23);
ASSERT_EQ(lmp->atom->map_tag_max, 26);
@ -387,17 +355,17 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_GE(GETIDX(25), 0);
ASSERT_GE(GETIDX(26), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_atom_ids sort yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids sort yes");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->map_tag_max, 23);
for (int i = 1; i <= 23; ++i)
ASSERT_GE(GETIDX(i), 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids nowater offset 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids nowater offset 1");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(1)], 2);
ASSERT_EQ(molid[GETIDX(2)], 2);
@ -423,13 +391,13 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_EQ(molid[GETIDX(22)], 4);
ASSERT_EQ(molid[GETIDX(23)], 4);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("create_atoms 1 single 0.0 0.0 0.0");
lmp->input->one("create_atoms 2 single 1.0 0.0 0.0");
lmp->input->one("create_atoms 3 single 2.0 0.0 0.0");
lmp->input->one("create_atoms 4 single 3.0 0.0 0.0");
lmp->input->one("reset_mol_ids all single yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("create_atoms 1 single 0.0 0.0 0.0");
command("create_atoms 2 single 1.0 0.0 0.0");
command("create_atoms 3 single 2.0 0.0 0.0");
command("create_atoms 4 single 3.0 0.0 0.0");
command("reset_mol_ids all single yes");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 27);
ASSERT_EQ(lmp->atom->map_tag_max, 27);
@ -441,9 +409,9 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_EQ(molid[GETIDX(26)], 6);
ASSERT_EQ(molid[GETIDX(27)], 7);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids all single no");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids all single no");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(21)], 3);
ASSERT_EQ(molid[GETIDX(22)], 3);
@ -453,9 +421,9 @@ TEST_F(ResetIDsTest, DeleteAdd)
ASSERT_EQ(molid[GETIDX(26)], 0);
ASSERT_EQ(molid[GETIDX(27)], 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_mol_ids all compress no single yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_mol_ids all compress no single yes");
END_HIDE_OUTPUT();
ASSERT_EQ(molid[GETIDX(21)], 21);
ASSERT_EQ(molid[GETIDX(22)], 21);
@ -471,23 +439,21 @@ TEST_F(ResetIDsTest, TopologyData)
if (lmp->atom->natoms == 0) GTEST_SKIP();
// delete two water molecules
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("group allwater molecule 3:6");
lmp->input->one("group twowater molecule 4:6:2");
lmp->input->one("group nowater subtract all allwater");
lmp->input->one("delete_atoms group twowater compress no bond yes mol yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("group allwater molecule 3:6");
command("group twowater molecule 4:6:2");
command("group nowater subtract all allwater");
command("delete_atoms group twowater compress no bond yes mol yes");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->atom->natoms, 23);
ASSERT_EQ(lmp->atom->map_tag_max, 26);
auto num_bond = lmp->atom->num_bond;
auto num_angle = lmp->atom->num_angle;
auto num_dihedral = lmp->atom->num_dihedral;
auto num_improper = lmp->atom->num_improper;
auto bond_atom = lmp->atom->bond_atom;
auto angle_atom1 = lmp->atom->angle_atom1;
auto angle_atom2 = lmp->atom->angle_atom2;
auto angle_atom3 = lmp->atom->angle_atom3;
auto num_bond = lmp->atom->num_bond;
auto num_angle = lmp->atom->num_angle;
auto bond_atom = lmp->atom->bond_atom;
auto angle_atom1 = lmp->atom->angle_atom1;
auto angle_atom2 = lmp->atom->angle_atom2;
auto angle_atom3 = lmp->atom->angle_atom3;
ASSERT_EQ(num_bond[GETIDX(1)], 2);
ASSERT_EQ(bond_atom[GETIDX(1)][0], 2);
ASSERT_EQ(bond_atom[GETIDX(1)][1], 3);
@ -562,18 +528,16 @@ TEST_F(ResetIDsTest, TopologyData)
ASSERT_EQ(angle_atom2[GETIDX(24)][0], 24);
ASSERT_EQ(angle_atom3[GETIDX(24)][0], 26);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("reset_atom_ids sort yes");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("reset_atom_ids sort yes");
END_HIDE_OUTPUT();
num_bond = lmp->atom->num_bond;
num_angle = lmp->atom->num_angle;
num_dihedral = lmp->atom->num_dihedral;
num_improper = lmp->atom->num_improper;
bond_atom = lmp->atom->bond_atom;
angle_atom1 = lmp->atom->angle_atom1;
angle_atom2 = lmp->atom->angle_atom2;
angle_atom3 = lmp->atom->angle_atom3;
num_bond = lmp->atom->num_bond;
num_angle = lmp->atom->num_angle;
bond_atom = lmp->atom->bond_atom;
angle_atom1 = lmp->atom->angle_atom1;
angle_atom2 = lmp->atom->angle_atom2;
angle_atom3 = lmp->atom->angle_atom3;
ASSERT_EQ(num_bond[GETIDX(1)], 2);
ASSERT_EQ(bond_atom[GETIDX(1)][0], 3);
ASSERT_EQ(bond_atom[GETIDX(1)][1], 2);
@ -662,61 +626,60 @@ TEST_F(ResetIDsTest, DeathTests)
{
if (lmp->atom->natoms == 0) GTEST_SKIP();
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", lmp->input->one("reset_mol_ids"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset 1 1"););
command("reset_mol_ids all offset 1 1"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset -2"););
command("reset_mol_ids all offset -2"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*", command("reset_mol_ids all offset xxx"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*",
lmp->input->one("reset_mol_ids all offset xxx"););
TEST_FAILURE(".*ERROR on proc 0: Expected integer.*",
lmp->input->one("reset_mol_ids all compress yes single no offset xxx"););
command("reset_mol_ids all compress yes single no offset xxx"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids all offset"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all offset"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all compress"););
command("reset_mol_ids all compress"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all compress xxx"););
command("reset_mol_ids all compress xxx"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*", command("reset_mol_ids all single"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all single"););
TEST_FAILURE(".*ERROR: Illegal reset_mol_ids command.*",
lmp->input->one("reset_mol_ids all single xxx"););
command("reset_mol_ids all single xxx"););
}
TEST(ResetMolIds, CMDFail)
{
LAMMPS *lmp;
const char *args[] = {"ResetIDsTest", "-log", "none", "-nocite", "-echo", "screen"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Reset_mol_ids command before simulation box is.*",
lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("atom_modify id no");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Cannot use reset_mol_ids unless.*",
lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
lmp->input->one("region box block 0 1 0 1 0 1");
lmp->input->one("create_box 1 box");
if (!verbose) ::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", lmp->input->one("reset_mol_ids all"););
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
class ResetMolIDsTest : public LAMMPSTest {
protected:
void SetUp() override
{
testbinary = "ResetIDsTest";
LAMMPSTest::SetUp();
}
};
TEST_F(ResetMolIDsTest, FailBeforeBox)
{
TEST_FAILURE(".*ERROR: Reset_mol_ids command before simulation box is.*",
command("reset_mol_ids all"););
}
TEST_F(ResetMolIDsTest, FailMissingId)
{
BEGIN_HIDE_OUTPUT();
command("atom_modify id no");
command("region box block 0 1 0 1 0 1");
command("create_box 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Cannot use reset_mol_ids unless.*", command("reset_mol_ids all"););
}
TEST_F(ResetMolIDsTest, FailOnlyMolecular)
{
BEGIN_HIDE_OUTPUT();
command("clear");
command("region box block 0 1 0 1 0 1");
command("create_box 1 box");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Can only use reset_mol_ids.*", command("reset_mol_ids all"););
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)
@ -724,7 +687,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -13,16 +13,20 @@
#include "lammps.h"
#include "citeme.h"
#include "comm.h"
#include "force.h"
#include "info.h"
#include "input.h"
#include "output.h"
#include "update.h"
#include "utils.h"
#include "variable.h"
#include "fmt/format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include "../testing/utils.h"
#include <cstdio>
#include <cstring>
@ -33,11 +37,6 @@
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
#if defined(OMPI_MAJOR_VERSION)
const bool have_openmpi = true;
#else
const bool have_openmpi = false;
#endif
using LAMMPS_NS::utils::split_words;
@ -46,46 +45,12 @@ using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
#define TEST_FAILURE(errmsg, ...) \
if (Info::has_exceptions()) { \
::testing::internal::CaptureStdout(); \
ASSERT_ANY_THROW({__VA_ARGS__}); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} else { \
if (!have_openmpi) { \
::testing::internal::CaptureStdout(); \
ASSERT_DEATH({__VA_ARGS__}, ""); \
auto mesg = ::testing::internal::GetCapturedStdout(); \
ASSERT_THAT(mesg, MatchesRegex(errmsg)); \
} \
}
class SimpleCommandsTest : public ::testing::Test {
protected:
LAMMPS *lmp;
void SetUp() override
{
const char *args[] = {"SimpleCommandsTest", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
if (!verbose) ::testing::internal::CaptureStdout();
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
if (!verbose) ::testing::internal::GetCapturedStdout();
}
void TearDown() override
{
if (!verbose) ::testing::internal::CaptureStdout();
delete lmp;
if (!verbose) ::testing::internal::GetCapturedStdout();
}
class SimpleCommandsTest : public LAMMPSTest {
};
TEST_F(SimpleCommandsTest, UnknownCommand)
{
TEST_FAILURE(".*ERROR: Unknown command.*", lmp->input->one("XXX one two"););
TEST_FAILURE(".*ERROR: Unknown command.*", command("XXX one two"););
}
TEST_F(SimpleCommandsTest, Echo)
@ -93,47 +58,47 @@ TEST_F(SimpleCommandsTest, Echo)
ASSERT_EQ(lmp->input->echo_screen, 1);
ASSERT_EQ(lmp->input->echo_log, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo none");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo none");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 0);
ASSERT_EQ(lmp->input->echo_log, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo both");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo both");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 1);
ASSERT_EQ(lmp->input->echo_log, 1);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo screen");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo screen");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 1);
ASSERT_EQ(lmp->input->echo_log, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("echo log");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("echo log");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->input->echo_screen, 0);
ASSERT_EQ(lmp->input->echo_log, 1);
TEST_FAILURE(".*ERROR: Illegal echo command.*", lmp->input->one("echo"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", lmp->input->one("echo xxx"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", command("echo"););
TEST_FAILURE(".*ERROR: Illegal echo command.*", command("echo xxx"););
}
TEST_F(SimpleCommandsTest, Log)
{
ASSERT_EQ(lmp->logfile, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log simple_command_test.log");
lmp->input->one("print 'test1'");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log simple_command_test.log");
command("print 'test1'");
END_HIDE_OUTPUT();
ASSERT_NE(lmp->logfile, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log none");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log none");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->logfile, nullptr);
std::string text;
@ -143,14 +108,14 @@ TEST_F(SimpleCommandsTest, Log)
in.close();
ASSERT_THAT(text, StrEq("test1"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log simple_command_test.log append");
lmp->input->one("print 'test2'");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log simple_command_test.log append");
command("print 'test2'");
END_HIDE_OUTPUT();
ASSERT_NE(lmp->logfile, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("log none");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("log none");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->logfile, nullptr);
in.open("simple_command_test.log");
@ -161,7 +126,7 @@ TEST_F(SimpleCommandsTest, Log)
in.close();
remove("simple_command_test.log");
TEST_FAILURE(".*ERROR: Illegal log command.*", lmp->input->one("log"););
TEST_FAILURE(".*ERROR: Illegal log command.*", command("log"););
}
TEST_F(SimpleCommandsTest, Newton)
@ -169,59 +134,111 @@ TEST_F(SimpleCommandsTest, Newton)
// default setting is "on" for both
ASSERT_EQ(lmp->force->newton_pair, 1);
ASSERT_EQ(lmp->force->newton_bond, 1);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton off");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton off");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 0);
ASSERT_EQ(lmp->force->newton_bond, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton on off");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton on off");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 1);
ASSERT_EQ(lmp->force->newton_bond, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton off on");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton off on");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 0);
ASSERT_EQ(lmp->force->newton_bond, 1);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("newton on");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("newton on");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->force->newton_pair, 1);
ASSERT_EQ(lmp->force->newton_bond, 1);
}
TEST_F(SimpleCommandsTest, Partition)
{
BEGIN_HIDE_OUTPUT();
command("echo none");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Illegal partition command .*", command("partition xxx 1 echo none"););
TEST_FAILURE(".*ERROR: Numeric index 2 is out of bounds.*",
command("partition yes 2 echo none"););
BEGIN_CAPTURE_OUTPUT();
command("partition yes 1 print 'test'");
auto text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, StrEq("test\n"));
BEGIN_CAPTURE_OUTPUT();
command("partition no 1 print 'test'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, StrEq(""));
}
TEST_F(SimpleCommandsTest, Processors)
{
// default setting is "*" for all dimensions
ASSERT_EQ(lmp->comm->user_procgrid[0], 0);
ASSERT_EQ(lmp->comm->user_procgrid[1], 0);
ASSERT_EQ(lmp->comm->user_procgrid[2], 0);
BEGIN_HIDE_OUTPUT();
command("processors 1 1 1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->comm->user_procgrid[0], 1);
ASSERT_EQ(lmp->comm->user_procgrid[1], 1);
ASSERT_EQ(lmp->comm->user_procgrid[2], 1);
BEGIN_HIDE_OUTPUT();
command("processors * 1 *");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->comm->user_procgrid[0], 0);
ASSERT_EQ(lmp->comm->user_procgrid[1], 1);
ASSERT_EQ(lmp->comm->user_procgrid[2], 0);
BEGIN_HIDE_OUTPUT();
command("processors 0 0 0");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->comm->user_procgrid[0], 0);
ASSERT_EQ(lmp->comm->user_procgrid[1], 0);
ASSERT_EQ(lmp->comm->user_procgrid[2], 0);
TEST_FAILURE(".*ERROR: Illegal processors command .*", command("processors -1 0 0"););
TEST_FAILURE(".*ERROR: Specified processors != physical processors.*", command("processors 100 100 100"););
}
TEST_F(SimpleCommandsTest, Quit)
{
::testing::internal::CaptureStdout();
lmp->input->one("echo none");
::testing::internal::GetCapturedStdout();
TEST_FAILURE(".*ERROR: Expected integer .*", lmp->input->one("quit xxx"););
BEGIN_HIDE_OUTPUT();
command("echo none");
END_HIDE_OUTPUT();
TEST_FAILURE(".*ERROR: Expected integer .*", command("quit xxx"););
// the following tests must be skipped with OpenMPI due to using threads
if (have_openmpi) GTEST_SKIP();
ASSERT_EXIT(lmp->input->one("quit"), ExitedWithCode(0), "");
ASSERT_EXIT(lmp->input->one("quit 9"), ExitedWithCode(9), "");
if (Info::get_mpi_vendor() == "Open MPI") GTEST_SKIP();
ASSERT_EXIT(command("quit"), ExitedWithCode(0), "");
ASSERT_EXIT(command("quit 9"), ExitedWithCode(9), "");
}
TEST_F(SimpleCommandsTest, ResetTimestep)
{
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.*", lmp->input->one("reset_timestep -10"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", lmp->input->one("reset_timestep"););
TEST_FAILURE(".*ERROR: Illegal reset_timestep .*", lmp->input->one("reset_timestep 10 10"););
TEST_FAILURE(".*ERROR: Expected integer .*", lmp->input->one("reset_timestep xxx"););
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"););
}
TEST_F(SimpleCommandsTest, Suffix)
@ -230,93 +247,92 @@ TEST_F(SimpleCommandsTest, Suffix)
ASSERT_EQ(lmp->suffix, nullptr);
ASSERT_EQ(lmp->suffix2, nullptr);
TEST_FAILURE(".*ERROR: May only enable suffixes after defining one.*",
lmp->input->one("suffix on"););
TEST_FAILURE(".*ERROR: May only enable suffixes after defining one.*", command("suffix on"););
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix one");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix one");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->suffix, StrEq("one"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix hybrid two three");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix hybrid two three");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->suffix, StrEq("two"));
ASSERT_THAT(lmp->suffix2, StrEq("three"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix four");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix four");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->suffix, StrEq("four"));
ASSERT_EQ(lmp->suffix2, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix off");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix off");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->suffix_enable, 0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("suffix on");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("suffix on");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->suffix_enable, 1);
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix hybrid"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", lmp->input->one("suffix hybrid one"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", command("suffix"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", command("suffix hybrid"););
TEST_FAILURE(".*ERROR: Illegal suffix command.*", command("suffix hybrid one"););
}
TEST_F(SimpleCommandsTest, Thermo)
{
ASSERT_EQ(lmp->output->thermo_every, 0);
ASSERT_EQ(lmp->output->var_thermo, nullptr);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("thermo 2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("thermo 2");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->output->thermo_every, 2);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("variable step equal logfreq(10,3,10)");
lmp->input->one("thermo v_step");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("variable step equal logfreq(10,3,10)");
command("thermo v_step");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->output->var_thermo, StrEq("step"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("thermo 10");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("thermo 10");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->output->thermo_every, 10);
ASSERT_EQ(lmp->output->var_thermo, nullptr);
TEST_FAILURE(".*ERROR: Illegal thermo command.*", lmp->input->one("thermo"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", lmp->input->one("thermo -1"););
TEST_FAILURE(".*ERROR: Expected integer.*", lmp->input->one("thermo xxx"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", command("thermo"););
TEST_FAILURE(".*ERROR: Illegal thermo command.*", command("thermo -1"););
TEST_FAILURE(".*ERROR: Expected integer.*", command("thermo xxx"););
}
TEST_F(SimpleCommandsTest, TimeStep)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep 1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep 1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, 1.0);
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep 0.1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep 0.1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, 0.1);
// zero timestep is legal and works (atoms don't move)
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep 0.0");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep 0.0");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, 0.0);
// negative timestep also creates a viable MD.
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("timestep -0.1");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("timestep -0.1");
END_HIDE_OUTPUT();
ASSERT_EQ(lmp->update->dt, -0.1);
TEST_FAILURE(".*ERROR: Illegal timestep command.*", lmp->input->one("timestep"););
TEST_FAILURE(".*ERROR: Expected floating point.*", lmp->input->one("timestep xxx"););
TEST_FAILURE(".*ERROR: Illegal timestep command.*", command("timestep"););
TEST_FAILURE(".*ERROR: Expected floating point.*", command("timestep xxx"););
}
TEST_F(SimpleCommandsTest, Units)
@ -328,46 +344,160 @@ TEST_F(SimpleCommandsTest, Units)
ASSERT_THAT(lmp->update->unit_style, StrEq("lj"));
for (std::size_t i = 0; i < num; ++i) {
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one(fmt::format("units {}", names[i]));
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command(fmt::format("units {}", names[i]));
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->update->unit_style, StrEq(names[i]));
ASSERT_EQ(lmp->update->dt, dt[i]);
}
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("clear");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("clear");
END_HIDE_OUTPUT();
ASSERT_THAT(lmp->update->unit_style, StrEq("lj"));
TEST_FAILURE(".*ERROR: Illegal units command.*", lmp->input->one("units unknown"););
TEST_FAILURE(".*ERROR: Illegal units command.*", command("units unknown"););
}
#if defined(LMP_PLUGIN)
TEST_F(SimpleCommandsTest, Plugin)
{
std::string loadfmt("plugin load {}plugin.so");
::testing::internal::CaptureStdout();
lmp->input->one(fmt::format(loadfmt, "hello"));
auto text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Loading plugin: Hello world command.*"));
::testing::internal::CaptureStdout();
lmp->input->one(fmt::format(loadfmt, "xxx"));
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Open of file xxx.* failed.*"));
::testing::internal::CaptureStdout();
lmp->input->one(fmt::format(loadfmt, "nve2"));
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Loading plugin: NVE2 variant fix style.*"));
::testing::internal::CaptureStdout();
lmp->input->one("plugin list");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*1: command style plugin hello"
".*2: fix style plugin nve2.*"));
::testing::internal::CaptureStdout();
lmp->input->one(fmt::format(loadfmt, "hello"));
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Ignoring load of command style hello: "
"must unload existing hello plugin.*"));
::testing::internal::CaptureStdout();
lmp->input->one("plugin unload command hello");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Unloading command style hello.*"));
::testing::internal::CaptureStdout();
lmp->input->one("plugin unload pair nve2");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Ignoring unload of pair style nve2: "
"not loaded from a plugin.*"));
::testing::internal::CaptureStdout();
lmp->input->one("plugin unload fix nve2");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Unloading fix style nve2.*"));
::testing::internal::CaptureStdout();
lmp->input->one("plugin unload fix nve");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Ignoring unload of fix style nve: "
"not loaded from a plugin.*"));
::testing::internal::CaptureStdout();
lmp->input->one("plugin list");
text = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << text;
ASSERT_THAT(text, MatchesRegex(".*Currently loaded plugins.*"));
}
#endif
TEST_F(SimpleCommandsTest, Shell)
{
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("shell putenv TEST_VARIABLE=simpletest");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("shell putenv TEST_VARIABLE=simpletest");
END_HIDE_OUTPUT();
char *test_var = getenv("TEST_VARIABLE");
const char *test_var = getenv("TEST_VARIABLE");
ASSERT_NE(test_var, nullptr);
ASSERT_THAT(test_var, StrEq("simpletest"));
if (!verbose) ::testing::internal::CaptureStdout();
lmp->input->one("shell putenv TEST_VARIABLE=simpletest");
lmp->input->one("shell putenv TEST_VARIABLE2=simpletest2 OTHER_VARIABLE=2");
if (!verbose) ::testing::internal::GetCapturedStdout();
BEGIN_HIDE_OUTPUT();
command("shell putenv TEST_VARIABLE");
command("shell putenv TEST_VARIABLE2=simpletest OTHER_VARIABLE=2");
END_HIDE_OUTPUT();
char *test_var2 = getenv("TEST_VARIABLE2");
char *other_var = getenv("OTHER_VARIABLE");
test_var = getenv("TEST_VARIABLE2");
ASSERT_NE(test_var, nullptr);
ASSERT_THAT(test_var, StrEq("simpletest"));
ASSERT_NE(test_var2, nullptr);
ASSERT_THAT(test_var2, StrEq("simpletest2"));
test_var = getenv("OTHER_VARIABLE");
ASSERT_NE(test_var, nullptr);
ASSERT_THAT(test_var, StrEq("2"));
ASSERT_NE(other_var, nullptr);
ASSERT_THAT(other_var, StrEq("2"));
test_var = getenv("TEST_VARIABLE");
ASSERT_NE(test_var, nullptr);
ASSERT_THAT(test_var, StrEq(""));
}
TEST_F(SimpleCommandsTest, CiteMe)
{
ASSERT_EQ(lmp->citeme, nullptr);
lmp->citeme = new LAMMPS_NS::CiteMe(lmp, CiteMe::TERSE, CiteMe::TERSE, nullptr);
BEGIN_CAPTURE_OUTPUT();
lmp->citeme->add("test citation one:\n 1\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation one:\n 1\n");
lmp->citeme->flush();
std::string text = END_CAPTURE_OUTPUT();
// find the two unique citations, but not the third
ASSERT_THAT(text, MatchesRegex(".*one.*two.*"));
ASSERT_THAT(text, Not(MatchesRegex(".*one.*two.*one.*")));
BEGIN_CAPTURE_OUTPUT();
lmp->citeme->add("test citation one:\n 0\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation three:\n 3\n");
lmp->citeme->flush();
text = END_CAPTURE_OUTPUT();
// find the forth (only differs in long citation) and sixth added citation
ASSERT_THAT(text, MatchesRegex(".*one.*three.*"));
ASSERT_THAT(text, Not(MatchesRegex(".*two.*")));
BEGIN_CAPTURE_OUTPUT();
lmp->citeme->add("test citation one:\n 1\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation one:\n 0\n");
lmp->citeme->add("test citation two:\n 2\n");
lmp->citeme->add("test citation three:\n 3\n");
lmp->citeme->flush();
text = END_CAPTURE_OUTPUT();
// no new citation. no CITE-CITE-CITE- lines
ASSERT_THAT(text, Not(MatchesRegex(".*CITE-CITE-CITE-CITE.*")));
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)
@ -375,7 +505,7 @@ int main(int argc, char **argv)
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (have_openmpi && !LAMMPS_NS::Info::has_exceptions())
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";

View File

@ -0,0 +1,538 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://lammps.sandia.gov/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "lammps.h"
#include "atom.h"
#include "domain.h"
#include "group.h"
#include "info.h"
#include "input.h"
#include "math_const.h"
#include "region.h"
#include "variable.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "../testing/core.h"
#include <cstring>
#include <vector>
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
using LAMMPS_NS::MathConst::MY_PI;
using LAMMPS_NS::utils::split_words;
namespace LAMMPS_NS {
using ::testing::ExitedWithCode;
using ::testing::MatchesRegex;
using ::testing::StrEq;
class VariableTest : public LAMMPSTest {
protected:
Group *group;
Domain *domain;
Variable *variable;
void SetUp() override
{
testbinary = "VariableTest";
args = {"-log", "none", "-echo", "screen", "-nocite", "-v", "num", "1"};
LAMMPSTest::SetUp();
group = lmp->group;
domain = lmp->domain;
variable = lmp->input->variable;
}
void TearDown() override
{
LAMMPSTest::TearDown();
unlink("test_variable.file");
unlink("test_variable.atomfile");
}
void atomic_system()
{
BEGIN_HIDE_OUTPUT();
command("units real");
command("lattice sc 1.0 origin 0.125 0.125 0.125");
command("region box block -2 2 -2 2 -2 2");
command("create_box 8 box");
command("create_atoms 1 box");
command("mass * 1.0");
command("region left block -2.0 -1.0 INF INF INF INF");
command("region right block 0.5 2.0 INF INF INF INF");
command("region top block INF INF -2.0 -1.0 INF INF");
command("set region left type 2");
command("set region right type 3");
END_HIDE_OUTPUT();
}
void molecular_system()
{
BEGIN_HIDE_OUTPUT();
command("fix props all property/atom mol rmass q");
END_HIDE_OUTPUT();
atomic_system();
BEGIN_HIDE_OUTPUT();
command("variable molid atom floor(id/4)+1");
command("variable charge atom 2.0*sin(PI/32*id)");
command("set atom * mol v_molid");
command("set atom * charge v_charge");
command("set type 1 mass 0.5");
command("set type 2*4 mass 2.0");
END_HIDE_OUTPUT();
}
void file_vars()
{
FILE *fp = fopen("test_variable.file", "w");
fputs("# test file for file style variable\n\n\none\n two \n\n"
"three # with comment\nfour ! with non-comment\n"
"# comments only\n five\n#END\n",
fp);
fclose(fp);
fp = fopen("test_variable.atomfile", "w");
fputs("# test file for atomfile style variable\n\n"
"4 # four lines\n4 0.5 #with comment\n"
"2 -0.5 \n3 1.5\n1 -1.5\n\n"
"2\n10 1.0 # test\n13 1.0\n\n######\n"
"4\n1 4.0 # test\n2 3.0\n3 2.0\n4 1.0\n#END\n",
fp);
fclose(fp);
}
};
TEST_F(VariableTest, CreateDelete)
{
file_vars();
ASSERT_EQ(variable->nvar, 1);
BEGIN_HIDE_OUTPUT();
command("shell putenv TEST_VARIABLE=simpletest2");
command("shell putenv TEST_VARIABLE2=simpletest OTHER_VARIABLE=2");
command("variable one index 1 2 3 4");
command("variable two equal 1");
command("variable two equal 2");
command("variable three string four");
command("variable three string three");
command("variable four1 loop 4");
command("variable four2 loop 2 4");
command("variable five1 loop 100 pad");
command("variable five2 loop 10 200 pad");
command("variable six world one");
command("variable seven format two \"%5.2f\"");
command("variable eight getenv TEST_VARIABLE2");
command("variable eight getenv XXX");
command("variable nine file test_variable.file");
command("variable ten internal 1.0");
command("variable ten internal 10.0");
command("variable ten1 universe 1 2 3 4");
command("variable ten2 uloop 4");
command("variable ten3 uloop 4 pad");
command("variable dummy index 0");
command("variable file equal is_file(MYFILE)");
END_HIDE_OUTPUT();
ASSERT_EQ(variable->nvar, 18);
BEGIN_HIDE_OUTPUT();
command("variable dummy delete");
END_HIDE_OUTPUT();
ASSERT_EQ(variable->nvar, 17);
ASSERT_THAT(variable->retrieve("three"), StrEq("three"));
variable->set_string("three", "four");
ASSERT_THAT(variable->retrieve("three"), StrEq("four"));
ASSERT_THAT(variable->retrieve("four2"), StrEq("2"));
ASSERT_THAT(variable->retrieve("five1"), StrEq("001"));
ASSERT_THAT(variable->retrieve("seven"), StrEq(" 2.00"));
ASSERT_THAT(variable->retrieve("ten"), StrEq("1"));
ASSERT_THAT(variable->retrieve("eight"), StrEq(""));
variable->internal_set(variable->find("ten"), 2.5);
ASSERT_THAT(variable->retrieve("ten"), StrEq("2.5"));
ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
FILE *fp = fopen("MYFILE","w");
fputs(" ",fp);
fclose(fp);
ASSERT_THAT(variable->retrieve("file"), StrEq("1"));
unlink("MYFILE");
ASSERT_THAT(variable->retrieve("file"), StrEq("0"));
BEGIN_HIDE_OUTPUT();
command("variable seven delete");
command("variable seven getenv TEST_VARIABLE");
command("variable eight getenv OTHER_VARIABLE");
END_HIDE_OUTPUT();
ASSERT_THAT(variable->retrieve("seven"), StrEq("simpletest2"));
ASSERT_THAT(variable->retrieve("eight"), StrEq("2"));
ASSERT_EQ(variable->equalstyle(variable->find("one")), 0);
ASSERT_EQ(variable->equalstyle(variable->find("two")), 1);
ASSERT_EQ(variable->equalstyle(variable->find("ten")), 1);
ASSERT_EQ(variable->internalstyle(variable->find("two")), 0);
ASSERT_EQ(variable->internalstyle(variable->find("ten")), 1);
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy index"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy delete xxx"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy loop -1"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy loop 10 1"););
TEST_FAILURE(".*ERROR: Illegal variable command.*", command("variable dummy xxxx"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable two string xxx"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable two getenv xxx"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one equal 2"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one internal 2"););
TEST_FAILURE(".*ERROR: Cannot use atomfile-style variable unless an atom map exists.*",
command("variable eleven atomfile test_variable.atomfile"););
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
command("variable nine1 file test_variable.xxx"););
TEST_FAILURE(".*ERROR: World variable count doesn't match # of partitions.*",
command("variable ten10 world xxx xxx"););
TEST_FAILURE(".*ERROR: All universe/uloop variables must have same # of values.*",
command("variable ten4 uloop 2"););
TEST_FAILURE(".*ERROR: Incorrect conversion in format string.*",
command("variable ten11 format two \"%08f\""););
TEST_FAILURE(".*ERROR: Variable name 'ten@12' must have only alphanumeric characters or.*",
command("variable ten@12 index one two three"););
TEST_FAILURE(".*ERROR: Variable evaluation before simulation box is defined.*",
variable->compute_equal("c_thermo_press"););
TEST_FAILURE(".*ERROR: Invalid variable reference v_unknown in variable formula.*",
variable->compute_equal("v_unknown"););
}
TEST_F(VariableTest, AtomicSystem)
{
HIDE_OUTPUT([&] { command("atom_modify map array"); });
atomic_system();
file_vars();
BEGIN_HIDE_OUTPUT();
command("variable one index 1 2 3 4");
command("variable id atom type");
command("variable id atom id");
command("variable ten atomfile test_variable.atomfile");
command("compute press all pressure NULL pair");
command("compute rg all gyration");
command("compute vacf all vacf");
command("fix press all ave/time 1 1 1 c_press mode vector");
command("fix rg all ave/time 1 1 1 c_rg mode vector");
command("fix vacf all ave/time 1 1 1 c_vacf mode vector");
command("variable press vector f_press");
command("variable rg vector f_rg");
command("variable vacf vector f_vacf");
command("variable press vector f_press+0.0");
command("variable self vector v_self+f_press");
command("variable circle vector f_press+v_circle");
command("variable sum vector v_press+v_rg");
command("variable sum2 vector v_vacf+v_rg");
command("variable pmax equal max(v_press)");
command("variable psum equal sum(v_press)");
command("variable rgmax equal max(v_rg)");
command("variable rgsum equal sum(v_rg)");
command("variable loop equal v_loop+1");
command("run 0 post no");
END_HIDE_OUTPUT();
ASSERT_EQ(variable->atomstyle(variable->find("one")), 0);
ASSERT_EQ(variable->atomstyle(variable->find("id")), 1);
ASSERT_EQ(variable->atomstyle(variable->find("ten")), 1);
ASSERT_EQ(variable->vectorstyle(variable->find("one")), 0);
ASSERT_EQ(variable->vectorstyle(variable->find("press")), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_pmax"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_psum"), 0.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_rgmax"), 1.25);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_rgsum"), 3.75);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_sum[1]"), 1.25);
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one atom x"););
TEST_FAILURE(".*ERROR: Cannot redefine variable as a different style.*",
command("variable one vector f_press"););
TEST_FAILURE(".*ERROR on proc 0: Cannot open file variable file test_variable.xxx.*",
command("variable ten1 atomfile test_variable.xxx"););
TEST_FAILURE(".*ERROR: Variable loop: has a circular dependency.*",
variable->compute_equal("v_loop"););
TEST_FAILURE(".*Variable self: Vector-style variable in equal-style variable formula.*",
variable->compute_equal("v_self"););
TEST_FAILURE(".*ERROR: Variable sum2: Inconsistent lengths in vector-style variable.*",
variable->compute_equal("max(v_sum2)"););
}
TEST_F(VariableTest, Expressions)
{
atomic_system();
BEGIN_HIDE_OUTPUT();
command("variable one index 1");
command("variable two equal 2");
command("variable three equal v_one+v_two");
command("variable four equal PI");
command("variable five equal version");
command("variable six equal XXX");
command("variable seven equal -v_one");
command("variable eight equal v_three-0.5");
command("variable nine equal v_two*(v_one+v_three)");
command("variable ten equal (1.0/v_two)^2");
command("variable eleven equal v_three%2");
command("variable twelve equal 1==2");
command("variable ten3 equal 1!=v_two");
command("variable ten4 equal 1<2");
command("variable ten5 equal 2>1");
command("variable ten6 equal (1<=v_one)&&(v_ten>=0.2)");
command("variable ten7 equal !(1<v_two)");
command("variable ten8 equal 1|^0");
command("variable ten9 equal v_one-v_ten9");
command("variable ten10 internal 100.0");
command("variable ten11 equal (1!=1)+(2<1)+(2<=1)+(1>2)+(1>=2)+(1&&0)+(0||0)+(1|^1)+10^0");
command("variable ten12 equal yes+no+on+off+true+false");
command("variable err1 equal v_one/v_ten7");
command("variable err2 equal v_one%v_ten7");
command("variable err3 equal v_ten7^-v_one");
variable->set("dummy index 1 2");
END_HIDE_OUTPUT();
int ivar = variable->find("one");
ASSERT_FALSE(variable->equalstyle(ivar));
ivar = variable->find("two");
ASSERT_TRUE(variable->equalstyle(ivar));
ASSERT_DOUBLE_EQ(variable->compute_equal(ivar), 2.0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_three"), 3.0);
ASSERT_FLOAT_EQ(variable->compute_equal("v_four"), MY_PI);
ASSERT_GE(variable->compute_equal("v_five"), 20210310);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_seven"), -1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_eight"), 2.5);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_nine"), 8);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten"), 0.25);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_eleven"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_twelve"), 0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten3"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten4"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten5"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten6"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten7"), 0);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten8"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten10"), 100);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten11"), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten12"), 3);
TEST_FAILURE(".*ERROR: Variable six: Invalid thermo keyword 'XXX' in variable formula.*",
command("print \"${six}\""););
TEST_FAILURE(".*ERROR: Variable ten9: has a circular dependency.*",
command("print \"${ten9}\""););
TEST_FAILURE(".*ERROR on proc 0: Variable err1: Divide by 0 in variable formula.*",
command("print \"${err1}\""););
TEST_FAILURE(".*ERROR on proc 0: Variable err2: Modulo 0 in variable formula.*",
command("print \"${err2}\""););
TEST_FAILURE(".*ERROR on proc 0: Variable err3: Invalid power expression in variable formula.*",
command("print \"${err3}\""););
}
TEST_F(VariableTest, Functions)
{
atomic_system();
file_vars();
BEGIN_HIDE_OUTPUT();
command("variable seed index 643532");
command("variable one index 1");
command("variable two equal random(1,2,v_seed)");
command("variable three equal atan2(v_one,1)");
command("variable four equal atan2()");
command("variable five equal sqrt(v_one+v_one)");
command("variable six equal exp(ln(0.1))");
command("variable seven equal abs(log(1.0/100.0))");
command("variable eight equal 0.5*PI");
command("variable nine equal round(sin(v_eight)+cos(v_eight))");
command("variable ten equal floor(1.85)+ceil(1.85)");
command("variable ten1 equal tan(v_eight/2.0)");
command("variable ten2 equal asin(-1.0)+acos(0.0)");
command("variable ten3 equal floor(100*random(0.2,0.8,v_seed)+1)");
END_HIDE_OUTPUT();
ASSERT_GT(variable->compute_equal(variable->find("two")), 0.99);
ASSERT_LT(variable->compute_equal(variable->find("two")), 2.01);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("three")), 0.25 * MY_PI);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("five")), sqrt(2.0));
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("six")), 0.1);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("seven")), 2);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("nine")), 1);
ASSERT_DOUBLE_EQ(variable->compute_equal(variable->find("ten")), 3);
ASSERT_FLOAT_EQ(variable->compute_equal(variable->find("ten1")), 1);
ASSERT_GT(variable->compute_equal(variable->find("ten3")), 19);
ASSERT_LT(variable->compute_equal(variable->find("ten3")), 81);
TEST_FAILURE(".*ERROR: Variable four: Invalid syntax in variable formula.*",
command("print \"${four}\""););
}
TEST_F(VariableTest, IfCommand)
{
BEGIN_HIDE_OUTPUT();
command("variable one index 1");
END_HIDE_OUTPUT();
BEGIN_CAPTURE_OUTPUT();
command("if 1>0 then 'print \"bingo!\"'");
auto text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if 1>2 then 'print \"bingo!\"' else 'print \"nope?\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*nope\?.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (1<=0) then 'print \"bingo!\"' else 'print \"nope?\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*nope\?.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (-1.0e-1<0.0E+0)|^(1<0) then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (${one}==1.0)&&(2>=1) then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if !((${one}!=1.0)||(2|^1)) then 'print \"missed\"' else 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if (1>=2)&&(0&&1) then 'print \"missed\"' else 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if !1 then 'print \"missed\"' else 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if !(a==b) then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if x==x|^1==0 then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
BEGIN_CAPTURE_OUTPUT();
command("if x!=x|^a!=b then 'print \"bingo!\"'");
text = END_CAPTURE_OUTPUT();
ASSERT_THAT(text, MatchesRegex(".*bingo!.*"));
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if () then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if \"1 1\" then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1a then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1=<2 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1!=a then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1&<2 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if 1|<2 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if (1)( then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if (1)1 then 'print \"bingo!\"'"););
TEST_FAILURE(".*ERROR: Invalid Boolean syntax in if command.*",
command("if (v_one==1.0)&&(2>=1) then 'print \"bingo!\"'"););
}
TEST_F(VariableTest, NextCommand)
{
file_vars();
BEGIN_HIDE_OUTPUT();
command("variable one index 1 2");
command("variable two equal 2");
command("variable three file test_variable.file");
command("variable four loop 2 4");
command("variable five index 1 2");
END_HIDE_OUTPUT();
ASSERT_DOUBLE_EQ(variable->compute_equal("v_one"), 1);
ASSERT_THAT(variable->retrieve("three"), StrEq("one"));
BEGIN_HIDE_OUTPUT();
command("next one");
command("next three");
END_HIDE_OUTPUT();
ASSERT_DOUBLE_EQ(variable->compute_equal("v_one"), 2);
ASSERT_THAT(variable->retrieve("three"), StrEq("two"));
ASSERT_GE(variable->find("one"), 0);
BEGIN_HIDE_OUTPUT();
command("next one");
command("next three");
END_HIDE_OUTPUT();
// index style variable is deleted if no more next element
ASSERT_EQ(variable->find("one"), -1);
ASSERT_GE(variable->find("three"), 0);
BEGIN_HIDE_OUTPUT();
command("next three");
command("next three");
command("next three");
END_HIDE_OUTPUT();
// file style variable is deleted if no more next element
ASSERT_EQ(variable->find("three"), -1);
TEST_FAILURE(".*ERROR: Illegal next command.*", command("next"););
TEST_FAILURE(".*ERROR: Invalid variable 'xxx' in next command.*", command("next xxx"););
TEST_FAILURE(".*ERROR: Invalid variable style with next command.*", command("next two"););
TEST_FAILURE(".*ERROR: All variables in next command must have same style.*",
command("next five four"););
}
} // namespace LAMMPS_NS
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);
for (auto arg : env) {
if (arg == "-v") {
verbose = true;
}
}
}
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
int rv = RUN_ALL_TESTS();
MPI_Finalize();
return rv;
}

View File

@ -2,7 +2,12 @@
add_executable(test_lammps_class test_lammps_class.cpp)
target_link_libraries(test_lammps_class PRIVATE lammps GTest::GMockMain GTest::GTest GTest::GMock)
add_test(LammpsClass test_lammps_class)
set_tests_properties(LammpsClass PROPERTIES ENVIRONMENT "OMP_NUM_THREADS=1")
add_executable(test_input_class test_input_class.cpp)
target_link_libraries(test_input_class PRIVATE lammps GTest::GTest GTest::GTestMain)
add_test(InputClass test_input_class)
add_executable(test_error_class test_error_class.cpp)
target_link_libraries(test_error_class PRIVATE lammps GTest::GMock GTest::GTest)
add_test(ErrorClass test_error_class)

View File

@ -0,0 +1,150 @@
// unit tests for issuing command to a LAMMPS instance through the Input class
#include "error.h"
#include "info.h"
#include "lammps.h"
#include "output.h"
#include "thermo.h"
#include "../testing/core.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <string>
// whether to print verbose output (i.e. not capturing LAMMPS screen output).
bool verbose = false;
namespace LAMMPS_NS {
using ::testing::MatchesRegex;
using utils::split_words;
class Error_class : public LAMMPSTest {
protected:
Error *error;
Thermo *thermo;
void SetUp() override
{
testbinary = "ErrorClass";
LAMMPSTest::SetUp();
error = lmp->error;
thermo = lmp->output->thermo;
}
};
TEST_F(Error_class, message)
{
auto output = CAPTURE_OUTPUT([&] {
error->message(FLERR, "one message");
});
ASSERT_THAT(output, MatchesRegex("one message .*test_error_class.cpp:.*"));
};
TEST_F(Error_class, warning)
{
// standard warning
auto output = CAPTURE_OUTPUT([&] {
error->warning(FLERR, "one warning");
});
ASSERT_THAT(output, MatchesRegex("WARNING: one warning .*test_error_class.cpp:.*"));
ASSERT_THAT(error->get_maxwarn(), 100);
// warnings disabled
HIDE_OUTPUT([&] {
command("thermo_modify warn ignore");
});
output = CAPTURE_OUTPUT([&] {
error->warning(FLERR, "one warning");
});
ASSERT_THAT(error->get_maxwarn(), -1);
BEGIN_HIDE_OUTPUT();
command("thermo_modify warn 2");
error->warning(FLERR, "one warning");
error->warning(FLERR, "one warning");
error->warning(FLERR, "one warning");
END_HIDE_OUTPUT();
ASSERT_THAT(error->get_maxwarn(), 2);
ASSERT_THAT(error->get_numwarn(), 5);
output = CAPTURE_OUTPUT([&] {
thermo->lost_check();
});
ASSERT_THAT(output, MatchesRegex("WARNING: Too many warnings: 5 vs 2. All future.*"));
output = CAPTURE_OUTPUT([&] {
error->warning(FLERR, "one warning");
});
ASSERT_EQ(output, "");
BEGIN_HIDE_OUTPUT();
command("thermo_modify warn reset");
thermo->lost_check();
error->warning(FLERR, "one warning");
END_HIDE_OUTPUT();
ASSERT_THAT(error->get_maxwarn(), 2);
ASSERT_THAT(error->get_numwarn(), 1);
output = CAPTURE_OUTPUT([&] {
error->warning(FLERR, "one warning");
});
ASSERT_THAT(output, MatchesRegex("WARNING: one warning.*"));
BEGIN_HIDE_OUTPUT();
command("thermo_modify warn default");
thermo->lost_check();
error->warning(FLERR, "one warning");
END_HIDE_OUTPUT();
ASSERT_THAT(error->get_maxwarn(), 100);
ASSERT_THAT(error->get_numwarn(), 1);
BEGIN_HIDE_OUTPUT();
command("thermo_modify warn always");
thermo->lost_check();
error->warning(FLERR, "one warning");
END_HIDE_OUTPUT();
ASSERT_THAT(error->get_maxwarn(), 0);
ASSERT_THAT(error->get_numwarn(), 2);
};
TEST_F(Error_class, one)
{
TEST_FAILURE("ERROR on proc 0: one error.*test_error_class.cpp:.*",
error->one(FLERR, "one error"););
};
TEST_F(Error_class, all)
{
TEST_FAILURE("ERROR: one error.*test_error_class.cpp:.*", error->all(FLERR, "one error"););
};
} // namespace LAMMPS_NS
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
::testing::InitGoogleMock(&argc, argv);
if (Info::get_mpi_vendor() == "Open MPI" && !LAMMPS_NS::Info::has_exceptions())
std::cout << "Warning: using OpenMPI without exceptions. "
"Death tests will be skipped\n";
// handle arguments passed via environment variable
if (const char *var = getenv("TEST_ARGS")) {
std::vector<std::string> env = split_words(var);
for (auto arg : env) {
if (arg == "-v") {
verbose = true;
}
}
}
if ((argc > 1) && (strcmp(argv[1], "-v") == 0)) verbose = true;
int rv = RUN_ALL_TESTS();
MPI_Finalize();
return rv;
}

View File

@ -1,13 +1,17 @@
// unit tests for the LAMMPS base class
#include "comm.h"
#include "info.h"
#include "lammps.h"
#include <cstdio> // for stdin, stdout
#include <cstdio> // for stdin, stdout
#include <cstdlib> // for setenv
#include <mpi.h>
#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::MatchesRegex;
using ::testing::StartsWith;
namespace LAMMPS_NS {
@ -318,10 +322,49 @@ TEST_F(LAMMPS_kokkos, InitMembers)
}
}
// check help message printing
TEST(LAMMPS_help, HelpMessage)
TEST(LAMMPS_init, OpenMP)
{
const char *args[] = {"LAMMPS_test", "-h"};
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (Info::get_openmp_info() == "OpenMP not enabled") GTEST_SKIP();
FILE *fp = fopen("in.lammps_empty", "w");
fputs("\n", fp);
fclose(fp);
const char *args[] = {"LAMMPS_init", "-in", "in.lammps_empty", "-log", "none", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
::testing::internal::CaptureStdout();
LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
std::string output = ::testing::internal::GetCapturedStdout();
EXPECT_THAT(output, MatchesRegex(".*using 2 OpenMP thread.*per MPI task.*"));
if (LAMMPS_NS::Info::has_accelerator_feature("USER-OMP", "api", "openmp"))
EXPECT_EQ(lmp->comm->nthreads, 2);
else
EXPECT_EQ(lmp->comm->nthreads, 1);
::testing::internal::CaptureStdout();
delete lmp;
::testing::internal::GetCapturedStdout();
remove("in.lammps_empty");
}
// check no OMP_NUM_THREADS warning message printing. this must be the
// last OpenMP related test as threads will be locked to 1 from here on.
TEST(LAMMPS_init, NoOpenMP)
{
if (!LAMMPS_NS::Info::has_accelerator_feature("USER-OMP", "api", "openmp"))
GTEST_SKIP() << "No threading enabled";
FILE *fp = fopen("in.lammps_class_noomp", "w");
fputs("\n", fp);
fclose(fp);
unsetenv("OMP_NUM_THREADS");
const char *args[] = {"LAMMPS_init", "-in", "in.lammps_class_noomp", "-log", "none", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
@ -329,7 +372,11 @@ TEST(LAMMPS_help, HelpMessage)
LAMMPS *lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
std::string output = ::testing::internal::GetCapturedStdout();
EXPECT_THAT(output,
StartsWith("\nLarge-scale Atomic/Molecular Massively Parallel Simulator -"));
MatchesRegex(".*OMP_NUM_THREADS environment is not set.*Defaulting to 1 thread.*"));
EXPECT_EQ(lmp->comm->nthreads, 1);
::testing::internal::CaptureStdout();
delete lmp;
::testing::internal::GetCapturedStdout();
}
} // namespace LAMMPS_NS

View File

@ -33,7 +33,7 @@ else()
target_link_libraries(style_tests PUBLIC mpi_stubs)
endif()
# propagate sanitizer options to test tools
if (NOT ENABLE_SANITIZER STREQUAL "none")
if (ENABLE_SANITIZER AND (NOT ENABLE_SANITIZER STREQUAL "none"))
if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.13)
target_compile_options(style_tests PUBLIC -fsanitize=${ENABLE_SANITIZER})
target_link_options(style_tests PUBLIC -fsanitize=${ENABLE_SANITIZER})
@ -124,6 +124,27 @@ file(GLOB FIX_TIMESTEP_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/fix-tim
foreach(TEST ${FIX_TIMESTEP_TESTS})
string(REGEX REPLACE "^.*fix-timestep-(.*)\.yaml" "FixTimestep:\\1" TNAME ${TEST})
add_test(NAME ${TNAME} COMMAND test_fix_timestep ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:${LAMMPS_PYTHON_DIR}:$ENV{PYTHONPATH}")
endforeach()
# dihedral style tester
add_executable(test_dihedral_style test_dihedral_style.cpp)
target_link_libraries(test_dihedral_style PRIVATE lammps style_tests)
file(GLOB DIHEDRAL_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/dihedral-*.yaml)
foreach(TEST ${DIHEDRAL_TESTS})
string(REGEX REPLACE "^.*dihedral-(.*)\.yaml" "DihedralStyle:\\1" TNAME ${TEST})
add_test(NAME ${TNAME} COMMAND test_dihedral_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
endforeach()
# improper style tester
add_executable(test_improper_style test_improper_style.cpp)
target_link_libraries(test_improper_style PRIVATE lammps style_tests)
file(GLOB IMPROPER_TESTS LIST_DIRECTORIES false ${TEST_INPUT_FOLDER}/improper-*.yaml)
foreach(TEST ${IMPROPER_TESTS})
string(REGEX REPLACE "^.*improper-(.*)\.yaml" "ImproperStyle:\\1" TNAME ${TEST})
add_test(NAME ${TNAME} COMMAND test_improper_style ${TEST} WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
set_tests_properties(${TNAME} PROPERTIES ENVIRONMENT "LAMMPS_POTENTIALS=${LAMMPS_POTENTIALS_DIR};PYTHONPATH=${TEST_INPUT_FOLDER}:$ENV{PYTHONPATH}")
endforeach()

View File

@ -38,7 +38,6 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <mpi.h>
#include <map>
@ -235,41 +234,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
YamlWriter writer(outfile);
// lammps_version
writer.emit("lammps_version", lmp->version);
// date_generated
std::time_t now = time(NULL);
block = ctime(&now);
block = block.substr(0, block.find("\n") - 1);
writer.emit("date_generated", block);
// epsilon
writer.emit("epsilon", config.epsilon);
// prerequisites
block.clear();
for (auto &prerequisite : config.prerequisites) {
block += prerequisite.first + " " + prerequisite.second + "\n";
}
writer.emit_block("prerequisites", block);
// pre_commands
block.clear();
for (auto &command : config.pre_commands) {
block += command + "\n";
}
writer.emit_block("pre_commands", block);
// post_commands
block.clear();
for (auto &command : config.post_commands) {
block += command + "\n";
}
writer.emit_block("post_commands", block);
// input_file
writer.emit("input_file", config.input_file);
// write yaml header
write_yaml_header(&writer, &test_config, lmp->version);
// angle_style
writer.emit("angle_style", config.angle_style);
@ -307,8 +273,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// init_forces
block.clear();
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
auto f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
@ -328,8 +293,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
writer.emit_block("run_stress", block);
block.clear();
f = lmp->atom->f;
tag = lmp->atom->tag;
f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
@ -342,6 +306,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
TEST(AngleStyle, plain)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
@ -568,6 +534,8 @@ TEST(AngleStyle, plain)
TEST(AngleStyle, omp)
{
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "omp", "4", "-sf", "omp"};
@ -741,6 +709,8 @@ TEST(AngleStyle, omp)
TEST(AngleStyle, single)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"AngleStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;

View File

@ -38,7 +38,6 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <mpi.h>
#include <map>
@ -235,41 +234,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
YamlWriter writer(outfile);
// lammps_version
writer.emit("lammps_version", lmp->version);
// date_generated
std::time_t now = time(NULL);
block = ctime(&now);
block = block.substr(0, block.find("\n") - 1);
writer.emit("date_generated", block);
// epsilon
writer.emit("epsilon", config.epsilon);
// prerequisites
block.clear();
for (auto &prerequisite : config.prerequisites) {
block += prerequisite.first + " " + prerequisite.second + "\n";
}
writer.emit_block("prerequisites", block);
// pre_commands
block.clear();
for (auto &command : config.pre_commands) {
block += command + "\n";
}
writer.emit_block("pre_commands", block);
// post_commands
block.clear();
for (auto &command : config.post_commands) {
block += command + "\n";
}
writer.emit_block("post_commands", block);
// input_file
writer.emit("input_file", config.input_file);
// write yaml header
write_yaml_header(&writer, &test_config, lmp->version);
// bond_style
writer.emit("bond_style", config.bond_style);
@ -307,8 +273,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// init_forces
block.clear();
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
auto f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
@ -328,8 +293,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
writer.emit_block("run_stress", block);
block.clear();
f = lmp->atom->f;
tag = lmp->atom->tag;
f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
@ -342,6 +306,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
TEST(BondStyle, plain)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
@ -568,6 +534,8 @@ TEST(BondStyle, plain)
TEST(BondStyle, omp)
{
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "omp", "4", "-sf", "omp"};
@ -740,6 +708,8 @@ TEST(BondStyle, omp)
TEST(BondStyle, single)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
@ -996,6 +966,8 @@ TEST(BondStyle, single)
TEST(BondStyle, extract)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"BondStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;

View File

@ -14,6 +14,7 @@
#ifndef TEST_CONFIG_H
#define TEST_CONFIG_H
#include <set>
#include <string>
#include <utility>
#include <vector>
@ -32,6 +33,7 @@ public:
std::string date_generated;
std::string basename;
double epsilon;
std::set<std::string> skip_tests;
std::vector<std::pair<std::string, std::string>> prerequisites;
std::vector<std::string> pre_commands;
std::vector<std::string> post_commands;
@ -74,6 +76,7 @@ public:
init_vdwl(0), run_vdwl(0), init_coul(0), run_coul(0), init_stress({0, 0, 0, 0, 0, 0}),
run_stress({0, 0, 0, 0, 0, 0}), global_scalar(0)
{
skip_tests.clear();
prerequisites.clear();
pre_commands.clear();
post_commands.clear();

View File

@ -15,6 +15,7 @@
#include "test_config.h"
#include "yaml.h"
#include "yaml_reader.h"
#include "utils.h"
#include <cstdlib>
#include <cstring>
@ -25,11 +26,14 @@
#include <utility>
#include <vector>
using LAMMPS_NS::utils::split_words;
TestConfigReader::TestConfigReader(TestConfig &config) : YamlReader(), config(config)
{
consumers["lammps_version"] = &TestConfigReader::lammps_version;
consumers["date_generated"] = &TestConfigReader::date_generated;
consumers["epsilon"] = &TestConfigReader::epsilon;
consumers["skip_tests"] = &TestConfigReader::skip_tests;
consumers["prerequisites"] = &TestConfigReader::prerequisites;
consumers["pre_commands"] = &TestConfigReader::pre_commands;
consumers["post_commands"] = &TestConfigReader::post_commands;
@ -53,13 +57,24 @@ TestConfigReader::TestConfigReader(TestConfig &config) : YamlReader(), config(co
consumers["global_scalar"] = &TestConfigReader::global_scalar;
consumers["global_vector"] = &TestConfigReader::global_vector;
consumers["bond_style"] = &TestConfigReader::bond_style;
consumers["bond_coeff"] = &TestConfigReader::bond_coeff;
consumers["angle_style"] = &TestConfigReader::angle_style;
consumers["angle_coeff"] = &TestConfigReader::angle_coeff;
consumers["init_energy"] = &TestConfigReader::init_energy;
consumers["run_energy"] = &TestConfigReader::run_energy;
consumers["equilibrium"] = &TestConfigReader::equilibrium;
consumers["bond_style"] = &TestConfigReader::bond_style;
consumers["bond_coeff"] = &TestConfigReader::bond_coeff;
consumers["angle_style"] = &TestConfigReader::angle_style;
consumers["angle_coeff"] = &TestConfigReader::angle_coeff;
consumers["dihedral_style"] = &TestConfigReader::dihedral_style;
consumers["dihedral_coeff"] = &TestConfigReader::dihedral_coeff;
consumers["improper_style"] = &TestConfigReader::improper_style;
consumers["improper_coeff"] = &TestConfigReader::improper_coeff;
consumers["init_energy"] = &TestConfigReader::init_energy;
consumers["run_energy"] = &TestConfigReader::run_energy;
consumers["equilibrium"] = &TestConfigReader::equilibrium;
}
void TestConfigReader::skip_tests(const yaml_event_t &event)
{
config.skip_tests.clear();
for (auto &word : split_words((char *)event.data.scalar.value))
config.skip_tests.insert(word);
}
void TestConfigReader::prerequisites(const yaml_event_t &event)
@ -259,6 +274,38 @@ void TestConfigReader::angle_coeff(const yaml_event_t &event)
}
}
void TestConfigReader::dihedral_style(const yaml_event_t &event)
{
config.dihedral_style = (char *)event.data.scalar.value;
}
void TestConfigReader::dihedral_coeff(const yaml_event_t &event)
{
config.dihedral_coeff.clear();
std::stringstream data((char *)event.data.scalar.value);
std::string line;
while (std::getline(data, line, '\n')) {
config.dihedral_coeff.push_back(line);
}
}
void TestConfigReader::improper_style(const yaml_event_t &event)
{
config.improper_style = (char *)event.data.scalar.value;
}
void TestConfigReader::improper_coeff(const yaml_event_t &event)
{
config.improper_coeff.clear();
std::stringstream data((char *)event.data.scalar.value);
std::string line;
while (std::getline(data, line, '\n')) {
config.improper_coeff.push_back(line);
}
}
void TestConfigReader::equilibrium(const yaml_event_t &event)
{
std::stringstream data((char *)event.data.scalar.value);

View File

@ -23,6 +23,7 @@ class TestConfigReader : public YamlReader<TestConfigReader> {
public:
TestConfigReader(TestConfig &config);
void skip_tests(const yaml_event_t &event);
void prerequisites(const yaml_event_t &event);
void pre_commands(const yaml_event_t &event);
void post_commands(const yaml_event_t &event);
@ -44,6 +45,10 @@ public:
void bond_coeff(const yaml_event_t &event);
void angle_style(const yaml_event_t &event);
void angle_coeff(const yaml_event_t &event);
void dihedral_style(const yaml_event_t &event);
void dihedral_coeff(const yaml_event_t &event);
void improper_style(const yaml_event_t &event);
void improper_coeff(const yaml_event_t &event);
void equilibrium(const yaml_event_t &event);
void init_vdwl(const yaml_event_t &event);
void init_coul(const yaml_event_t &event);

View File

@ -0,0 +1,711 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://lammps.sandia.gov/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
// unit tests for dihedral styles intended for molecular systems
#include "error_stats.h"
#include "test_config.h"
#include "test_config_reader.h"
#include "test_main.h"
#include "yaml_reader.h"
#include "yaml_writer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "atom.h"
#include "compute.h"
#include "dihedral.h"
#include "fmt/format.h"
#include "force.h"
#include "info.h"
#include "input.h"
#include "lammps.h"
#include "modify.h"
#include "universe.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <mpi.h>
#include <map>
#include <string>
#include <utility>
#include <vector>
using ::testing::HasSubstr;
using ::testing::StartsWith;
using namespace LAMMPS_NS;
static void delete_file(const std::string &filename)
{
remove(filename.c_str());
};
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
{
delete_file(cfg.basename + ".restart");
delete_file(cfg.basename + ".data");
delete_file(cfg.basename + "-coeffs.in");
delete lmp;
}
LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true)
{
LAMMPS *lmp;
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
// check if prerequisite styles are available
Info *info = new Info(lmp);
int nfail = 0;
for (auto &prerequisite : cfg.prerequisites) {
std::string style = prerequisite.second;
// this is a test for dihedral styles, so if the suffixed
// version is not available, there is no reason to test.
if (prerequisite.first == "dihedral") {
if (lmp->suffix_enable) {
style += "/";
style += lmp->suffix;
}
}
if (!info->has_style(prerequisite.first, style)) ++nfail;
}
delete info;
if (nfail > 0) {
cleanup_lammps(lmp, cfg);
return nullptr;
}
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
};
if (newton) {
command("variable newton_bond index on");
} else {
command("variable newton_bond index off");
}
command("variable input_dir index " + INPUT_FOLDER);
for (auto &pre_command : cfg.pre_commands) {
command(pre_command);
}
std::string input_file = INPUT_FOLDER + PATH_SEP + cfg.input_file;
parse_input_script(input_file);
command("dihedral_style " + cfg.dihedral_style);
for (auto &dihedral_coeff : cfg.dihedral_coeff) {
command("dihedral_coeff " + dihedral_coeff);
}
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
command("run 0 post no");
command("write_restart " + cfg.basename + ".restart");
command("write_data " + cfg.basename + ".data");
command("write_coeff " + cfg.basename + "-coeffs.in");
return lmp;
}
void run_lammps(LAMMPS *lmp)
{
// utility lambda to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
command("fix 1 all nve");
command("compute pe all pe/atom dihedral");
command("compute sum all reduce sum c_pe");
command("thermo_style custom step temp pe press c_sum");
command("thermo 2");
command("run 4 post no");
}
void restart_lammps(LAMMPS *lmp, const TestConfig &cfg)
{
// utility lambda to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
command("clear");
command("read_restart " + cfg.basename + ".restart");
if (!lmp->force->dihedral) {
command("dihedral_style " + cfg.dihedral_style);
}
if ((cfg.dihedral_style.substr(0, 6) == "hybrid") || !lmp->force->dihedral->writedata) {
for (auto &dihedral_coeff : cfg.dihedral_coeff) {
command("dihedral_coeff " + dihedral_coeff);
}
}
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
command("run 0 post no");
}
void data_lammps(LAMMPS *lmp, const TestConfig &cfg)
{
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
};
command("clear");
command("variable dihedral_style delete");
command("variable data_file delete");
command("variable newton_bond delete");
command("variable newton_bond index on");
for (auto &pre_command : cfg.pre_commands) {
command(pre_command);
}
command("variable dihedral_style index '" + cfg.dihedral_style + "'");
command("variable data_file index " + cfg.basename + ".data");
// special treatment for dihedral styles charmm and charmmfsw
if (cfg.dihedral_style == "charmm") {
command("variable pair_style delete");
command("variable pair_style index 'lj/charmm/coul/charmm 7.0 8.0'");
} else if (cfg.dihedral_style == "charmmfsw") {
command("variable pair_style delete");
command("variable pair_style index 'lj/charmmfsw/coul/charmmfsh 7.0 8.0'");
}
std::string input_file = INPUT_FOLDER + PATH_SEP + cfg.input_file;
parse_input_script(input_file);
for (auto &dihedral_coeff : cfg.dihedral_coeff) {
command("dihedral_coeff " + dihedral_coeff);
}
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
command("run 0 post no");
}
// re-generate yaml file with current settings.
void generate_yaml_file(const char *outfile, const TestConfig &config)
{
// initialize system geometry
const char *args[] = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
LAMMPS *lmp = init_lammps(argc, argv, config);
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
for (auto &prerequisite : config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
return;
}
const int natoms = lmp->atom->natoms;
std::string block("");
YamlWriter writer(outfile);
// write yaml header
write_yaml_header(&writer, &test_config, lmp->version);
// dihedral_style
writer.emit("dihedral_style", config.dihedral_style);
// dihedral_coeff
block.clear();
for (auto &dihedral_coeff : config.dihedral_coeff) {
block += dihedral_coeff + "\n";
}
writer.emit_block("dihedral_coeff", block);
// extract
block.clear();
for (auto data : config.extract)
block += fmt::format("{} {}\n", data.first, data.second);
writer.emit_block("extract", block);
// natoms
writer.emit("natoms", natoms);
// init_energy
writer.emit("init_energy", lmp->force->dihedral->energy);
// init_stress
auto stress = lmp->force->dihedral->virial;
block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0],
stress[1], stress[2], stress[3], stress[4], stress[5]);
writer.emit_block("init_stress", block);
// init_forces
block.clear();
auto f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
}
writer.emit_block("init_forces", block);
// do a few steps of MD
run_lammps(lmp);
// run_energy
writer.emit("run_energy", lmp->force->dihedral->energy);
// run_stress
stress = lmp->force->dihedral->virial;
block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0],
stress[1], stress[2], stress[3], stress[4], stress[5]);
writer.emit_block("run_stress", block);
block.clear();
f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
}
writer.emit_block("run_forces", block);
cleanup_lammps(lmp, config);
return;
}
TEST(DihedralStyle, plain)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(argc, argv, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
double epsilon = test_config.epsilon;
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
ErrorStats stats;
stats.reset();
const std::vector<coord_t> &f_ref = test_config.init_forces;
ASSERT_EQ(nlocal + 1, f_ref.size());
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton on: " << stats << std::endl;
auto dihedral = lmp->force->dihedral;
auto stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, epsilon);
if (print_stats) std::cerr << "init_stress stats, newton on: " << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stress = dihedral->virial;
const std::vector<coord_t> &f_run = test_config.run_forces;
ASSERT_EQ(nlocal + 1, f_run.size());
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton on: " << stats << std::endl;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, epsilon);
if (print_stats) std::cerr << "run_stress stats, newton on: " << stats << std::endl;
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon);
EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(argc, argv, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton off:" << stats << std::endl;
dihedral = lmp->force->dihedral;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 2 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton off:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stress = dihedral->virial;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton off:" << stats << std::endl;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, epsilon);
if (print_stats) std::cerr << "run_stress stats, newton off:" << stats << std::endl;
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon);
EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
restart_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
ASSERT_EQ(nlocal + 1, f_ref.size());
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "restart_forces stats:" << stats << std::endl;
dihedral = lmp->force->dihedral;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, epsilon);
if (print_stats) std::cerr << "restart_stress stats:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "restart_energy stats:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
data_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
ASSERT_EQ(nlocal + 1, f_ref.size());
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "data_forces stats:" << stats << std::endl;
dihedral = lmp->force->dihedral;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, epsilon);
if (print_stats) std::cerr << "data_stress stats:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "data_energy stats:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(DihedralStyle, omp)
{
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"DihedralStyle", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "omp", "4", "-sf", "omp"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(argc, argv, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /omp suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error a bit for USER-OMP package
double epsilon = 5.0 * test_config.epsilon;
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
const std::vector<coord_t> &f_ref = test_config.init_forces;
ErrorStats stats;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton on: " << stats << std::endl;
auto dihedral = lmp->force->dihedral;
auto stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton on: " << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stress = dihedral->virial;
const std::vector<coord_t> &f_run = test_config.run_forces;
ASSERT_EQ(nlocal + 1, f_run.size());
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton on: " << stats << std::endl;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "run_stress stats, newton on: " << stats << std::endl;
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon);
// TODO: this is currently broken for USER-OMP with dihedral style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
if (test_config.dihedral_style.substr(0, 6) != "hybrid")
EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(argc, argv, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton off:" << stats << std::endl;
dihedral = lmp->force->dihedral;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton off:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton off:" << stats << std::endl;
stress = dihedral->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "run_stress stats, newton off:" << stats << std::endl;
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(dihedral->energy, test_config.run_energy, epsilon);
// TODO: this is currently broken for USER-OMP with dihedral style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
if (test_config.dihedral_style.substr(0, 6) != "hybrid")
EXPECT_FP_LE_WITH_EPS(dihedral->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};

View File

@ -42,7 +42,6 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <mpi.h>
#include <map>
@ -193,41 +192,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
std::string block("");
YamlWriter writer(outfile);
// lammps_version
writer.emit("lammps_version", lmp->version);
// date_generated
std::time_t now = time(NULL);
block = ctime(&now);
block = block.substr(0, block.find("\n") - 1);
writer.emit("date_generated", block);
// epsilon
writer.emit("epsilon", config.epsilon);
// prerequisites
block.clear();
for (auto &prerequisite : config.prerequisites) {
block += prerequisite.first + " " + prerequisite.second + "\n";
}
writer.emit_block("prerequisites", block);
// pre_commands
block.clear();
for (auto &command : config.pre_commands) {
block += command + "\n";
}
writer.emit_block("pre_commands", block);
// post_commands
block.clear();
for (auto &command : config.post_commands) {
block += command + "\n";
}
writer.emit_block("post_commands", block);
// input_file
writer.emit("input_file", config.input_file);
// write yaml header
write_yaml_header(&writer, &test_config, lmp->version);
// natoms
writer.emit("natoms", natoms);
@ -288,6 +254,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
TEST(FixTimestep, plain)
{
if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
@ -730,6 +698,8 @@ TEST(FixTimestep, omp)
{
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (!LAMMPS::is_installed_pkg("MOLECULE")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"FixTimestep", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "omp", "4", "-sf", "omp"};

View File

@ -0,0 +1,702 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://lammps.sandia.gov/, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
// unit tests for improper styles intended for molecular systems
#include "error_stats.h"
#include "test_config.h"
#include "test_config_reader.h"
#include "test_main.h"
#include "yaml_reader.h"
#include "yaml_writer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "atom.h"
#include "compute.h"
#include "fmt/format.h"
#include "force.h"
#include "improper.h"
#include "info.h"
#include "input.h"
#include "lammps.h"
#include "modify.h"
#include "universe.h"
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <mpi.h>
#include <map>
#include <string>
#include <utility>
#include <vector>
using ::testing::HasSubstr;
using ::testing::StartsWith;
using namespace LAMMPS_NS;
static void delete_file(const std::string &filename)
{
remove(filename.c_str());
};
void cleanup_lammps(LAMMPS *lmp, const TestConfig &cfg)
{
delete_file(cfg.basename + ".restart");
delete_file(cfg.basename + ".data");
delete_file(cfg.basename + "-coeffs.in");
delete lmp;
}
LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool newton = true)
{
LAMMPS *lmp;
lmp = new LAMMPS(argc, argv, MPI_COMM_WORLD);
// check if prerequisite styles are available
Info *info = new Info(lmp);
int nfail = 0;
for (auto &prerequisite : cfg.prerequisites) {
std::string style = prerequisite.second;
// this is a test for improper styles, so if the suffixed
// version is not available, there is no reason to test.
if (prerequisite.first == "improper") {
if (lmp->suffix_enable) {
style += "/";
style += lmp->suffix;
}
}
if (!info->has_style(prerequisite.first, style)) ++nfail;
}
delete info;
if (nfail > 0) {
cleanup_lammps(lmp, cfg);
return nullptr;
}
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
};
if (newton) {
command("variable newton_bond index on");
} else {
command("variable newton_bond index off");
}
command("variable input_dir index " + INPUT_FOLDER);
for (auto &pre_command : cfg.pre_commands) {
command(pre_command);
}
std::string input_file = INPUT_FOLDER + PATH_SEP + cfg.input_file;
parse_input_script(input_file);
command("improper_style " + cfg.improper_style);
for (auto &improper_coeff : cfg.improper_coeff) {
command("improper_coeff " + improper_coeff);
}
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
command("run 0 post no");
command("write_restart " + cfg.basename + ".restart");
command("write_data " + cfg.basename + ".data");
command("write_coeff " + cfg.basename + "-coeffs.in");
return lmp;
}
void run_lammps(LAMMPS *lmp)
{
// utility lambda to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
command("fix 1 all nve");
command("compute pe all pe/atom improper");
command("compute sum all reduce sum c_pe");
command("thermo_style custom step temp pe press c_sum");
command("thermo 2");
command("run 4 post no");
}
void restart_lammps(LAMMPS *lmp, const TestConfig &cfg)
{
// utility lambda to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
command("clear");
command("read_restart " + cfg.basename + ".restart");
if (!lmp->force->improper) {
command("improper_style " + cfg.improper_style);
}
if ((cfg.improper_style.substr(0, 6) == "hybrid") || !lmp->force->improper->writedata) {
for (auto &improper_coeff : cfg.improper_coeff) {
command("improper_coeff " + improper_coeff);
}
}
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
command("run 0 post no");
}
void data_lammps(LAMMPS *lmp, const TestConfig &cfg)
{
// utility lambdas to improve readability
auto command = [&](const std::string &line) {
lmp->input->one(line.c_str());
};
auto parse_input_script = [&](const std::string &filename) {
lmp->input->file(filename.c_str());
};
command("clear");
command("variable improper_style delete");
command("variable data_file delete");
command("variable newton_bond delete");
command("variable newton_bond index on");
for (auto &pre_command : cfg.pre_commands) {
command(pre_command);
}
command("variable improper_style index '" + cfg.improper_style + "'");
command("variable data_file index " + cfg.basename + ".data");
std::string input_file = INPUT_FOLDER + PATH_SEP + cfg.input_file;
parse_input_script(input_file);
for (auto &improper_coeff : cfg.improper_coeff) {
command("improper_coeff " + improper_coeff);
}
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
command("run 0 post no");
}
// re-generate yaml file with current settings.
void generate_yaml_file(const char *outfile, const TestConfig &config)
{
// initialize system geometry
const char *args[] = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
LAMMPS *lmp = init_lammps(argc, argv, config);
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
for (auto &prerequisite : config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
return;
}
const int natoms = lmp->atom->natoms;
std::string block("");
YamlWriter writer(outfile);
// write yaml header
write_yaml_header(&writer, &test_config, lmp->version);
// improper_style
writer.emit("improper_style", config.improper_style);
// improper_coeff
block.clear();
for (auto &improper_coeff : config.improper_coeff) {
block += improper_coeff + "\n";
}
writer.emit_block("improper_coeff", block);
// extract
block.clear();
for (auto data : config.extract)
block += fmt::format("{} {}\n", data.first, data.second);
writer.emit_block("extract", block);
// natoms
writer.emit("natoms", natoms);
// init_energy
writer.emit("init_energy", lmp->force->improper->energy);
// init_stress
auto stress = lmp->force->improper->virial;
block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0],
stress[1], stress[2], stress[3], stress[4], stress[5]);
writer.emit_block("init_stress", block);
// init_forces
block.clear();
auto f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
}
writer.emit_block("init_forces", block);
// do a few steps of MD
run_lammps(lmp);
// run_energy
writer.emit("run_energy", lmp->force->improper->energy);
// run_stress
stress = lmp->force->improper->virial;
block = fmt::format("{:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e} {:23.16e}", stress[0],
stress[1], stress[2], stress[3], stress[4], stress[5]);
writer.emit_block("run_stress", block);
block.clear();
f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
}
writer.emit_block("run_forces", block);
cleanup_lammps(lmp, config);
return;
}
TEST(ImproperStyle, plain)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(argc, argv, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles are not available "
"in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
double epsilon = test_config.epsilon;
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
ErrorStats stats;
stats.reset();
const std::vector<coord_t> &f_ref = test_config.init_forces;
ASSERT_EQ(nlocal + 1, f_ref.size());
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton on: " << stats << std::endl;
auto improper = lmp->force->improper;
auto stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, epsilon);
if (print_stats) std::cerr << "init_stress stats, newton on: " << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stress = improper->virial;
const std::vector<coord_t> &f_run = test_config.run_forces;
ASSERT_EQ(nlocal + 1, f_run.size());
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton on: " << stats << std::endl;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, epsilon);
if (print_stats) std::cerr << "run_stress stats, newton on: " << stats << std::endl;
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon);
EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(argc, argv, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton off:" << stats << std::endl;
improper = lmp->force->improper;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 2 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 2 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton off:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stress = improper->virial;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton off:" << stats << std::endl;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, epsilon);
if (print_stats) std::cerr << "run_stress stats, newton off:" << stats << std::endl;
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon);
EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
restart_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
ASSERT_EQ(nlocal + 1, f_ref.size());
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "restart_forces stats:" << stats << std::endl;
improper = lmp->force->improper;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, epsilon);
if (print_stats) std::cerr << "restart_stress stats:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "restart_energy stats:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
data_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
ASSERT_EQ(nlocal + 1, f_ref.size());
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "data_forces stats:" << stats << std::endl;
improper = lmp->force->improper;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, epsilon);
if (print_stats) std::cerr << "data_stress stats:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "data_energy stats:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(ImproperStyle, omp)
{
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"ImproperStyle", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "omp", "4", "-sf", "omp"};
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(argc, argv, test_config, true);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /omp suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error a bit for USER-OMP package
double epsilon = 5.0 * test_config.epsilon;
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
const std::vector<coord_t> &f_ref = test_config.init_forces;
ErrorStats stats;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton on: " << stats << std::endl;
auto improper = lmp->force->improper;
auto stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton on: " << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stress = improper->virial;
const std::vector<coord_t> &f_run = test_config.run_forces;
ASSERT_EQ(nlocal + 1, f_run.size());
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton on: " << stats << std::endl;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "run_stress stats, newton on: " << stats << std::endl;
stats.reset();
int id = lmp->modify->find_compute("sum");
double energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon);
// TODO: this is currently broken for USER-OMP with improper style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
if (test_config.improper_style.substr(0, 6) != "hybrid")
EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton on: " << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
lmp = init_lammps(argc, argv, test_config, false);
if (!verbose) ::testing::internal::GetCapturedStdout();
// skip over these tests if newton bond is forced to be on
if (lmp->force->newton_bond == 0) {
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton off:" << stats << std::endl;
improper = lmp->force->improper;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton off:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.init_energy, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 10 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton off:" << stats << std::endl;
stress = improper->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "run_stress stats, newton off:" << stats << std::endl;
stats.reset();
id = lmp->modify->find_compute("sum");
energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(improper->energy, test_config.run_energy, epsilon);
// TODO: this is currently broken for USER-OMP with improper style hybrid
// needs to be fixed in the main code somewhere. Not sure where, though.
if (test_config.improper_style.substr(0, 6) != "hybrid")
EXPECT_FP_LE_WITH_EPS(improper->energy, energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
}
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};

View File

@ -16,16 +16,19 @@
#include "test_config.h"
#include "test_config_reader.h"
#include "utils.h"
#include "yaml_writer.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <mpi.h>
#include <vector>
using LAMMPS_NS::utils::split_words;
using LAMMPS_NS::utils::trim;
// common read_yaml_file function
bool read_yaml_file(const char *infile, TestConfig &config)
@ -37,6 +40,55 @@ bool read_yaml_file(const char *infile, TestConfig &config)
return true;
}
// write out common header items for yaml files
void write_yaml_header(YamlWriter *writer,
TestConfig *cfg,
const char *version)
{
// lammps_version
writer->emit("lammps_version", version);
// date_generated
std::time_t now = time(NULL);
std::string block = trim(ctime(&now));
writer->emit("date_generated", block);
// epsilon
writer->emit("epsilon", cfg->epsilon);
// skip tests
block.clear();
for (auto &skip : cfg->skip_tests) {
if (block.empty()) block = skip;
else block += " " + skip;
}
writer->emit("skip_tests", block);
// prerequisites
block.clear();
for (auto &prerequisite : cfg->prerequisites) {
block += prerequisite.first + " " + prerequisite.second + "\n";
}
writer->emit_block("prerequisites", block);
// pre_commands
block.clear();
for (auto &command : cfg->pre_commands) {
block += command + "\n";
}
writer->emit_block("pre_commands", block);
// post_commands
block.clear();
for (auto &command : cfg->post_commands) {
block += command + "\n";
}
writer->emit_block("post_commands", block);
// input_file
writer->emit("input_file", cfg->input_file);
}
// need to be defined in unit test body
extern void generate_yaml_file(const char *, const TestConfig &);

View File

@ -22,6 +22,10 @@ extern bool print_stats;
extern bool verbose;
extern std::string INPUT_FOLDER;
// convenience method to write out common entries
void write_yaml_header(class YamlWriter *writer, TestConfig *cfg,
const char *version);
#define EXPECT_FP_LE_WITH_EPS(val1, val2, eps) \
do { \
const double diff = fabs(val1 - val2); \
@ -31,10 +35,11 @@ extern std::string INPUT_FOLDER;
EXPECT_PRED_FORMAT2(::testing::DoubleLE, err, eps); \
} while (0);
#endif
#if defined _WIN32
static const char PATH_SEP = '\\';
#else
static const char PATH_SEP = '/';
#endif
#endif

View File

@ -25,7 +25,6 @@
#include "atom.h"
#include "compute.h"
#include "fmt/format.h"
#include "force.h"
#include "info.h"
#include "input.h"
@ -40,7 +39,6 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <mpi.h>
#include <map>
@ -125,6 +123,13 @@ LAMMPS *init_lammps(int argc, char **argv, const TestConfig &cfg, const bool new
command("pair_coeff " + pair_coeff);
}
// set this here explicitly to a setting different
// from the default, so we can spot YAML files for
// long-range interactions that do not include these
// settings. they will fail after restart or read data.
command("pair_modify table 0");
command("pair_modify table/disp 0");
for (auto &post_command : cfg.post_commands) {
command(post_command);
}
@ -238,41 +243,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
YamlWriter writer(outfile);
// lammps_version
writer.emit("lammps_version", lmp->version);
// date_generated
std::time_t now = time(NULL);
block = ctime(&now);
block = block.substr(0, block.find("\n") - 1);
writer.emit("date_generated", block);
// epsilon
writer.emit("epsilon", config.epsilon);
// prerequisites
block.clear();
for (auto &prerequisite : config.prerequisites) {
block += prerequisite.first + " " + prerequisite.second + "\n";
}
writer.emit_block("prerequisites", block);
// pre_commands
block.clear();
for (auto &command : config.pre_commands) {
block += command + "\n";
}
writer.emit_block("pre_commands", block);
// post_commands
block.clear();
for (auto &command : config.post_commands) {
block += command + "\n";
}
writer.emit_block("post_commands", block);
// input_file
writer.emit("input_file", config.input_file);
// write yaml header
write_yaml_header(&writer, &test_config, lmp->version);
// pair_style
writer.emit("pair_style", config.pair_style);
@ -307,8 +279,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
// init_forces
block.clear();
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
auto f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
@ -331,8 +302,7 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
writer.emit_block("run_stress", block);
block.clear();
f = lmp->atom->f;
tag = lmp->atom->tag;
f = lmp->atom->f;
for (int i = 1; i <= natoms; ++i) {
const int j = lmp->atom->map(i);
block += fmt::format("{:3} {:23.16e} {:23.16e} {:23.16e}\n", i, f[j][0], f[j][1], f[j][2]);
@ -345,6 +315,8 @@ void generate_yaml_file(const char *outfile, const TestConfig &config)
TEST(PairStyle, plain)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
@ -627,9 +599,14 @@ TEST(PairStyle, plain)
TEST(PairStyle, omp)
{
if (!LAMMPS::is_installed_pkg("USER-OMP")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "omp", "4", "-sf", "omp"};
// cannot run dpd styles with more than 1 thread due to using multiple pRNGs
if (utils::strmatch(test_config.pair_style, "^dpd")) args[8] = "1";
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
@ -651,14 +628,6 @@ TEST(PairStyle, omp)
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
if (utils::strmatch(test_config.pair_style, "^dpd")) {
std::cerr << "Skipping pair style " << lmp->force->pair_style << "\n";
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
GTEST_SKIP();
}
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
@ -806,13 +775,136 @@ TEST(PairStyle, omp)
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(PairStyle, gpu)
{
if (!LAMMPS::is_installed_pkg("GPU")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args_neigh[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "gpu"};
const char *args_noneigh[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "gpu", "-pk", "gpu", "0", "neigh", "no"};
char **argv = (char **)args_neigh;
int argc = sizeof(args_neigh) / sizeof(char *);
// cannot use GPU neighbor list with hybrid pair style (yet)
if (test_config.pair_style.substr(0, 6) == "hybrid") {
argv = (char **)args_noneigh;
argc = sizeof(args_noneigh) / sizeof(char *);
}
::testing::internal::CaptureStdout();
LAMMPS *lmp = init_lammps(argc, argv, test_config, false);
std::string output = ::testing::internal::GetCapturedStdout();
if (verbose) std::cout << output;
if (!lmp) {
std::cerr << "One or more prerequisite styles with /gpu suffix\n"
"are not available in this LAMMPS configuration:\n";
for (auto &prerequisite : test_config.prerequisites) {
std::cerr << prerequisite.first << "_style " << prerequisite.second << "\n";
}
GTEST_SKIP();
}
EXPECT_THAT(output, StartsWith("LAMMPS ("));
EXPECT_THAT(output, HasSubstr("Loop time"));
// abort if running in parallel and not all atoms are local
const int nlocal = lmp->atom->nlocal;
ASSERT_EQ(lmp->atom->natoms, nlocal);
// relax error for GPU package depending on precision setting
double epsilon = test_config.epsilon;
if (Info::has_accelerator_feature("GPU","precision","double"))
epsilon *= 7.5;
else if (Info::has_accelerator_feature("GPU","precision","mixed"))
epsilon *= 5.0e8;
else epsilon *= 1.0e10;
// relax test precision when using pppm and single precision FFTs, but only when also running with double precision
#if defined(FFT_SINGLE)
if (lmp->force->kspace && lmp->force->kspace->compute_flag && Info::has_accelerator_feature("GPU","precision","double"))
if (utils::strmatch(lmp->force->kspace_style, "^pppm")) epsilon *= 2.0e8;
#endif
const std::vector<coord_t> &f_ref = test_config.init_forces;
const std::vector<coord_t> &f_run = test_config.run_forces;
ErrorStats stats;
auto f = lmp->atom->f;
auto tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_ref[tag[i]].x, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_ref[tag[i]].y, epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_ref[tag[i]].z, epsilon);
}
if (print_stats) std::cerr << "init_forces stats, newton off:" << stats << std::endl;
auto pair = lmp->force->pair;
auto stress = pair->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.init_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.init_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.init_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.init_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.init_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.init_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "init_stress stats, newton off:" << stats << std::endl;
stats.reset();
EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.init_vdwl, epsilon);
EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.init_coul, epsilon);
if (print_stats) std::cerr << "init_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
run_lammps(lmp);
if (!verbose) ::testing::internal::GetCapturedStdout();
f = lmp->atom->f;
tag = lmp->atom->tag;
stats.reset();
for (int i = 0; i < nlocal; ++i) {
EXPECT_FP_LE_WITH_EPS(f[i][0], f_run[tag[i]].x, 5 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][1], f_run[tag[i]].y, 5 * epsilon);
EXPECT_FP_LE_WITH_EPS(f[i][2], f_run[tag[i]].z, 5 * epsilon);
}
if (print_stats) std::cerr << "run_forces stats, newton off:" << stats << std::endl;
stress = pair->virial;
stats.reset();
EXPECT_FP_LE_WITH_EPS(stress[0], test_config.run_stress.xx, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[1], test_config.run_stress.yy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[2], test_config.run_stress.zz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[3], test_config.run_stress.xy, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[4], test_config.run_stress.xz, 10 * epsilon);
EXPECT_FP_LE_WITH_EPS(stress[5], test_config.run_stress.yz, 10 * epsilon);
if (print_stats) std::cerr << "run_stress stats, newton off:" << stats << std::endl;
stats.reset();
auto id = lmp->modify->find_compute("sum");
auto energy = lmp->modify->compute[id]->compute_scalar();
EXPECT_FP_LE_WITH_EPS(pair->eng_vdwl, test_config.run_vdwl, epsilon);
EXPECT_FP_LE_WITH_EPS(pair->eng_coul, test_config.run_coul, epsilon);
EXPECT_FP_LE_WITH_EPS((pair->eng_vdwl + pair->eng_coul), energy, epsilon);
if (print_stats) std::cerr << "run_energy stats, newton off:" << stats << std::endl;
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
};
TEST(PairStyle, intel)
{
if (!LAMMPS::is_installed_pkg("USER-INTEL")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite",
"-pk", "intel", "0", "mode", "double", "omp",
"4", "lrt", "no", "-sf", "intel"};
// cannot use more than 1 thread for dpd styles due to pRNG
if (utils::strmatch(test_config.pair_style, "^dpd")) args[12] = "1";
char **argv = (char **)args;
int argc = sizeof(args) / sizeof(char *);
@ -831,22 +923,6 @@ TEST(PairStyle, intel)
GTEST_SKIP();
}
if ((test_config.pair_style == "rebo") || utils::strmatch(test_config.pair_style, "^dpd")) {
std::cerr << "Skipping pair style " << lmp->force->pair_style << "\n";
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
GTEST_SKIP();
}
if (lmp->force->kspace && utils::strmatch(lmp->force->kspace_style, "^pppm/disp/intel")) {
if (!verbose) ::testing::internal::CaptureStdout();
cleanup_lammps(lmp, test_config);
if (!verbose) ::testing::internal::GetCapturedStdout();
std::cerr << "Skipping kspace style pppm/disp/intel\n";
GTEST_SKIP();
}
// relax error a bit for USER-INTEL package
double epsilon = 7.5 * test_config.epsilon;
// relax test precision when using pppm and single precision FFTs
@ -947,6 +1023,8 @@ TEST(PairStyle, intel)
TEST(PairStyle, opt)
{
if (!LAMMPS::is_installed_pkg("OPT")) GTEST_SKIP();
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite", "-sf", "opt"};
char **argv = (char **)args;
@ -1052,6 +1130,8 @@ TEST(PairStyle, opt)
TEST(PairStyle, single)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;
@ -1309,6 +1389,8 @@ TEST(PairStyle, single)
TEST(PairStyle, extract)
{
if (test_config.skip_tests.count(test_info_->name())) GTEST_SKIP();
const char *args[] = {"PairStyle", "-log", "none", "-echo", "screen", "-nocite"};
char **argv = (char **)args;

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:23 2021
epsilon: 5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:23 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:23 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:23 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:23 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 8 Apr 2021
date_generated: Thu Apr 8 09:28:11 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -11,32 +11,32 @@ input_file: in.fourmol
angle_style: cosine/periodic
angle_coeff: ! |
1 75.0 1 2
2 45.0 1 2
2 45.0 -1 2
3 50.0 -1 3
4 100.0 -1 4
equilibrium: 4 3.141592653589793 3.141592653589793 3.141592653589793 3.141592653589793
equilibrium: 4 3.141592653589793 1.5707963267948966 2.0943951023931957 2.356194490192345
extract: ! ""
natoms: 29
init_energy: 946.676664091363
init_stress: ! |2-
3.8581448829084906e+00 -6.3926599144452858e+01 6.0068454261544439e+01 1.4347370855129017e+02 1.0109551149053127e+02 4.9470344115369670e+01
init_energy: 605.3643061001458
init_stress: ! |-
-1.7082420754402889e+01 -7.3281097507808681e+00 2.4410530505183818e+01 8.5827033671406951e+01 1.4260977966148616e+02 4.1579557432232576e+01
init_forces: ! |2
1 7.9609486050127529e+00 -3.9274211736421961e+01 -3.8917410871887981e+01
2 4.6997439470662350e+00 3.8052682089524090e+01 3.0599010994189470e+01
3 -4.4330179925982058e+01 -1.6514501437366098e+00 1.9894582317318523e+01
4 1.1465928779203908e+01 -7.1462736556935234e+00 -1.8983545733370338e+01
5 2.7634466780141157e+01 1.5504150132065057e+01 1.0078115065618357e+01
6 2.2512674572611367e+01 -5.4260358088923418e+01 -6.0646506351853276e+01
3 -7.1532072701475698e+01 9.6873528247272844e+01 7.3410935137796983e+01
4 3.1784763224659116e+01 -4.4133218046130608e+01 -6.2234613362865147e+01
5 5.8817481848549889e+01 -2.5112568523390145e+01 3.9611729278121981e+00
6 -8.7258065964885336e+00 -4.2663580774228997e+01 -1.6819642012415606e+01
7 -1.5578858996464229e+01 1.3895348629116569e+01 -3.3939856789628062e+00
8 -2.6028225001107934e+00 4.7418887884887312e+01 1.2659217319984802e+02
9 9.4419020144376677e+00 -1.3812152922900303e+01 1.2280697239365450e+00
10 3.7181742871134183e+01 -2.6592777970320334e+01 -1.0034832175946605e+02
11 1.1888648487599809e+01 -1.7288532453781471e+00 -1.8714004234488471e+00
12 1.3452345752647041e+01 3.9195153629390539e+01 -3.9429673136141247e+01
13 -4.6656310032990458e+00 -1.2502935413462930e+01 1.4918864440944628e+01
14 -2.1383527724886850e+01 -9.3422692044635554e+00 7.5125645645164223e+00
15 -8.0644375221897171e+00 -2.6783296801963008e+00 6.9267625241565547e+00
16 -7.0395776185793807e+01 4.3227686209287491e+01 3.0567216126495769e+01
8 -1.6678237064738614e+01 -2.6557373913973738e+01 8.7708427797183326e+00
9 -9.4419020144376677e+00 1.3812152922900303e+01 -1.2280697239365450e+00
10 1.0844630504236606e+02 1.9274264686364820e+01 1.2594098114786526e+01
11 -1.1888648487599809e+01 1.7288532453781471e+00 1.8714004234488471e+00
12 9.7432958614920665e+01 1.1284647087939499e+02 -1.3445218835244805e+02
13 -2.2887258478933525e+01 -5.9815335453575649e+01 4.1237962971772127e+01
14 -4.6498844054867675e+01 -3.0251289808967520e+01 1.5556535565006259e+01
15 -5.3477741242848616e+01 -1.7885978453267143e+01 4.6284681424489207e+01
16 -7.3215663693592745e+01 1.7514552522777997e+01 7.4857846653898914e+00
17 2.0782832048872386e+01 -2.8304296512773977e+01 1.5273484998106287e+01
18 1.6481336531704756e+00 1.7222946144801426e+01 -6.9896289164966490e+01
19 -2.0180190840279820e+01 -2.5140421523544326e+01 2.9933594625645306e+01
@ -50,27 +50,27 @@ init_forces: ! |2
27 -8.7971258084923178e+00 7.2217511410368814e+01 -2.4599681382405976e+01
28 -1.9235439225569891e+01 -4.3179911322776611e+01 1.0030656861974458e+00
29 2.8032565034062209e+01 -2.9037600087592210e+01 2.3596615696208531e+01
run_energy: 945.667120914027
run_stress: ! |2-
4.9007195370705645e+00 -6.4584848054201885e+01 5.9684128517131313e+01 1.4440631784196160e+02 1.0147779649040916e+02 5.0605123164347972e+01
run_energy: 603.8182365368202
run_stress: ! |-
-1.6098625319219664e+01 -7.7961962067566510e+00 2.3894821525976329e+01 8.7036156470651477e+01 1.4262918929621054e+02 4.2523803236880880e+01
run_forces: ! |2
1 8.0595707378962782e+00 -3.9275884216073550e+01 -3.8921834622274609e+01
2 4.6450877231394490e+00 3.7989319504376653e+01 3.0709930231636147e+01
3 -4.4174062041610540e+01 -1.3116774304574319e+00 1.9852389406583850e+01
4 1.1432955350908090e+01 -7.3978491536336328e+00 -1.8963452260213845e+01
5 2.7565769765719310e+01 1.5533965769082254e+01 1.0064393083030197e+01
6 2.2437947870916961e+01 -5.4321180615060769e+01 -6.0748488446866872e+01
7 -1.5585343433722571e+01 1.3904433399215314e+01 -3.4020204287915634e+00
8 -2.7173598979194153e+00 4.7428178462168347e+01 1.2654691883960646e+02
9 9.4915406599908749e+00 -1.3885257714808199e+01 1.2160209239091246e+00
10 3.7036130179485966e+01 -2.6384482125884212e+01 -1.0013051660330657e+02
11 1.1913327728618880e+01 -1.7105485662994653e+00 -1.8898750666441195e+00
12 1.3449580650332301e+01 3.9344535800585398e+01 -3.9552691785632291e+01
13 -4.6002052262583266e+00 -1.2370495939576998e+01 1.4765847794019894e+01
14 -2.1313398317698834e+01 -9.6666833306404527e+00 7.4826992840481967e+00
15 -8.0459573339780484e+00 -2.8098768831377434e+00 7.2021609989661499e+00
16 -7.0394187900784956e+01 4.3284348202675552e+01 3.0478355256814506e+01
17 2.0798603484964556e+01 -2.8350845162531051e+01 1.5290163395115368e+01
1 8.1036664069391833e+00 -3.9279459516104339e+01 -3.8959949625007155e+01
2 4.6488532958171156e+00 3.7987813821226069e+01 3.0712083303318757e+01
3 -7.1419656269516480e+01 9.7015207052323333e+01 7.3123837986656483e+01
4 3.1774739774255771e+01 -4.4324760214341296e+01 -6.1918121921961003e+01
5 5.8630133295649813e+01 -2.5003101567718115e+01 3.8957656941403842e+00
6 -8.6686835699933500e+00 -4.2717543793109854e+01 -1.6944132920021204e+01
7 -1.5605967450730276e+01 1.3924972058096937e+01 -3.4081311693274161e+00
8 -1.6735469954990947e+01 -2.6654949908594496e+01 8.9412902423392993e+00
9 -9.4705763934675620e+00 1.3861186924074314e+01 -1.2218212802251793e+00
10 1.0864309846473817e+02 1.9311615651482960e+01 1.2534898619395602e+01
11 -1.1889594908454491e+01 1.6849924892427488e+00 1.9039966312260486e+00
12 9.6643785665770423e+01 1.1329932305772147e+02 -1.3435213826206018e+02
13 -2.2815824864999897e+01 -5.9701629573330088e+01 4.1148977584672039e+01
14 -4.6226658006998740e+01 -3.0469540424436548e+01 1.5534272011399247e+01
15 -5.3141801628038777e+01 -1.8156497866651446e+01 4.6272398149175629e+01
16 -7.3254211788300807e+01 1.7569251761827239e+01 7.4522974142679850e+00
17 2.0784167932320894e+01 -2.8346879951708846e+01 1.5284477542010659e+01
18 1.7456021018344252e+00 1.7528557172698406e+01 -7.0852460721917453e+01
19 -2.0389936120749365e+01 -2.5462340563923114e+01 3.0421727677614534e+01
20 1.8644334018914940e+01 7.9337833912247095e+00 4.0430733044302912e+01

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:23 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 29 Oct 2020
date_generated: Sat Nov 14 17:18:12 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
epsilon: 2.5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 5e-13
prerequisites: ! |
atom full
angle harmonic

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:34 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:24 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
epsilon: 2.5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:25 2021
epsilon: 4e-13
prerequisites: ! |
atom full
angle quartic

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
epsilon: 2.5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:25 2021
epsilon: 5e-13
prerequisites: ! |
atom full
angle table

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
epsilon: 2.5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:25 2021
epsilon: 5e-13
prerequisites: ! |
atom full
angle table

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:35 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:25 2021
epsilon: 1e-14
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:58 2021
epsilon: 5e-13
prerequisites: ! |
pair adp

View File

@ -1,12 +1,12 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:58 2021
epsilon: 5e-12
prerequisites: ! |
pair atm
pre_commands: ! |
variable newton_pair delete
variable newton_pair index on
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
post_commands: ! ""
input_file: in.metal
pair_style: atm 12.0 5.0

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
epsilon: 5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 2e-12
prerequisites: ! |
pair beck
pre_commands: ! ""

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 5e-13
prerequisites: ! |
pair born

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 5e-14
prerequisites: ! |
pair colloid

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 5e-14
prerequisites: ! |
pair colloid

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 5e-13
prerequisites: ! |
pair colloid

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 5e-14
prerequisites: ! |
pair colloid

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:08:59 2021
epsilon: 5e-13
prerequisites: ! |
pair colloid

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:21 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:00 2021
epsilon: 6e-12
prerequisites: ! |
pair eam

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:00 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/alloy

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:00 2021
epsilon: 7.5e-12
prerequisites: ! |
pair eam/alloy

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:00 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/cd

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:00 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/cd/old

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:00 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/cd

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:01 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/fs

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:01 2021
epsilon: 7.5e-12
prerequisites: ! |
pair eam/fs

View File

@ -0,0 +1,89 @@
---
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:01 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/he
pre_commands: ! ""
post_commands: ! ""
input_file: in.metal
pair_style: eam/he
pair_coeff: ! |
* * PdHHe.eam.he Pd He
extract: ! ""
natoms: 32
init_vdwl: -15.3146152609365
init_coul: 0
init_stress: ! |2-
1.0127679615895376e+02 9.3559970433415444e+01 9.1432412459889193e+01 4.0035576925472673e+00 -9.7686923241135581e-01 2.8980241224200443e+00
init_forces: ! |2
1 1.2005847856522014e+00 2.2040396377071869e+00 -1.0711805842453261e+00
2 -1.5935390465573379e-01 -8.3057674140080351e-01 3.5885201320339977e-01
3 -8.3922102051696701e-02 4.1053523947712707e+00 3.2379570522514384e-01
4 9.6680271004438867e-01 -6.0272944088190550e-01 1.7088406391974090e-01
5 -1.5118032750014099e-01 4.8152982355843301e+00 -2.3396251503834162e-01
6 6.9769996639420007e-01 2.1986594375389688e+00 3.7782787462812606e-01
7 -1.9293747297385899e+00 2.3965302429887498e+00 5.3526894592078611e-01
8 -5.7898968354416502e-01 -1.7424269600946102e-01 4.6553500563912831e-01
9 -1.9170501143342826e+00 -1.5811474204082574e+00 -1.5153955037081890e+00
10 -1.0389874633978984e+00 -1.0136677465869111e+00 -2.8606245342679020e+00
11 -6.8937210559650852e-01 -4.9861949626741522e+00 1.7468278589450823e+00
12 -1.0247245841335400e+00 -2.9144176183755111e+00 1.0162869145592908e+00
13 8.8392380716960872e-01 -2.1032444766660849e-01 -4.5408294970791102e-01
14 3.9708226038326155e-01 -7.8680161984030961e-01 -1.9977901194159892e-01
15 -7.8687732774064545e-02 -2.1157301146984339e-01 3.4042801915998766e-01
16 4.0325457730206029e+00 -2.3548979291247609e+00 9.2949967143894952e-01
17 7.4997446543261548e-01 2.0845833390037725e+00 1.7238817466288217e+00
18 -2.1412087035667221e-01 -5.6906054172322229e-01 -5.2781467006833294e-01
19 -3.0256742141254084e-01 6.0688322127888294e-01 -9.1127162282408275e-02
20 2.3174481031809935e-01 3.0892939020181726e-01 -3.7137738763066941e-01
21 1.1702211057625094e+00 4.2920154821923315e+00 1.3460541385609648e+00
22 3.8027613826247031e-02 4.3239633632972230e-01 -3.8188409283423194e-02
23 1.4000432801696054e+00 1.0040601640391840e+00 -2.4122350019076917e+00
24 -1.5604155772955447e-01 3.4572668285914510e-01 -2.8556703863036959e-01
25 -2.9449464597969849e-01 -3.4630638648128692e-01 1.1805865362173559e-01
26 -1.8108866036308173e+00 -1.8950909756776353e+00 3.3196635723271326e+00
27 -7.7538420123902196e-01 -1.2937697587184989e+00 -9.6725767253143236e-01
28 -3.5707629120214823e-01 -2.8995606245962768e-01 -1.2007211500278167e-01
29 3.6987879522593697e-01 -4.9287949481541249e-01 5.4972323630766012e-02
30 1.1712105233973889e-01 -6.9110122964840481e-01 9.5437848811806628e-02
31 1.9388288555816860e-01 -2.0146460156127194e-01 -2.0863139798712499e-01
32 -8.8731897202011578e-01 -3.3482718789714783e+00 -1.5659784019873610e+00
run_vdwl: -15.3236335310355
run_coul: 0
run_stress: ! |2-
1.0125543392557182e+02 9.3539230810233988e+01 9.1388997082229878e+01 4.0040941706030253e+00 -9.7826716756924303e-01 2.9018476991088571e+00
run_forces: ! |2
1 1.1949883047712304e+00 2.2060858143622002e+00 -1.0733885545165418e+00
2 -1.5963527935293531e-01 -8.3496477000211577e-01 3.6354718487355586e-01
3 -8.4458087648033864e-02 4.1335068175946956e+00 3.2562083254074076e-01
4 9.7516402928123347e-01 -6.1050193540570252e-01 1.7035859794498676e-01
5 -1.5399721579534215e-01 4.8120569088649683e+00 -2.3294021119313149e-01
6 6.9813149221746262e-01 2.1977391468237610e+00 3.7752101367086355e-01
7 -1.9335938530288574e+00 2.3989898112356141e+00 5.3226592065468015e-01
8 -5.8346129298071359e-01 -1.7815682091755050e-01 4.6582930751668622e-01
9 -1.9172329351091069e+00 -1.5829627245185132e+00 -1.5163042130781048e+00
10 -1.0334176082685609e+00 -1.0148545000176199e+00 -2.8584769425899079e+00
11 -6.8756244404382794e-01 -4.9891360565883884e+00 1.7443920243481270e+00
12 -1.0236334662680082e+00 -2.9150791430800980e+00 1.0158839648906106e+00
13 8.8312645129364897e-01 -2.1071143805836662e-01 -4.5244072317123446e-01
14 3.9927871470591697e-01 -7.8979672016550584e-01 -2.0106817979273284e-01
15 -7.8923521050882781e-02 -2.1032668862489418e-01 3.3903131601122610e-01
16 4.0274555753165444e+00 -2.3555929271854597e+00 9.2684665883544881e-01
17 7.5117151275169469e-01 2.0849083749786277e+00 1.7261549167735377e+00
18 -2.1494836879728668e-01 -5.7509260272248663e-01 -5.3373034744908598e-01
19 -3.0249976756523766e-01 6.0674463278548640e-01 -9.1809428603960672e-02
20 2.3156742504597116e-01 3.0887145855490367e-01 -3.7127049070468199e-01
21 1.1686499084188677e+00 4.2891627780548545e+00 1.3459230037755703e+00
22 3.8179702424449569e-02 4.3243601345801236e-01 -3.8079863481504578e-02
23 1.4067770990537660e+00 1.0070141778822215e+00 -2.4069585948142982e+00
24 -1.5591693014836788e-01 3.4568121542161234e-01 -2.8546260901671355e-01
25 -2.9429104311734711e-01 -3.4618233584978003e-01 1.1804410855998390e-01
26 -1.8072996525588660e+00 -1.8933503719653344e+00 3.3208542120004427e+00
27 -7.7461160804433704e-01 -1.2927908441630280e+00 -9.6864680654489232e-01
28 -3.5780846246953718e-01 -2.8988724628268286e-01 -1.1924240028778682e-01
29 3.6970648233559189e-01 -4.9268726775164107e-01 5.5185028378882096e-02
30 1.1705695741665428e-01 -6.9122064837750197e-01 9.5592509524696681e-02
31 1.9349589373949760e-01 -1.9991899011439837e-01 -2.0661879538790651e-01
32 -8.9145801252527535e-01 -3.3499831182258872e+00 -1.5666124396675569e+00
...

View File

@ -0,0 +1,90 @@
---
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:02 2021
epsilon: 7.5e-12
prerequisites: ! |
pair eam/he
pre_commands: ! |
variable units index real
post_commands: ! ""
input_file: in.metal
pair_style: eam/he
pair_coeff: ! |
* * PdHHe.eam.he Pd He
extract: ! ""
natoms: 32
init_vdwl: -353.163435640974
init_coul: 0
init_stress: ! |2-
2.3354985203865667e+03 2.1575442826183294e+03 2.1084816277194832e+03 9.2324238343315059e+01 -2.2527140800613445e+01 6.6830027278251166e+01
init_forces: ! |2
1 2.7686144278186653e+01 5.0826364063289034e+01 -2.4702012350837244e+01
2 -3.6747885266547895e+00 -1.9153555643332677e+01 8.2753244342250110e+00
3 -1.9352897465461538e+00 9.4671680061884146e+01 7.4669067263334208e+00
4 2.2295001268309708e+01 -1.3899271805198000e+01 3.9406803293404700e+00
5 -3.4863013501526918e+00 1.1104342091130563e+02 -5.3953040422049119e+00
6 1.6089344262331657e+01 5.0702293693679884e+01 8.7129182164280419e+00
7 -4.4492440494497494e+01 5.5265303098423985e+01 1.2343595755584241e+01
8 -1.3351819967863772e+01 -4.0181322292175965e+00 1.0735492808756252e+01
9 -4.4208228097061294e+01 -3.6462127564548197e+01 -3.4945852267642280e+01
10 -2.3959621310073842e+01 -2.3375734739886113e+01 -6.5967572243087659e+01
11 -1.5897299220341502e+01 -1.1498439326030027e+02 4.0282809435768357e+01
12 -2.3630711483916183e+01 -6.7208070295011467e+01 2.3436134191253181e+01
13 2.0383768267501306e+01 -4.8501972313137021e+00 -1.0471402111803629e+01
14 9.1569349225997474e+00 -1.8144077307608963e+01 -4.6070136940518891e+00
15 -1.8145823173352931e+00 -4.8789897980772752e+00 7.8504570168111005e+00
16 9.2992719393484805e+01 -5.4305239084580101e+01 2.1434772718702309e+01
17 1.7294822908857860e+01 4.8071636233680366e+01 3.9753659488339430e+01
18 -4.9377448227825411e+00 -1.3122848506373817e+01 -1.2171696062028875e+01
19 -6.9773708472871210e+00 1.3995060261579386e+01 -2.1014423910442734e+00
20 5.3441625538361990e+00 7.1240813402889511e+00 -8.5641664449490893e+00
21 2.6985941150269763e+01 9.8976233335854843e+01 3.1040747418937880e+01
22 8.7693765199327156e-01 9.9712969013523196e+00 -8.8064568351232408e-01
23 3.2285766664472092e+01 2.3154178611774061e+01 -5.5627463461007146e+01
24 -3.5984039880587519e+00 7.9726471106807173e+00 -6.5853326871205784e+00
25 -6.7912082138528707e+00 -7.9860153944650030e+00 2.7224973667181924e+00
26 -4.1760039256471202e+01 -4.3701838304071202e+01 7.6553264473163750e+01
27 -1.7880785366498504e+01 -2.9835040915646299e+01 -2.2305492953037302e+01
28 -8.2343753100058397e+00 -6.6865459861976770e+00 -2.7689288915546530e+00
29 8.5296080813687887e+00 -1.1366071741285882e+01 1.2676919627309815e+00
30 2.7008757664122220e+00 -1.5937173770267322e+01 2.2008491889792485e+00
31 4.4710457826753673e+00 -4.6458843160683996e+00 -4.8111545762194012e+00
32 -2.0462062632899592e+01 -7.7212987730343386e+01 -3.6112321671970648e+01
run_vdwl: -353.230598025017
run_coul: 0
run_stress: ! |2-
2.3352018947327042e+03 2.1575803047701361e+03 2.1079997407908877e+03 9.2286943467903825e+01 -2.2591362673321409e+01 6.6981941401935686e+01
run_forces: ! |2
1 2.7570840184953529e+01 5.0878936563954468e+01 -2.4745193716885819e+01
2 -3.6751057733124783e+00 -1.9167341173087838e+01 8.2931871358142466e+00
3 -1.9458273195805660e+00 9.4745013001500453e+01 7.4613246126708113e+00
4 2.2322999682742939e+01 -1.3910836126089546e+01 3.9444558071725182e+00
5 -3.5611755339443869e+00 1.1098583048019351e+02 -5.3589546434886657e+00
6 1.6098529359830774e+01 5.0681471667414634e+01 8.7065695410635300e+00
7 -4.4532333454110486e+01 5.5329574524982760e+01 1.2275125678150991e+01
8 -1.3365798458276837e+01 -4.0311665119688325e+00 1.0738893622536514e+01
9 -4.4219909611484340e+01 -3.6506027825529728e+01 -3.4970646977778003e+01
10 -2.3838805073020580e+01 -2.3388505371089686e+01 -6.5920271795280030e+01
11 -1.5863107119046816e+01 -1.1501474143750076e+02 4.0236861649778703e+01
12 -2.3597639915238879e+01 -6.7219256881236532e+01 2.3428611972869568e+01
13 2.0372282061050672e+01 -4.8599967847476790e+00 -1.0435173423332810e+01
14 9.1868968538149876e+00 -1.8180822851027013e+01 -4.6226879613716969e+00
15 -1.8187982708833512e+00 -4.8633248636475823e+00 7.8331412550634454e+00
16 9.2883964220226872e+01 -5.4312212635591663e+01 2.1376066838247318e+01
17 1.7335571325471630e+01 4.8086629272887443e+01 3.9799611586568851e+01
18 -4.9380025631152833e+00 -1.3140883981374724e+01 -1.2192856535881621e+01
19 -6.9765790243039625e+00 1.3993117559236460e+01 -2.1082447485751517e+00
20 5.3413030155749288e+00 7.1244381338347607e+00 -8.5630059362592803e+00
21 2.6939069851048053e+01 9.8929039552947501e+01 3.1025635765431552e+01
22 8.7771899094057326e-01 9.9759331856305540e+00 -8.7675403015085085e-01
23 3.2451609933852048e+01 2.3224549699639688e+01 -5.5509981817200973e+01
24 -3.5964621834607793e+00 7.9732311561843838e+00 -6.5839559665478173e+00
25 -6.7879787318782503e+00 -7.9847098239766732e+00 2.7230073490545976e+00
26 -4.1688921616984544e+01 -4.3653314583134815e+01 7.6583618010794297e+01
27 -1.7863754347437737e+01 -2.9811723761490370e+01 -2.2339924855988965e+01
28 -8.2430574229283415e+00 -6.6852368720976481e+00 -2.7583576098041354e+00
29 8.5269603298722565e+00 -1.1364005508745327e+01 1.2731276160949609e+00
30 2.6994843727982003e+00 -1.5940803816308822e+01 2.2046514286792602e+00
31 4.4654048480426765e+00 -4.6271939008948024e+00 -4.7862215560852475e+00
32 -2.0559378611212470e+01 -7.7265660088866639e+01 -3.6131658295360147e+01
...

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:02 2021
epsilon: 5e-12
prerequisites: ! |
pair eam

View File

@ -1,13 +1,13 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:02 2021
epsilon: 7.5e-13
prerequisites: ! |
pair edip
pre_commands: ! |
echo screen
variable newton_pair delete
variable newton_pair index on
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
atom_modify map array
units metal
lattice diamond 5.43

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:02 2021
epsilon: 1e-11
prerequisites: ! |
pair eim

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:22 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:02 2021
epsilon: 5e-12
prerequisites: ! |
pair gauss

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
epsilon: 5e-12
lammps_version: 8 Apr 2021
date_generated: Mon Apr 19 08:49:08 2021
epsilon: 1e-11
prerequisites: ! |
pair eam/fs
pre_commands: ! ""
@ -13,7 +13,7 @@ pair_coeff: ! |
2 2 eam Ni_u3.eam
extract: ! ""
natoms: 32
init_vdwl: 0.713225916338978
init_vdwl: 0.7132259163389776
init_coul: 0
init_stress: ! |2-
2.6556151567263032e+02 2.6660724159085703e+02 2.4812081237895359e+02 6.0264893464561915e+00 -6.6027371615114303e+00 -1.4187579099120772e+01
@ -50,7 +50,7 @@ init_forces: ! |2
30 -8.7442364632334701e-01 -8.5922993943854902e+00 -3.1671240722317777e+00
31 3.1880080741982892e+00 -5.0021160844369490e+00 -2.7083467494366831e-01
32 -1.5986786450380142e+01 -5.5759911113046883e+00 -1.5504124024744577e+00
run_vdwl: 0.669352105052575
run_vdwl: 0.6693521050525746
run_coul: 0
run_stress: ! |2-
2.6541041873586806e+02 2.6644256162479292e+02 2.4793398704069506e+02 5.9903981717659827e+00 -6.6045526000630410e+00 -1.4160943794248436e+01

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
lammps_version: 8 Apr 2021
date_generated: Mon Apr 19 08:49:08 2021
epsilon: 5e-12
prerequisites: ! |
pair eam/fs
@ -13,7 +13,7 @@ pair_coeff: ! |
* * eam/fs AlFe_mm.eam.fs NULL Al
extract: ! ""
natoms: 32
init_vdwl: 15.6583494469006
init_vdwl: 15.658349446900637
init_coul: 0
init_stress: ! |2-
3.1757662346015599e+02 3.1488042003987044e+02 2.9518192213010605e+02 8.0970202601485379e+00 -4.6038792816319125e+00 -1.1521259274290610e+01
@ -50,7 +50,7 @@ init_forces: ! |2
30 -2.0584055270338175e+00 -5.2207163606526530e+00 -4.6304543222177532e+00
31 1.2014109675977875e+00 -6.5554529419137078e+00 2.1453874832093329e+00
32 -1.5986786450380142e+01 -5.5759911113046883e+00 -1.5504124024744577e+00
run_vdwl: 15.6055369596825
run_vdwl: 15.605536959682482
run_coul: 0
run_stress: ! |2-
3.1739734448741643e+02 3.1467775824072135e+02 2.9494960877836593e+02 8.0575431550134713e+00 -4.6069278562709943e+00 -1.1484582135772436e+01

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:03 2021
epsilon: 5e-13
prerequisites: ! |
pair kim

View File

@ -0,0 +1,91 @@
---
lammps_version: 10 Feb 2021
date_generated: Sun Feb 28 23:32:03 2021
epsilon: 5e-13
prerequisites: ! |
pair born
pre_commands: ! ""
post_commands: ! ""
input_file: in.metal
pair_style: lj/relres 4.0 5.0 7.0 8.0
pair_coeff: ! |
1 1 0.00121585 3.905 0 3.905
1 2 0.00121585 3.905 0.00121585 3.905
2 2 0.00121585 3.905 0.00121585 3.905
extract: ! ""
natoms: 32
init_vdwl: 278.180950996338
init_coul: 0
init_stress: ! |2-
1.1877397131221412e+03 1.1638761902735005e+03 1.0939934354329380e+03 6.8492993891187240e+01 -3.1686913926055702e+00 -3.0318931219574608e+01
init_forces: ! |2
1 1.1257725802206693e-01 1.5003115850475984e+01 3.7161715906573249e+00
2 -3.9371074133244033e+00 -1.5797318896888202e+01 9.8265483014448343e+00
3 -9.8213019857385877e+00 4.5398626929289222e+01 -1.1984345677554444e+01
4 3.8619783724436347e+00 -2.2367670285503563e+00 -9.8667499113042698e+00
5 1.7421331278287461e+01 3.5003615980663376e+01 5.4604696757275848e+00
6 9.1359404522604510e+00 4.9829473194427507e+00 -2.4129924428156402e+00
7 -1.5766701507678247e+01 2.0974333341024735e+01 -2.6155159105794188e+00
8 -1.5183115657866077e+01 -1.2451351620442299e+01 1.1636254945740577e+01
9 3.8090425554608491e+00 -1.0907791092741443e+01 -6.1447809963829947e+00
10 -1.0395436945303533e+01 -3.8367074884512746e+01 -2.5800182132854442e+01
11 -7.9545805384553478e+00 -1.0115999734551822e+01 9.0610883954699659e+00
12 9.1249981420231450e+00 -2.0896442188182313e+01 -1.2969177591443883e+00
13 -4.5921575862854080e+00 4.6114711730821698e+00 -1.0000636415917823e+01
14 1.2749517192690996e+01 -3.9970170399846938e+00 1.6639389558970819e+01
15 -6.5965824174094028e+00 6.6153731373766966e+00 -5.6427929840815771e+00
16 2.4351513585083858e+01 -2.0415196023133920e+01 8.4814988111712459e+00
17 1.0299109427501774e+01 2.9546303629211895e+01 -1.9341947600693978e+00
18 -3.7195187867020032e+01 -1.1030315937513105e+01 -1.6710107278365474e+01
19 -3.9497427656163509e+01 -2.2552418505155995e+01 8.0707729455886117e+00
20 4.7864511359094548e+00 3.9752456387755553e+00 -7.5621289377276177e+00
21 3.8528644298025895e+01 1.3519655659162099e+01 8.5256493265734801e-01
22 1.1077729180999789e+00 -1.6208072481067383e+01 -3.0979650557204157e+00
23 1.4113913436346907e+01 3.1494001129414158e+01 -1.8142897754964714e+01
24 3.3881181432547542e+01 2.4370415248363962e+01 2.0078166368292568e+01
25 1.4753375696198107e+01 -1.6860224492541906e-01 -1.0357256153984068e+01
26 -1.4396504175389046e+01 -3.8109515237450715e+01 3.1516681941309770e+01
27 1.1459132062617343e+01 -2.7648747331934835e+00 -6.0134710728971097e-01
28 8.6792370740090519e-01 1.3711362475104321e+01 1.7060845401384995e+01
29 1.4886320532090263e+01 2.6415990570893030e+01 -6.3587763727632818e-01
30 -8.3053344792491117e+00 -6.7854505410487436e+00 -1.9926676569327796e+01
31 -3.9722675775001202e+00 -2.6202171362782902e+01 1.7034787150328516e+01
32 -4.7637017675627781e+01 -1.6616078530154439e+01 -4.7018745333836263e+00
run_vdwl: 277.787230338519
run_coul: 0
run_stress: ! |2-
1.1861045479571328e+03 1.1621545499754693e+03 1.0925950582629255e+03 6.7871794269310669e+01 -3.2811225906376507e+00 -3.0119921761225132e+01
run_forces: ! |2
1 5.0761504793041319e-02 1.4972569031846831e+01 3.7082674582636526e+00
2 -3.9381058430565288e+00 -1.5782802165860760e+01 9.8125660936307053e+00
3 -9.7425327584084691e+00 4.5033863259233172e+01 -1.1963779315033937e+01
4 3.8461752102094633e+00 -2.2100266107527706e+00 -9.8627527183535459e+00
5 1.7286298464840606e+01 3.4803069057765718e+01 5.5124972577097848e+00
6 9.1365148074930023e+00 4.9905844771929031e+00 -2.4069911355223432e+00
7 -1.5710733381690963e+01 2.0948145953415406e+01 -2.6352545999033143e+00
8 -1.5191011151562712e+01 -1.2423405537748620e+01 1.1609656474941872e+01
9 3.8300649394200663e+00 -1.0939289188313623e+01 -6.1652357236607127e+00
10 -1.0179095304450680e+01 -3.8138499760472136e+01 -2.5614937128525611e+01
11 -7.9328424473210770e+00 -1.0126931858947339e+01 9.0323728831931760e+00
12 9.1240445709604625e+00 -2.0801517592482849e+01 -1.2864845436518126e+00
13 -4.6154026287895666e+00 4.5678314059294269e+00 -9.9574005013456635e+00
14 1.2739453844823467e+01 -3.8639640724167696e+00 1.6503517451482374e+01
15 -6.5851001501170838e+00 6.5954448786505750e+00 -5.6251052965943709e+00
16 2.4131969420516253e+01 -2.0319213195026325e+01 8.4318175142187748e+00
17 1.0274453472246744e+01 2.9448733262109759e+01 -1.9321994588155988e+00
18 -3.6997902937678973e+01 -1.0947728341166549e+01 -1.6629476705430637e+01
19 -3.9256632036490366e+01 -2.2382462798833316e+01 8.0133124681507351e+00
20 4.7785967094492916e+00 3.9919292918758300e+00 -7.5598392292642806e+00
21 3.8336179494883886e+01 1.3372767736301565e+01 8.9441495342140864e-01
22 1.1374772919402263e+00 -1.6159423036575365e+01 -3.0958996778988328e+00
23 1.4060431172656273e+01 3.1322405912593315e+01 -1.8048650528231175e+01
24 3.3628163932173699e+01 2.4221707885083035e+01 1.9997423960892526e+01
25 1.4719235839277802e+01 -1.3664529090023003e-01 -1.0322356751316049e+01
26 -1.4249543090594170e+01 -3.7792175725759691e+01 3.1320364026272529e+01
27 1.1432267884704974e+01 -2.7686316107074638e+00 -6.2637494606673982e-01
28 8.4057547201635785e-01 1.3690742783314787e+01 1.7006819241247609e+01
29 1.4764759789215882e+01 2.6280384715684544e+01 -6.1061690968417726e-01
30 -8.2772161889870315e+00 -6.7692020199003098e+00 -1.9822795745009806e+01
31 -4.0013247597925483e+00 -2.6130935247333245e+01 1.6988712159243850e+01
32 -4.7439981142681432e+01 -1.6547325597799496e+01 -4.6655910283603808e+00
...

View File

@ -1,12 +1,12 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:03 2021
epsilon: 5e-13
prerequisites: ! |
pair meam/c
pre_commands: ! |
variable newton_pair delete
variable newton_pair index on
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
post_commands: ! ""
input_file: in.metal
pair_style: meam/c

View File

@ -1,12 +1,12 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:03 2021
epsilon: 1e-14
prerequisites: ! |
pair meam/spline
pre_commands: ! |
variable newton_pair delete
variable newton_pair index on
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
post_commands: ! ""
input_file: in.metal
pair_style: meam/spline

View File

@ -1,13 +1,13 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:03 2021
epsilon: 1e-14
prerequisites: ! |
pair meam/sw/spline
pre_commands: ! |
echo screen
variable newton_pair delete
variable newton_pair index on
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
atom_modify map array
units metal
lattice diamond 5.43

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:03 2021
epsilon: 2.5e-12
prerequisites: ! |
pair momb

View File

@ -1,12 +1,12 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:23 202
epsilon: 1e-12
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:04 2021
epsilon: 1e-14
prerequisites: ! |
pair polymorphic
pre_commands: ! |
variable newton_pair delete
variable newton_pair index on
if "$(is_active(package,gpu)) > 0.0" then "variable newton_pair index off" else "variable newton_pair index on"
post_commands: ! |
change_box all x final 0 18 y final 0 18 z final 0 18
input_file: in.metal

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:24 202
epsilon: 2.5e-11
epsilon: 5e-11
prerequisites: ! |
pair reax/c
fix qeq/reax

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:25 202
epsilon: 1e-10
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:06 2021
epsilon: 2e-10
prerequisites: ! |
pair reax/c
fix qeq/reax

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:26 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:08 2021
epsilon: 5e-13
prerequisites: ! |
pair reax/c

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:27 202
epsilon: 5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:09 2021
epsilon: 2e-12
prerequisites: ! |
pair table
pre_commands: ! ""

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:27 202
epsilon: 5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:10 2021
epsilon: 2e-12
prerequisites: ! |
pair table
pre_commands: ! ""

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:27 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:10 2021
epsilon: 5e-13
prerequisites: ! |
pair table

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:27 202
epsilon: 5e-13
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:10 2021
epsilon: 2e-12
prerequisites: ! |
pair table
pre_commands: ! ""

View File

@ -1,7 +1,7 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:27 202
epsilon: 5e-14
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:10 2021
epsilon: 2e-13
prerequisites: ! |
atom sphere
pair yukawa/colloid

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:21 2021
epsilon: 1e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:21 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:21 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 29 Oct 2020
date_generated: Sat Nov 14 16:49:01 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:21 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:21 2021
epsilon: 5e-13
prerequisites: ! |
atom full
@ -15,7 +15,7 @@ bond_coeff: ! |
3 350.0 1.3
4 650.0 1.2
5 450.0 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! |
kappa 1
r0 1

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:21 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -15,7 +15,7 @@ bond_coeff: ! |
3 350.0 1.3
4 650.0 1.2
5 450.0 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! |
kappa 1
r0 1

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:22 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -15,7 +15,7 @@ bond_coeff: ! |
3 350.0 1.3 0.3
4 650.0 1.2 0.2
5 450.0 1.0 0.0
equilibrium: 5 1.5 1.1 1.3 1.2 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! ""
natoms: 29
init_energy: -9395.51998238922

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:22 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -15,7 +15,7 @@ bond_coeff: ! |
3 350.0 1.3 0.3
4 650.0 1.2 0.2
5 450.0 1.0 0.0
equilibrium: 5 1.5 1.1 1.3 1.2 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! ""
natoms: 29
init_energy: 0

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:22 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -16,7 +16,7 @@ bond_coeff: ! |
3 morse 7000.0 0.2 1.3
4 harmonic 650.0 1.2
5 harmonic 450.0 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! ""
natoms: 29
init_energy: 4.63957309438403

View File

@ -1,6 +1,6 @@
---
lammps_version: 24 Aug 2020
date_generated: Tue Sep 15 09:44:33 202
lammps_version: 10 Feb 2021
date_generated: Fri Feb 26 23:09:22 2021
epsilon: 2.5e-13
prerequisites: ! |
atom full
@ -15,7 +15,7 @@ bond_coeff: ! |
3 350.0 1.3
4 650.0 1.2
5 450.0 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1.0
equilibrium: 5 1.5 1.1 1.3 1.2 1
extract: ! ""
natoms: 29
init_energy: 4.24726500827314

Some files were not shown because too many files have changed in this diff Show More