diff --git a/unittest/commands/CMakeLists.txt b/unittest/commands/CMakeLists.txt index 6d5ea802d4..f6ef263f5f 100644 --- a/unittest/commands/CMakeLists.txt +++ b/unittest/commands/CMakeLists.txt @@ -21,6 +21,10 @@ add_executable(test_groups test_groups.cpp) target_link_libraries(test_groups PRIVATE lammps GTest::GMock) add_test(NAME Groups COMMAND test_groups) +add_executable(test_regions test_regions.cpp) +target_link_libraries(test_regions PRIVATE lammps GTest::GMock) +add_test(NAME Regions COMMAND test_regions) + add_executable(test_variables test_variables.cpp) target_link_libraries(test_variables PRIVATE lammps GTest::GMock) add_test(NAME Variables COMMAND test_variables) diff --git a/unittest/commands/test_regions.cpp b/unittest/commands/test_regions.cpp new file mode 100644 index 0000000000..57d36e608e --- /dev/null +++ b/unittest/commands/test_regions.cpp @@ -0,0 +1,231 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, 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 "../testing/core.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include +#include + +// 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::StrEq; + +class RegionTest : public LAMMPSTest { +protected: + Atom *atom; + Domain *domain; + Group *group; + + void SetUp() override + { + testbinary = "RegionTest"; + LAMMPSTest::SetUp(); + atom = lmp->atom; + domain = lmp->domain; + group = lmp->group; + } + + 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 -10 10 -10 10 -10 10"); + command("create_box 8 box"); + command("create_atoms 1 box"); + command("mass * 1.0"); + END_HIDE_OUTPUT(); + } +}; + +TEST_F(RegionTest, NoBox) +{ + auto list = domain->get_region_list(); + ASSERT_EQ(list.size(), 0); + BEGIN_HIDE_OUTPUT(); + command("region reg1 block 0 1 0 1 0 1"); + command("region reg2 cone x 0 0 2 1 0 1 units box"); + command("region reg3 plane 0 0 0 0 0 1 side out"); + command("region reg4 prism 0 1 0 1 0 1 0.1 0.2 0.3"); + command("region reg5 sphere 0 0 0 1"); + command("region reg6 union 3 reg1 reg2 reg3"); + command("region reg7 intersect 3 reg1 reg2 reg4"); + END_HIDE_OUTPUT(); + list = domain->get_region_list(); + EXPECT_EQ(list.size(), 7); + + auto reg = domain->get_region_by_id("reg1"); + EXPECT_EQ(reg->interior, 1); + EXPECT_EQ(reg->scaleflag, 1); + EXPECT_EQ(reg->bboxflag, 1); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + reg = domain->get_region_by_id("reg2"); + EXPECT_EQ(reg->interior, 1); + EXPECT_EQ(reg->scaleflag, 0); + EXPECT_EQ(reg->bboxflag, 1); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + reg = domain->get_region_by_id("reg3"); + EXPECT_EQ(reg->interior, 0); + EXPECT_EQ(reg->scaleflag, 1); + EXPECT_EQ(reg->bboxflag, 0); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + reg = domain->get_region_by_id("reg4"); + EXPECT_EQ(reg->interior, 1); + EXPECT_EQ(reg->scaleflag, 1); + EXPECT_EQ(reg->bboxflag, 1); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + reg = domain->get_region_by_id("reg5"); + EXPECT_EQ(reg->interior, 1); + EXPECT_EQ(reg->scaleflag, 1); + EXPECT_EQ(reg->bboxflag, 1); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + reg = domain->get_region_by_id("reg6"); + EXPECT_EQ(reg->interior, 1); + EXPECT_EQ(reg->scaleflag, 1); + EXPECT_EQ(reg->bboxflag, 0); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + reg = domain->get_region_by_id("reg7"); + EXPECT_EQ(reg->interior, 1); + EXPECT_EQ(reg->scaleflag, 1); + EXPECT_EQ(reg->bboxflag, 1); + EXPECT_EQ(reg->varshape, 0); + EXPECT_EQ(reg->dynamic, 0); + EXPECT_EQ(reg->moveflag, 0); + EXPECT_EQ(reg->rotateflag, 0); + EXPECT_EQ(reg->openflag, 0); + + TEST_FAILURE(".*ERROR: Unrecognized region style 'xxx'.*", command("region new1 xxx");); + TEST_FAILURE(".*ERROR: Illegal region command.*", command("region new1 block 0 1");); +} + +TEST_F(RegionTest, Counts) +{ + atomic_system(); + + BEGIN_HIDE_OUTPUT(); + command("region reg1 block 0 5 0 5 -5 5"); + command("region reg2 cone y 0 0 10 0 -5 5 units box"); + command("region reg3 plane 0 0 0 0 1 0 side out"); + command("region reg4 prism -5 5 -5 5 -5 5 0.1 0.2 0.3 units box"); + command("region reg5 sphere 0 0 0 6"); + command("region reg6 union 3 reg1 reg2 reg3"); + command("region reg7 intersect 3 reg1 reg2 reg4"); + END_HIDE_OUTPUT(); + + auto x = atom->x; + auto reg1 = domain->get_region_by_id("reg1"); + auto reg2 = domain->get_region_by_id("reg2"); + auto reg3 = domain->get_region_by_id("reg3"); + auto reg4 = domain->get_region_by_id("reg4"); + auto reg5 = domain->get_region_by_id("reg5"); + auto reg6 = domain->get_region_by_id("reg6"); + auto reg7 = domain->get_region_by_id("reg7"); + int count1, count2, count3, count4, count5, count6, count7; + count1 = count2 = count3 = count4 = count5 = count6 = count7 = 0; + reg1->prematch(); + reg2->prematch(); + reg3->prematch(); + reg4->prematch(); + reg5->prematch(); + reg6->prematch(); + reg7->prematch(); + + for (int i = 0; i < atom->nlocal; ++i) { + if (reg1->match(x[i][0], x[i][1], x[i][2])) ++count1; + if (reg2->match(x[i][0], x[i][1], x[i][2])) ++count2; + if (reg3->match(x[i][0], x[i][1], x[i][2])) ++count3; + if (reg4->match(x[i][0], x[i][1], x[i][2])) ++count4; + if (reg5->match(x[i][0], x[i][1], x[i][2])) ++count5; + if (reg6->match(x[i][0], x[i][1], x[i][2])) ++count6; + if (reg7->match(x[i][0], x[i][1], x[i][2])) ++count7; + } + EXPECT_EQ(count1, 250); + EXPECT_EQ(count2, 1132); + EXPECT_EQ(count3, 4000); + EXPECT_EQ(count4, 1000); + EXPECT_EQ(count5, 907); + EXPECT_EQ(count6, 4314); + EXPECT_EQ(count7, 86); +} +} // namespace LAMMPS_NS + +int main(int argc, char **argv) +{ + MPI_Init(&argc, &argv); + ::testing::InitGoogleMock(&argc, argv); + + if (platform::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 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; +}