diff --git a/include/votca/csg/boundarycondition.h b/include/votca/csg/boundarycondition.h index a2712e7f93..d2c78a439b 100644 --- a/include/votca/csg/boundarycondition.h +++ b/include/votca/csg/boundarycondition.h @@ -14,37 +14,59 @@ * limitations under the License. * */ +#pragma once +#ifndef VOTCA_CSG_BOUNDARYCONDITION_H +#define VOTCA_CSG_BOUNDARYCONDITION_H -#ifndef _VOTCA_CSG_BOUNDARYCONDITION_H -#define _VOTCA_CSG_BOUNDARYCONDITION_H - +#include #include namespace votca { namespace csg { +/** + * @brief Class keeps track of how the boundaries of the system are handled + * + * There are a total of 3 different boundaries: + * open - no boundaries + * orthorhombic - orthorombic boundaries + * triclinic - triclinic boundaries + * + * This class enables the correct treatement of distances beteween topology + * objects, such that distances accound for the periodic boundaries. + */ class BoundaryCondition { public: virtual ~BoundaryCondition() = default; + /** + * @brief Safe way to allow child classes to be copied + * + * The child classes must use the same method and override it with their type + * for this to work. + * + * @return standard pointer to child class + */ + virtual std::unique_ptr Clone() const = 0; + /** * set the simulation box * \param box triclinic box matrix */ - void setBox(const Eigen::Matrix3d &box) { _box = box; }; + void setBox(const Eigen::Matrix3d &box) noexcept { _box = box; }; /** * get the simulation box * \return triclinic box matrix */ - const Eigen::Matrix3d &getBox() { return _box; }; + const Eigen::Matrix3d &getBox() const noexcept { return _box; }; /** * get the volume of the box * \return box volume as double */ - virtual double BoxVolume(); + virtual double BoxVolume() const noexcept; /** * get shortest connection vector between r_i and r_j with respect to the @@ -54,7 +76,7 @@ class BoundaryCondition { const Eigen::Vector3d &r_i, const Eigen::Vector3d &r_j) const = 0; enum eBoxtype { typeAuto = 0, typeTriclinic, typeOrthorhombic, typeOpen }; - virtual eBoxtype getBoxType() = 0; + virtual eBoxtype getBoxType() const noexcept = 0; protected: Eigen::Matrix3d _box; @@ -63,4 +85,4 @@ class BoundaryCondition { } // namespace csg } // namespace votca -#endif /* _VOTCA_CSG_BOUNDARYCONDITION_H */ +#endif // VOTCA_CSG_BOUNDARYCONDITION_H diff --git a/include/votca/csg/openbox.h b/include/votca/csg/openbox.h index 4f5cd081cb..76669e6a49 100644 --- a/include/votca/csg/openbox.h +++ b/include/votca/csg/openbox.h @@ -14,9 +14,9 @@ * limitations under the License. * */ - -#ifndef _VOTCA_CSG_OPENBOX_H -#define _VOTCA_CSG_OPENBOX_H +#pragma once +#ifndef VOTCA_CSG_OPENBOX_H +#define VOTCA_CSG_OPENBOX_H #include "boundarycondition.h" @@ -29,10 +29,14 @@ class OpenBox : public BoundaryCondition { Eigen::Vector3d BCShortestConnection(const Eigen::Vector3d &r_i, const Eigen::Vector3d &r_j) const final; - eBoxtype getBoxType() final { return typeOpen; } + virtual std::unique_ptr Clone() const final { + return std::unique_ptr(new OpenBox(*this)); + } + + eBoxtype getBoxType() const noexcept final { return typeOpen; } }; } // namespace csg } // namespace votca -#endif /* _VOTCA_CSG_OPENBOX_H */ +#endif // VOTCA_CSG_OPENBOX_H diff --git a/include/votca/csg/orthorhombicbox.h b/include/votca/csg/orthorhombicbox.h index 725dd0c1df..4ad2469789 100644 --- a/include/votca/csg/orthorhombicbox.h +++ b/include/votca/csg/orthorhombicbox.h @@ -14,9 +14,9 @@ * limitations under the License. * */ - -#ifndef _VOTCA_CSG_ORTHORHOMBICBOX_H -#define _VOTCA_CSG_ORTHORHOMBICBOX_H +#pragma once +#ifndef VOTCA_CSG_ORTHORHOMBICBOX_H +#define VOTCA_CSG_ORTHORHOMBICBOX_H #include "boundarycondition.h" @@ -29,7 +29,11 @@ class OrthorhombicBox : public BoundaryCondition { Eigen::Vector3d BCShortestConnection(const Eigen::Vector3d &r_i, const Eigen::Vector3d &r_j) const final; - eBoxtype getBoxType() final { return typeOrthorhombic; } + virtual std::unique_ptr Clone() const final { + return std::unique_ptr(new OrthorhombicBox(*this)); + } + + eBoxtype getBoxType() const noexcept final { return typeOrthorhombic; } protected: }; @@ -37,4 +41,4 @@ class OrthorhombicBox : public BoundaryCondition { } // namespace csg } // namespace votca -#endif /* _VOTCA_CSG_ORTHORHOMBICBOX_H */ +#endif // VOTCA_CSG_ORTHORHOMBICBOX_H diff --git a/include/votca/csg/triclinicbox.h b/include/votca/csg/triclinicbox.h index cd4828d423..ef0b4a8471 100644 --- a/include/votca/csg/triclinicbox.h +++ b/include/votca/csg/triclinicbox.h @@ -14,9 +14,9 @@ * limitations under the License. * */ - -#ifndef _VOTCA_CSG_TRICLINICBOX_H -#define _VOTCA_CSG_TRICLINICBOX_H +#pragma once +#ifndef VOTCA_CSG_TRICLINICBOX_H +#define VOTCA_CSG_TRICLINICBOX_H #include "boundarycondition.h" @@ -29,7 +29,11 @@ class TriclinicBox : public BoundaryCondition { Eigen::Vector3d BCShortestConnection(const Eigen::Vector3d &r_i, const Eigen::Vector3d &r_j) const final; - eBoxtype getBoxType() final { return typeTriclinic; } + virtual std::unique_ptr Clone() const final { + return std::unique_ptr(new TriclinicBox(*this)); + } + + eBoxtype getBoxType() const noexcept final { return typeTriclinic; } protected: }; @@ -37,4 +41,4 @@ class TriclinicBox : public BoundaryCondition { } // namespace csg } // namespace votca -#endif /* _VOTCA_CSG_TRICLINICBOX_H */ +#endif // VOTCA_CSG_TRICLINICBOX_H diff --git a/src/libcsg/boundarycondition.cc b/src/libcsg/boundarycondition.cc index 3c37e4d8d1..f580f772a2 100644 --- a/src/libcsg/boundarycondition.cc +++ b/src/libcsg/boundarycondition.cc @@ -21,7 +21,9 @@ namespace votca { namespace csg { -double BoundaryCondition::BoxVolume() { return std::abs(_box.determinant()); } +double BoundaryCondition::BoxVolume() const noexcept { + return std::abs(_box.determinant()); +} } // namespace csg } // namespace votca diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index fd8348da9f..0ab6041fe7 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -16,6 +16,7 @@ foreach(PROG test_lammpsdumpreaderwriter test_nblist_3body test_nblistgrid_3body + test_boundarycondition test_pdbreader test_tabulatedpotential test_triplelist ) diff --git a/src/tests/test_boundarycondition.cc b/src/tests/test_boundarycondition.cc new file mode 100644 index 0000000000..34b790b35e --- /dev/null +++ b/src/tests/test_boundarycondition.cc @@ -0,0 +1,125 @@ +/* + * Copyright 2009-2019 The VOTCA Development Team (http://www.votca.org) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#define BOOST_TEST_MAIN + +#define BOOST_TEST_MODULE pdbreader_test +#include "../../include/votca/csg/openbox.h" +#include "../../include/votca/csg/orthorhombicbox.h" +#include "../../include/votca/csg/triclinicbox.h" +#include +#include + +#include +#include + +using namespace std; +using namespace votca::csg; + +BOOST_AUTO_TEST_SUITE(boundarycondition_test) + +BOOST_AUTO_TEST_CASE(test_boundarycondition_initiatialization) { + vector> boundaries; + + boundaries.push_back(unique_ptr(new OpenBox)); + boundaries.push_back(unique_ptr(new TriclinicBox)); + boundaries.push_back(unique_ptr(new OrthorhombicBox)); + + BOOST_CHECK_EQUAL(boundaries.at(0)->getBoxType(), + BoundaryCondition::eBoxtype::typeOpen); + BOOST_CHECK_EQUAL(boundaries.at(1)->getBoxType(), + BoundaryCondition::eBoxtype::typeTriclinic); + BOOST_CHECK_EQUAL(boundaries.at(2)->getBoxType(), + BoundaryCondition::eBoxtype::typeOrthorhombic); +} + +BOOST_AUTO_TEST_CASE(test_boundarycondition_boxvolume) { + vector> boundaries; + + boundaries.push_back(unique_ptr(new OpenBox)); + boundaries.push_back(unique_ptr(new TriclinicBox)); + boundaries.push_back(unique_ptr(new OrthorhombicBox)); + + Eigen::Matrix3d box; + box << 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0; + + boundaries.at(0)->setBox(box); + boundaries.at(1)->setBox(box); + boundaries.at(2)->setBox(box); + + BOOST_CHECK_EQUAL(boundaries.at(0)->BoxVolume(), 0.0); + BOOST_CHECK_EQUAL(boundaries.at(1)->BoxVolume(), 0.0); + BOOST_CHECK_EQUAL(boundaries.at(2)->BoxVolume(), 0.0); + + box(0, 0) = 1.0; + box(1, 1) = 2.0; + box(2, 2) = 1.0; + + boundaries.at(0)->setBox(box); + boundaries.at(1)->setBox(box); + boundaries.at(2)->setBox(box); + + BOOST_CHECK_EQUAL(boundaries.at(0)->BoxVolume(), 2.0); + BOOST_CHECK_EQUAL(boundaries.at(1)->BoxVolume(), 2.0); + BOOST_CHECK_EQUAL(boundaries.at(2)->BoxVolume(), 2.0); +} + +BOOST_AUTO_TEST_CASE(test_boundarycondition_clone) { + vector> boundaries; + + boundaries.push_back(unique_ptr(new OpenBox)); + boundaries.push_back(unique_ptr(new TriclinicBox)); + boundaries.push_back(unique_ptr(new OrthorhombicBox)); + + Eigen::Matrix3d box; + box << 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0; + + boundaries.at(0)->setBox(box); + boundaries.at(1)->setBox(box); + boundaries.at(2)->setBox(box); + + vector> boundaries_copy; + + boundaries_copy.push_back(boundaries.at(0)->Clone()); + boundaries_copy.push_back(boundaries.at(1)->Clone()); + boundaries_copy.push_back(boundaries.at(2)->Clone()); + + BOOST_CHECK_EQUAL(boundaries_copy.at(0)->getBoxType(), + BoundaryCondition::eBoxtype::typeOpen); + BOOST_CHECK_EQUAL(boundaries_copy.at(1)->getBoxType(), + BoundaryCondition::eBoxtype::typeTriclinic); + BOOST_CHECK_EQUAL(boundaries_copy.at(2)->getBoxType(), + BoundaryCondition::eBoxtype::typeOrthorhombic); + + box(0, 0) = 1.0; + box(1, 1) = 2.0; + box(2, 2) = 1.0; + + boundaries_copy.at(0)->setBox(box); + boundaries_copy.at(1)->setBox(box); + boundaries_copy.at(2)->setBox(box); + + BOOST_CHECK_EQUAL(boundaries_copy.at(0)->BoxVolume(), 2.0); + BOOST_CHECK_EQUAL(boundaries_copy.at(1)->BoxVolume(), 2.0); + BOOST_CHECK_EQUAL(boundaries_copy.at(2)->BoxVolume(), 2.0); + + /* Ensure that the original boundaries were not altered */ + BOOST_CHECK_EQUAL(boundaries.at(0)->BoxVolume(), 0.0); + BOOST_CHECK_EQUAL(boundaries.at(1)->BoxVolume(), 0.0); + BOOST_CHECK_EQUAL(boundaries.at(2)->BoxVolume(), 0.0); +} +BOOST_AUTO_TEST_SUITE_END()