From ae4404201f779adbdf55292a29c71a4b6306b84f Mon Sep 17 00:00:00 2001 From: Karl Hammond Date: Thu, 22 Sep 2022 19:55:10 -0500 Subject: [PATCH] Forgot to add the unit test files to the commit.... --- .../fortran/test_fortran_extract_atom.f90 | 130 ++++++++++++++++++ unittest/fortran/wrap_extract_atom.cpp | 99 +++++++++++++ 2 files changed, 229 insertions(+) create mode 100644 unittest/fortran/test_fortran_extract_atom.f90 create mode 100644 unittest/fortran/wrap_extract_atom.cpp diff --git a/unittest/fortran/test_fortran_extract_atom.f90 b/unittest/fortran/test_fortran_extract_atom.f90 new file mode 100644 index 0000000000..d3a49c56ec --- /dev/null +++ b/unittest/fortran/test_fortran_extract_atom.f90 @@ -0,0 +1,130 @@ +MODULE keepatom + USE liblammps + TYPE(LAMMPS) :: lmp + CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: demo_input = & + [ CHARACTER(len=40) :: & + 'region box block 0 $x 0 3 0 4', & + 'create_box 1 box', & + 'create_atoms 1 single 1.0 1.0 ${zpos}' ] + CHARACTER(LEN=40), DIMENSION(2), PARAMETER :: cont_input = & + [ CHARACTER(len=40) :: & + 'create_atoms 1 single &', & + ' 0.2 0.1 0.1' ] + CHARACTER(LEN=40), DIMENSION(3), PARAMETER :: pair_input = & + [ CHARACTER(LEN=40) :: & + 'pair_style lj/cut 2.5', & + 'pair_coeff 1 1 1.0 1.0', & + 'mass 1 2.0' ] +END MODULE keepatom + +FUNCTION f_lammps_with_args() BIND(C, name="f_lammps_with_args") + USE ISO_C_BINDING, ONLY: c_ptr + USE liblammps + USE keepatom, ONLY: lmp + IMPLICIT NONE + TYPE(c_ptr) :: f_lammps_with_args + CHARACTER(len=12), DIMENSION(12), PARAMETER :: args = & + [ CHARACTER(len=12) :: 'liblammps', '-log', 'none', & + '-echo','screen','-nocite','-var','zpos','1.5','-var','x','2'] + + lmp = lammps(args) + f_lammps_with_args = lmp%handle +END FUNCTION f_lammps_with_args + +SUBROUTINE f_lammps_close() BIND(C, name="f_lammps_close") + USE ISO_C_BINDING, ONLY: c_null_ptr + USE liblammps + USE keepatom, ONLY: lmp + IMPLICIT NONE + + CALL lmp%close() + lmp%handle = c_null_ptr +END SUBROUTINE f_lammps_close + +SUBROUTINE f_lammps_setup_extract_atom () BIND(C) + USE LIBLAMMPS + USE keepatom, ONLY : lmp, demo_input, cont_input, pair_input + IMPLICIT NONE + + CALL lmp%commands_list(demo_input) + CALL lmp%commands_list(cont_input) + CALL lmp%commands_list(pair_input) +! CALL lmp%command('run 0') +END SUBROUTINE f_lammps_setup_extract_atom + +FUNCTION f_lammps_extract_atom_mass () BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double + USE LIBLAMMPS + USE keepatom, ONLY : lmp + IMPLICIT NONE + REAL(C_double) :: f_lammps_extract_atom_mass + REAL(C_double), DIMENSION(:), POINTER :: mass + + mass = lmp%extract_atom('mass') + f_lammps_extract_atom_mass = mass(1) +END FUNCTION f_lammps_extract_atom_mass + +FUNCTION f_lammps_extract_atom_tag_int (i) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int + USE LIBLAMMPS + USE keepatom, ONLY : lmp + IMPLICIT NONE + INTEGER(C_int), INTENT(IN), VALUE :: i + INTEGER(C_int) :: f_lammps_extract_atom_tag_int + INTEGER(C_int), DIMENSION(:), POINTER :: tag + + tag = lmp%extract_atom('id') + f_lammps_extract_atom_tag_int = tag(i) +END FUNCTION f_lammps_extract_atom_tag_int + +FUNCTION f_lammps_extract_atom_tag_int64 (i) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int64_t + USE LIBLAMMPS + USE keepatom, ONLY : lmp + IMPLICIT NONE + INTEGER(C_int64_t), INTENT(IN), VALUE :: i + INTEGER(C_int64_t) :: f_lammps_extract_atom_tag_int64 + INTEGER(C_int64_t), DIMENSION(:), POINTER :: tag + + tag = lmp%extract_atom('id') + f_lammps_extract_atom_tag_int64 = tag(i) +END FUNCTION f_lammps_extract_atom_tag_int64 + +FUNCTION f_lammps_extract_atom_type(i) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int + USE LIBLAMMPS + USE keepatom, ONLY : lmp + IMPLICIT NONE + INTEGER(C_int), INTENT(IN), VALUE :: i + INTEGER(C_int) :: f_lammps_extract_atom_type + INTEGER(C_int), DIMENSION(:), POINTER :: atype + + atype = lmp%extract_atom('type') + f_lammps_extract_atom_type = atype(i) +END FUNCTION f_lammps_extract_atom_type + +FUNCTION f_lammps_extract_atom_mask(i) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_int + USE LIBLAMMPS + USE keepatom, ONLY : lmp + IMPLICIT NONE + INTEGER(C_int), INTENT(IN), VALUE :: i + INTEGER(C_int) :: f_lammps_extract_atom_mask + INTEGER(C_int), DIMENSION(:), POINTER :: mask + + mask = lmp%extract_atom('mask') + f_lammps_extract_atom_mask = mask(i) +END FUNCTION f_lammps_extract_atom_mask + +SUBROUTINE f_lammps_extract_atom_x (i, x) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_double, C_int + USE LIBLAMMPS + USE keepatom, ONLY : lmp + IMPLICIT NONE + INTEGER(C_int), INTENT(IN), VALUE :: i + REAL(C_double), DIMENSION(3) :: x + REAL(C_double), DIMENSION(:,:), POINTER :: xptr + + xptr = lmp%extract_atom('x') + x = xptr(:,i) +END SUBROUTINE f_lammps_extract_atom_x diff --git a/unittest/fortran/wrap_extract_atom.cpp b/unittest/fortran/wrap_extract_atom.cpp new file mode 100644 index 0000000000..7cc5ff396f --- /dev/null +++ b/unittest/fortran/wrap_extract_atom.cpp @@ -0,0 +1,99 @@ +// unit tests for extracting Atom class data from a LAMMPS instance through the +// Fortran wrapper + +#include "lammps.h" +#include "library.h" +#include "lmptype.h" +#include +#include +#include +#include + +#include "gtest/gtest.h" + +// prototypes for Fortran reverse wrapper functions +extern "C" { +void *f_lammps_with_args(); +void f_lammps_close(); +void f_lammps_setup_extract_atom(); +double f_lammps_extract_atom_mass(); +int f_lammps_extract_atom_tag_int(int); +int64_t f_lammps_extract_atom_tag_int64(int64_t); +int f_lammps_extract_atom_type(int); +int f_lammps_extract_atom_mask(int); +void f_lammps_extract_atom_x(int,double*); +} + +class LAMMPS_extract_atom : public ::testing::Test { +protected: + LAMMPS_NS::LAMMPS *lmp; + LAMMPS_extract_atom() = default; + ~LAMMPS_extract_atom() override = default; + + void SetUp() override + { + ::testing::internal::CaptureStdout(); + lmp = (LAMMPS_NS::LAMMPS *)f_lammps_with_args(); + std::string output = ::testing::internal::GetCapturedStdout(); + EXPECT_STREQ(output.substr(0, 8).c_str(), "LAMMPS ("); + } + void TearDown() override + { + ::testing::internal::CaptureStdout(); + f_lammps_close(); + std::string output = ::testing::internal::GetCapturedStdout(); + EXPECT_STREQ(output.substr(0, 16).c_str(), "Total wall time:"); + lmp = nullptr; + } +}; + +TEST_F(LAMMPS_extract_atom, mass) +{ + f_lammps_setup_extract_atom(); + EXPECT_DOUBLE_EQ(f_lammps_extract_atom_mass(), 2.0); +}; + +TEST_F(LAMMPS_extract_atom, tag) +{ + f_lammps_setup_extract_atom(); +#ifdef LAMMPS_BIGBIG + EXPECT_EQ(f_lammps_extract_atom_tag_int64(1l), 1l); + EXPECT_EQ(f_lammps_extract_atom_tag_int64(2l), 2l); +#else + EXPECT_EQ(f_lammps_extract_atom_tag_int(1), 1); + EXPECT_EQ(f_lammps_extract_atom_tag_int(2), 2); +#endif +}; + +TEST_F(LAMMPS_extract_atom, type) +{ + f_lammps_setup_extract_atom(); + EXPECT_EQ(f_lammps_extract_atom_type(1), 1); + EXPECT_EQ(f_lammps_extract_atom_type(2), 1); +}; + +TEST_F(LAMMPS_extract_atom, mask) +{ + f_lammps_setup_extract_atom(); + EXPECT_EQ(f_lammps_extract_atom_mask(1), 1); + EXPECT_EQ(f_lammps_extract_atom_mask(2), 1); + lammps_command(lmp, "group 1 id 1"); + lammps_command(lmp, "group 2 id 2"); + EXPECT_EQ(f_lammps_extract_atom_mask(1), 3); + EXPECT_EQ(f_lammps_extract_atom_mask(2), 5); +}; + +TEST_F(LAMMPS_extract_atom, x) +{ + f_lammps_setup_extract_atom(); + double x1[3]; + double x2[3]; + f_lammps_extract_atom_x(1, x1); + EXPECT_DOUBLE_EQ(x1[0], 1.0); + EXPECT_DOUBLE_EQ(x1[1], 1.0); + EXPECT_DOUBLE_EQ(x1[2], 1.5); + f_lammps_extract_atom_x(2, x2); + EXPECT_DOUBLE_EQ(x2[0], 0.2); + EXPECT_DOUBLE_EQ(x2[1], 0.1); + EXPECT_DOUBLE_EQ(x2[2], 0.1); +}