diff --git a/src/mesh/mesh_iterators.hh b/src/mesh/mesh_iterators.hh index 420606b50..55027bd64 100644 --- a/src/mesh/mesh_iterators.hh +++ b/src/mesh/mesh_iterators.hh @@ -1,302 +1,302 @@ /** * @file mesh_iterators.hh * * @author Nicolas Richart * * @date creation Wed Aug 09 2017 * * @brief Set of helper classes to have fun with range based for * * @section LICENSE * * Copyright (©) 2010-2011 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_named_argument.hh" #include "aka_static_if.hh" #include "mesh.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_MESH_ITERATORS_HH__ #define __AKANTU_MESH_ITERATORS_HH__ namespace akantu { class MeshElementsByTypes { using elements_iterator = Array::scalar_iterator; public: explicit MeshElementsByTypes(const Array & elements) { this->elements.copy(elements); std::sort(this->elements.begin(), this->elements.end()); } /* ------------------------------------------------------------------------ */ class MeshElementsRange { public: MeshElementsRange() = default; MeshElementsRange(const elements_iterator & begin, const elements_iterator & end) : type((*begin).type), ghost_type((*begin).ghost_type), begin(begin), end(end) {} AKANTU_GET_MACRO(Type, type, const ElementType &); AKANTU_GET_MACRO(GhostType, ghost_type, const GhostType &); const Array & getElements() { elements.resize(end - begin); auto el_it = elements.begin(); for (auto it = begin; it != end; ++it, ++el_it) { *el_it = it->element; } return elements; } private: ElementType type{_not_defined}; GhostType ghost_type{_casper}; elements_iterator begin; elements_iterator end; Array elements; }; /* ------------------------------------------------------------------------ */ class iterator { struct element_comparator { bool operator()(const Element & lhs, const Element & rhs) const { return ((rhs == ElementNull) || std::tie(lhs.ghost_type, lhs.type) < std::tie(rhs.ghost_type, rhs.type)); } }; public: iterator(const iterator &) = default; iterator(const elements_iterator & first, const elements_iterator & last) : range(std::equal_range(first, last, *first, element_comparator())), first(first), last(last) {} decltype(auto) operator*() const { return MeshElementsRange(range.first, range.second); } iterator operator++() { first = range.second; range = std::equal_range(first, last, *first, element_comparator()); return *this; } bool operator==(const iterator & other) const { return (first == other.first and last == other.last); } bool operator!=(const iterator & other) const { return (not operator==(other)); } private: std::pair range; elements_iterator first; elements_iterator last; }; iterator begin() { return iterator(elements.begin(), elements.end()); } iterator end() { return iterator(elements.end(), elements.end()); } private: Array elements; }; /* -------------------------------------------------------------------------- */ namespace mesh_iterators { namespace details { template class delegated_iterator { public: using value_type = std::remove_pointer_t< typename internal_iterator::value_type::second_type>; using difference_type = std::ptrdiff_t; using pointer = value_type *; using reference = value_type &; using iterator_category = std::input_iterator_tag; explicit delegated_iterator(internal_iterator it) : it(std::move(it)) {} decltype(auto) operator*() { return std::forwardsecond))>(*(it->second)); } delegated_iterator operator++() { ++it; return *this; } bool operator==(const delegated_iterator & other) const { return other.it == it; } bool operator!=(const delegated_iterator & other) const { return other.it != it; } private: internal_iterator it; }; template class ElementGroupsIterable { public: explicit ElementGroupsIterable(GroupManager && group_manager) : group_manager(std::forward(group_manager)) {} size_t size() { return group_manager.getNbElementGroups(); } decltype(auto) begin() { return delegated_iterator( group_manager.element_group_begin()); } decltype(auto) begin() const { return delegated_iterator( group_manager.element_group_begin()); } decltype(auto) end() { return delegated_iterator( group_manager.element_group_end()); } decltype(auto) end() const { return delegated_iterator( group_manager.element_group_end()); } private: GroupManager && group_manager; }; template class NodeGroupsIterable { public: explicit NodeGroupsIterable(GroupManager && group_manager) : group_manager(std::forward(group_manager)) {} size_t size() { return group_manager.getNbNodeGroups(); } decltype(auto) begin() { return delegated_iterator( group_manager.node_group_begin()); } decltype(auto) begin() const { return delegated_iterator( group_manager.node_group_begin()); } decltype(auto) end() { return delegated_iterator( group_manager.node_group_end()); } decltype(auto) end() const { return delegated_iterator( group_manager.node_group_end()); } private: GroupManager && group_manager; }; } // namespace details } // namespace mesh_iterators template decltype(auto) ElementGroupsIterable(GroupManager && group_manager) { return mesh_iterators::details::ElementGroupsIterable( group_manager); } template decltype(auto) NodeGroupsIterable(GroupManager && group_manager) { return mesh_iterators::details::NodeGroupsIterable( group_manager); } /* -------------------------------------------------------------------------- */ template void for_each_elements(UInt nb_elements, const Array & filter_elements, Func && function) { if (filter_elements != empty_filter) { std::for_each(filter_elements.begin(), filter_elements.end(), std::forward(function)); } else { auto && range = arange(nb_elements); std::for_each(range.begin(), range.end(), std::forward(function)); } } namespace { DECLARE_NAMED_ARGUMENT(element_filter); } /* -------------------------------------------------------------------------- */ template void for_each_elements(const Mesh & mesh, Func && function, pack &&... _pack) { - auto && requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper); + auto requested_ghost_type = OPTIONAL_NAMED_ARG(ghost_type, _casper); const ElementTypeMapArray * filter = OPTIONAL_NAMED_ARG(element_filter, nullptr); bool all_ghost_types = requested_ghost_type == _casper; - auto && spatial_dimension = + auto spatial_dimension = OPTIONAL_NAMED_ARG(spatial_dimension, mesh.getSpatialDimension()); - auto && element_kind = OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined); + auto element_kind = OPTIONAL_NAMED_ARG(element_kind, _ek_not_defined); for (auto ghost_type : ghost_types) { if ((not(ghost_type == requested_ghost_type)) and (not all_ghost_types)) continue; auto element_types = mesh.elementTypes(spatial_dimension, ghost_type, element_kind); if (filter) { element_types = filter->elementTypes(spatial_dimension, ghost_type, element_kind); } for (auto type : element_types) { const Array * filter_array; if (filter) { filter_array = &((*filter)(type, ghost_type)); } else { filter_array = &empty_filter; } auto nb_elements = mesh.getNbElement(type, ghost_type); for_each_elements(nb_elements, *filter_array, [&](auto && el) { auto element = Element{type, el, ghost_type}; std::forward(function)(element); }); } } } } // namespace akantu #endif /* __AKANTU_MESH_ITERATORS_HH__ */ diff --git a/test/test_common/test_array.cc b/test/test_common/test_array.cc index 8affcbce8..0990e521f 100644 --- a/test/test_common/test_array.cc +++ b/test/test_common/test_array.cc @@ -1,241 +1,241 @@ /* -------------------------------------------------------------------------- */ #include "aka_array.hh" #include "aka_types.hh" /* -------------------------------------------------------------------------- */ #include #include #include #include /* -------------------------------------------------------------------------- */ using namespace akantu; namespace { class NonTrivial { public: NonTrivial() = default; NonTrivial(int a) : a(a){}; bool operator==(const NonTrivial & rhs) { return a == rhs.a; } int a{0}; }; bool operator==(const int & a, const NonTrivial & rhs) { return a == rhs.a; } std::ostream & operator<<(std::ostream & stream, const NonTrivial & _this) { stream << _this.a; return stream; } /* -------------------------------------------------------------------------- */ using TestTypes = ::testing::Types; /* -------------------------------------------------------------------------- */ ::testing::AssertionResult AssertType(const char * /*a_expr*/, const char * /*b_expr*/, const std::type_info & a, const std::type_info & b) { if (std::type_index(a) == std::type_index(b)) return ::testing::AssertionSuccess(); return ::testing::AssertionFailure() << debug::demangle(a.name()) << " != " << debug::demangle(b.name()) << ") are different"; } /* -------------------------------------------------------------------------- */ template class ArrayConstructor : public ::testing::Test { protected: using type = T; void SetUp() override { type_str = debug::demangle(typeid(T).name()); } template decltype(auto) construct(P &&... params) { return std::make_unique>(std::forward

(params)...); } protected: std::string type_str; }; TYPED_TEST_CASE(ArrayConstructor, TestTypes); TYPED_TEST(ArrayConstructor, ConstructDefault1) { auto array = this->construct(); EXPECT_EQ(0, array->size()); EXPECT_EQ(1, array->getNbComponent()); EXPECT_STREQ("", array->getID().c_str()); } TYPED_TEST(ArrayConstructor, ConstructDefault2) { auto array = this->construct(1000); EXPECT_EQ(1000, array->size()); EXPECT_EQ(1, array->getNbComponent()); EXPECT_STREQ("", array->getID().c_str()); } TYPED_TEST(ArrayConstructor, ConstructDefault3) { auto array = this->construct(1000, 10); EXPECT_EQ(1000, array->size()); EXPECT_EQ(10, array->getNbComponent()); EXPECT_STREQ("", array->getID().c_str()); } TYPED_TEST(ArrayConstructor, ConstructDefault4) { auto array = this->construct(1000, 10, "test"); EXPECT_EQ(1000, array->size()); EXPECT_EQ(10, array->getNbComponent()); EXPECT_STREQ("test", array->getID().c_str()); } TYPED_TEST(ArrayConstructor, ConstructDefault5) { auto array = this->construct(1000, 10, 1); EXPECT_EQ(1000, array->size()); EXPECT_EQ(10, array->getNbComponent()); EXPECT_EQ(1, array->operator()(10, 6)); EXPECT_STREQ("", array->getID().c_str()); } TYPED_TEST(ArrayConstructor, ConstructDefault6) { typename TestFixture::type defaultv[2] = {0, 1}; - auto array = this->construct(1000, 10, defaultv); + auto array = this->construct(1000, 2, defaultv); EXPECT_EQ(1000, array->size()); - EXPECT_EQ(10, array->getNbComponent()); + EXPECT_EQ(2, array->getNbComponent()); EXPECT_EQ(1, array->operator()(10, 1)); EXPECT_EQ(0, array->operator()(603, 0)); EXPECT_STREQ("", array->getID().c_str()); } /* -------------------------------------------------------------------------- */ template class ArrayFixture : public ArrayConstructor { public: void SetUp() override { ArrayConstructor::SetUp(); array = this->construct(1000, 10); } void TearDown() override { array.reset(nullptr); } protected: std::unique_ptr> array; }; TYPED_TEST_CASE(ArrayFixture, TestTypes); TYPED_TEST(ArrayFixture, Copy) { Array copy(*this->array); EXPECT_EQ(1000, copy.size()); EXPECT_EQ(10, copy.getNbComponent()); EXPECT_NE(this->array->storage(), copy.storage()); } TYPED_TEST(ArrayFixture, Set) { auto & arr = *(this->array); arr.set(12); EXPECT_EQ(12, arr(156, 5)); EXPECT_EQ(12, arr(520, 7)); EXPECT_EQ(12, arr(999, 9)); } TYPED_TEST(ArrayFixture, Resize) { auto & arr = *(this->array); auto ptr = arr.storage(); arr.resize(0); EXPECT_EQ(0, arr.size()); EXPECT_EQ(ptr, arr.storage()); EXPECT_EQ(1000, arr.getAllocatedSize()); arr.resize(3000); EXPECT_EQ(3000, arr.size()); EXPECT_EQ(3000, arr.getAllocatedSize()); arr.resize(0); EXPECT_EQ(0, arr.size()); EXPECT_EQ(nullptr, arr.storage()); EXPECT_EQ(0, arr.getAllocatedSize()); } TYPED_TEST(ArrayFixture, PushBack) { auto & arr = *(this->array); auto ptr = arr.storage(); arr.resize(0); EXPECT_EQ(0, arr.size()); EXPECT_EQ(ptr, arr.storage()); EXPECT_EQ(1000, arr.getAllocatedSize()); arr.resize(3000); EXPECT_EQ(3000, arr.size()); EXPECT_EQ(3000, arr.getAllocatedSize()); arr.resize(0); EXPECT_EQ(0, arr.size()); EXPECT_EQ(nullptr, arr.storage()); EXPECT_EQ(0, arr.getAllocatedSize()); } TYPED_TEST(ArrayFixture, ViewVector) { auto && view = make_view(*this->array, 10); EXPECT_NO_THROW(view.begin()); { auto it = view.begin(); EXPECT_EQ(10, it->size()); EXPECT_PRED_FORMAT2(AssertType, typeid(*it), typeid(Vector)); EXPECT_PRED_FORMAT2(AssertType, typeid(it[0]), typeid(VectorProxy)); } } TYPED_TEST(ArrayFixture, ViewMatrix) { { auto && view = make_view(*this->array, 2, 5); EXPECT_NO_THROW(view.begin()); { auto it = view.begin(); EXPECT_EQ(10, it->size()); EXPECT_EQ(2, it->size(0)); EXPECT_EQ(5, it->size(1)); EXPECT_PRED_FORMAT2(AssertType, typeid(*it), typeid(Matrix)); EXPECT_PRED_FORMAT2(AssertType, typeid(it[0]), typeid(MatrixProxy)); } } } TYPED_TEST(ArrayFixture, ViewVectorWrong) { auto && view = make_view(*this->array, 11); EXPECT_THROW(view.begin(), debug::ArrayException); } TYPED_TEST(ArrayFixture, ViewMatrixWrong) { auto && view = make_view(*this->array, 3, 7); EXPECT_THROW(view.begin(), debug::ArrayException); } TYPED_TEST(ArrayFixture, ViewMatrixIter) { std::size_t count = 0; for (auto && mat : make_view(*this->array, 10, 10)) { EXPECT_EQ(100, mat.size()); EXPECT_EQ(10, mat.size(0)); EXPECT_EQ(10, mat.size(1)); EXPECT_PRED_FORMAT2(AssertType, typeid(mat), typeid(Matrix)); ++count; } EXPECT_EQ(100, count); } } // namespace diff --git a/test/test_common/test_tensors.cc b/test/test_common/test_tensors.cc index 8803a66e4..d52b9d302 100644 --- a/test/test_common/test_tensors.cc +++ b/test/test_common/test_tensors.cc @@ -1,531 +1,533 @@ /* -------------------------------------------------------------------------- */ #include "aka_array.hh" #include "aka_types.hh" /* -------------------------------------------------------------------------- */ #include #include #include /* -------------------------------------------------------------------------- */ using namespace akantu; namespace { /* -------------------------------------------------------------------------- */ class TensorConstructorFixture : public ::testing::Test { public: void SetUp() override { for (auto & r : reference) { r = rand(); // google-test seeds srand() } } void TearDown() override {} template void compareToRef(const V & v) { for (int i = 0; i < size_; ++i) { EXPECT_DOUBLE_EQ(reference[i], v.storage()[i]); } } protected: const int size_{24}; const std::array mat_size{{4, 6}}; // const std::array tens3_size{{4, 2, 3}}; std::array reference; }; /* -------------------------------------------------------------------------- */ class TensorFixture : public TensorConstructorFixture { public: TensorFixture() : vref(reference.data(), size_), mref(reference.data(), mat_size[0], mat_size[1]) {} protected: Vector vref; Matrix mref; }; /* -------------------------------------------------------------------------- */ // Vector ---------------------------------------------------------------------- TEST_F(TensorConstructorFixture, VectorDefaultConstruct) { Vector v; EXPECT_EQ(0, v.size()); EXPECT_EQ(nullptr, v.storage()); EXPECT_EQ(false, v.isWrapped()); } TEST_F(TensorConstructorFixture, VectorConstruct1) { double r = rand(); Vector v(size_, r); EXPECT_EQ(size_, v.size()); EXPECT_EQ(false, v.isWrapped()); for (int i = 0; i < size_; ++i) { EXPECT_DOUBLE_EQ(r, v(i)); EXPECT_DOUBLE_EQ(r, v[i]); } } TEST_F(TensorConstructorFixture, VectorConstructWrapped) { Vector v(reference.data(), size_); EXPECT_EQ(size_, v.size()); EXPECT_EQ(true, v.isWrapped()); for (int i = 0; i < size_; ++i) { EXPECT_DOUBLE_EQ(reference[i], v(i)); EXPECT_DOUBLE_EQ(reference[i], v[i]); } } TEST_F(TensorConstructorFixture, VectorConstructInitializer) { Vector v{0., 1., 2., 3., 4., 5.}; EXPECT_EQ(6, v.size()); EXPECT_EQ(false, v.isWrapped()); for (int i = 0; i < 6; ++i) { EXPECT_DOUBLE_EQ(i, v(i)); } } TEST_F(TensorConstructorFixture, VectorConstructCopy1) { Vector vref(reference.data(), reference.size()); Vector v(vref); EXPECT_EQ(size_, v.size()); EXPECT_EQ(false, v.isWrapped()); compareToRef(v); } TEST_F(TensorConstructorFixture, VectorConstructCopy2) { Vector vref(reference.data(), reference.size()); Vector v(vref, false); EXPECT_EQ(size_, v.size()); EXPECT_EQ(true, v.isWrapped()); compareToRef(v); } TEST_F(TensorConstructorFixture, VectorConstructProxy1) { VectorProxy vref(reference.data(), reference.size()); EXPECT_EQ(size_, vref.size()); compareToRef(vref); Vector v(vref); EXPECT_EQ(size_, v.size()); EXPECT_EQ(true, v.isWrapped()); compareToRef(v); } TEST_F(TensorConstructorFixture, VectorConstructProxy2) { Vector vref(reference.data(), reference.size()); VectorProxy v(vref); EXPECT_EQ(size_, v.size()); compareToRef(v); } /* -------------------------------------------------------------------------- */ TEST_F(TensorFixture, VectorEqual) { Vector v; v = vref; compareToRef(v); EXPECT_EQ(size_, v.size()); EXPECT_EQ(false, v.isWrapped()); } TEST_F(TensorFixture, VectorEqualProxy) { VectorProxy vref_proxy(vref); Vector v; v = vref; compareToRef(v); EXPECT_EQ(size_, v.size()); EXPECT_EQ(false, v.isWrapped()); } TEST_F(TensorFixture, VectorEqualProxy2) { Vector v_store(size_, 0.); VectorProxy v(v_store); v = vref; compareToRef(v); compareToRef(v_store); } /* -------------------------------------------------------------------------- */ TEST_F(TensorFixture, VectorSet) { Vector v(vref); compareToRef(v); double r = rand(); v.set(r); for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(r, v[i]); } TEST_F(TensorFixture, VectorClear) { Vector v(vref); compareToRef(v); v.clear(); for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(0, v[i]); } /* -------------------------------------------------------------------------- */ TEST_F(TensorFixture, VectorDivide) { Vector v; double r = rand(); v = vref / r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] / r, v[i]); } TEST_F(TensorFixture, VectorMultiply1) { Vector v; double r = rand(); v = vref * r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * r, v[i]); } TEST_F(TensorFixture, VectorMultiply2) { Vector v; double r = rand(); v = r * vref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * r, v[i]); } TEST_F(TensorFixture, VectorAddition) { Vector v; v = vref + vref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * 2., v[i]); } TEST_F(TensorFixture, VectorSubstract) { Vector v; v = vref - vref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(0., v[i]); } TEST_F(TensorFixture, VectorDivideEqual) { Vector v(vref); double r = rand(); v /= r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] / r, v[i]); } TEST_F(TensorFixture, VectorMultiplyEqual1) { Vector v(vref); double r = rand(); v *= r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * r, v[i]); } TEST_F(TensorFixture, VectorMultiplyEqual2) { Vector v(vref); v *= v; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * reference[i], v[i]); } TEST_F(TensorFixture, VectorAdditionEqual) { Vector v(vref); v += vref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * 2., v[i]); } TEST_F(TensorFixture, VectorSubstractEqual) { Vector v(vref); v -= vref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(0., v[i]); } /* -------------------------------------------------------------------------- */ // Matrix ---------------------------------------------------------------------- TEST_F(TensorConstructorFixture, MatrixDefaultConstruct) { Matrix m; EXPECT_EQ(0, m.size()); EXPECT_EQ(0, m.rows()); EXPECT_EQ(0, m.cols()); EXPECT_EQ(nullptr, m.storage()); EXPECT_EQ(false, m.isWrapped()); } TEST_F(TensorConstructorFixture, MatrixConstruct1) { double r = rand(); Matrix m(mat_size[0], mat_size[1], r); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(false, m.isWrapped()); for (int i = 0; i < mat_size[0]; ++i) { for (int j = 0; j < mat_size[1]; ++j) { EXPECT_EQ(r, m(i, j)); EXPECT_EQ(r, m[i + j * mat_size[0]]); } } } TEST_F(TensorConstructorFixture, MatrixConstructWrapped) { Matrix m(reference.data(), mat_size[0], mat_size[1]); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(true, m.isWrapped()); for (int i = 0; i < mat_size[0]; ++i) { for (int j = 0; j < mat_size[1]; ++j) { EXPECT_DOUBLE_EQ(reference[i + j * mat_size[0]], m(i, j)); } } compareToRef(m); } TEST_F(TensorConstructorFixture, MatrixConstructInitializer) { Matrix m{{0., 1., 2.}, {3., 4., 5.}}; EXPECT_EQ(6, m.size()); EXPECT_EQ(2, m.rows()); EXPECT_EQ(3, m.cols()); EXPECT_EQ(false, m.isWrapped()); int c = 0; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 3; ++j, ++c) { EXPECT_DOUBLE_EQ(c, m(i, j)); } } } TEST_F(TensorConstructorFixture, MatrixConstructCopy1) { Matrix mref(reference.data(), mat_size[0], mat_size[1]); Matrix m(mref); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(false, m.isWrapped()); compareToRef(m); } TEST_F(TensorConstructorFixture, MatrixConstructCopy2) { Matrix mref(reference.data(), mat_size[0], mat_size[1]); Matrix m(mref); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(false, m.isWrapped()); compareToRef(m); } TEST_F(TensorConstructorFixture, MatrixConstructProxy1) { MatrixProxy mref(reference.data(), mat_size[0], mat_size[1]); EXPECT_EQ(size_, mref.size()); EXPECT_EQ(mat_size[0], mref.size(0)); EXPECT_EQ(mat_size[1], mref.size(1)); compareToRef(mref); Matrix m(mref); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(true, m.isWrapped()); compareToRef(m); } TEST_F(TensorConstructorFixture, MatrixConstructProxy2) { Matrix mref(reference.data(), mat_size[0], mat_size[1]); MatrixProxy m(mref); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.size(0)); EXPECT_EQ(mat_size[1], m.size(1)); compareToRef(m); } /* -------------------------------------------------------------------------- */ TEST_F(TensorFixture, MatrixEqual) { Matrix m; m = mref; compareToRef(m); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(false, m.isWrapped()); } TEST_F(TensorFixture, MatrixEqualProxy1) { MatrixProxy mref_proxy(mref); Matrix m; m = mref; compareToRef(m); EXPECT_EQ(size_, m.size()); EXPECT_EQ(mat_size[0], m.rows()); EXPECT_EQ(mat_size[1], m.cols()); EXPECT_EQ(false, m.isWrapped()); } TEST_F(TensorFixture, MatrixEqualProxy2) { Matrix m_store(mat_size[0], mat_size[1], 0.); MatrixProxy m(m_store); m = mref; compareToRef(m); compareToRef(m_store); } TEST_F(TensorFixture, MatrixEqualSlice) { Matrix m(mat_size[0], mat_size[1], 0.); for (unsigned int i = 0; i < m.cols(); ++i) m(i) = Vector(mref(i)); compareToRef(m); } /* -------------------------------------------------------------------------- */ TEST_F(TensorFixture, MatrixSet) { Matrix m(mref); compareToRef(m); double r = rand(); m.set(r); for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(r, m[i]); } TEST_F(TensorFixture, MatrixClear) { Matrix m(mref); compareToRef(m); m.clear(); for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(0, m[i]); } /* -------------------------------------------------------------------------- */ TEST_F(TensorFixture, MatrixDivide) { Matrix m; double r = rand(); m = mref / r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] / r, m[i]); } TEST_F(TensorFixture, MatrixMultiply1) { Matrix m; double r = rand(); m = mref * r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * r, m[i]); } TEST_F(TensorFixture, MatrixMultiply2) { Matrix m; double r = rand(); m = r * mref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * r, m[i]); } TEST_F(TensorFixture, MatrixAddition) { Matrix m; m = mref + mref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * 2., m[i]); } TEST_F(TensorFixture, MatrixSubstract) { Matrix m; m = mref - mref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(0., m[i]); } TEST_F(TensorFixture, MatrixDivideEqual) { Matrix m(mref); double r = rand(); m /= r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] / r, m[i]); } TEST_F(TensorFixture, MatrixMultiplyEqual1) { Matrix m(mref); double r = rand(); m *= r; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * r, m[i]); } TEST_F(TensorFixture, MatrixAdditionEqual) { Matrix m(mref); m += mref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(reference[i] * 2., m[i]); } TEST_F(TensorFixture, MatrixSubstractEqual) { Matrix m(mref); m -= mref; for (int i = 0; i < size_; ++i) EXPECT_DOUBLE_EQ(0., m[i]); } +#if defined (AKANTU_USE_LAPACK) TEST_F(TensorFixture, MatrixEigs) { Matrix m{{0, 1, 0, 0}, {1., 0, 0, 0}, {0, 1, 0, 1}, {0, 0, 4, 0}}; Matrix eig_vects(4, 4); Vector eigs(4); m.eig(eigs, eig_vects); Vector eigs_ref{2, 1., -1., -2}; auto lambda_v = m * eig_vects; for (int i = 0; i < 4; ++i) { EXPECT_NEAR(eigs_ref(i), eigs(i), 1e-14); for (int j = 0; j < 4; ++j) { EXPECT_NEAR(lambda_v(i)(j), eigs(i) * eig_vects(i)(j), 1e-14); } } } +#endif /* -------------------------------------------------------------------------- */ } // namespace diff --git a/third-party/cmake/iohelper.cmake b/third-party/cmake/iohelper.cmake index 53c56418a..23953af2e 100644 --- a/third-party/cmake/iohelper.cmake +++ b/third-party/cmake/iohelper.cmake @@ -1,99 +1,97 @@ #=============================================================================== # @file iohelper.cmake # # @author Nicolas Richart # # @date creation: Mon Mar 30 2015 # @date last modification: Tue Jan 19 2016 # # @brief build script for iohelper # # @section LICENSE # # Copyright (©) 2015 EPFL (Ecole Polytechnique Fédérale de Lausanne) Laboratory # (LSMS - Laboratoire de Simulation en Mécanique des Solides) # # Akantu is free software: you can redistribute it and/or modify it under the # terms of the GNU Lesser General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # Akantu is distributed in the hope that it will be useful, but WITHOUT ANY # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR # A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more # details. # # You should have received a copy of the GNU Lesser General Public License # along with Akantu. If not, see . # #=============================================================================== if(EXISTS ${PROJECT_SOURCE_DIR}/third-party/iohelper) set(IOHELPER_TARGETS_EXPORT ${AKANTU_TARGETS_EXPORT}) add_subdirectory(${PROJECT_SOURCE_DIR}/third-party/iohelper) set(IOHELPER_SOURCE_TYPE "internal" CACHE INTERNAL "internal variable for clean export") #set(IOHELPER_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/third-party/iohelper/src" # CACHE INTERNAL "IOHelper include directory") set(IOHELPER_LIBRARIES iohelper CACHE INTERNAL "IOHelper library") package_add_to_export_list(iohelper iohelper) + mask_package_options(IOHELPER) return() endif() if(NOT EXISTS ${PROJECT_SOURCE_DIR}/third-party/${IOHELPER_ARCHIVE}) set(_iohelper_download_command GIT_REPOSITORY ${IOHELPER_GIT} GIT_TAG ${IOHELPER_VERSION} ) else() set(_iohelper_download_command URL ${PROJECT_SOURCE_DIR}/third-party/${IOHELPER_ARCHIVE} ) endif() if(CMAKE_VERSION VERSION_GREATER 3.1) set(_extra_options UPDATE_DISCONNECTED 1 DOWNLOAD_NO_PROGRESS 1 EXCLUDE_FROM_ALL 1 ) endif() ExternalProject_Add(iohelper PREFIX ${PROJECT_BINARY_DIR}/third-party ${_iohelper_download_command} ${_extra_options} CMAKE_ARGS / CMAKE_CACHE_ARGS -DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER:PATH=${CMAKE_CXX_COMPILER} ) find_library(IOHELPER_LIBRARIES iohelper HINTS ${PROJECT_BINARY_DIR}/third-party) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") set(_tmp ${IOHELPER_LIBRARIES}) set(IOHELPER_LIBRARIES "${_tmp}.a" CACHE FILEPATH "" FORCE) endif() find_path(IOHELPER_INCLUDE_DIR iohelper/io_helper.hh HINTS ${PROJECT_BINARY_DIR}/third-party) set(IOHELPER_SOURCE_TYPE "external" CACHE INTERNAL "internal variable for clean export") -mark_as_advanced( - IOHELPER_LIBRARIES - IOHELPER_INCLUDE_DIR - ) +mask_package_options(IOHELPER) package_add_extra_dependency(IOHelper iohelper) install(FILES ${IOHELPER_LIBRARIES} DESTINATION lib COMPONENT lib ) install(DIRECTORY ${IOHELPER_INCLUDE_DIR} DESTINATION include COMPONENT dev)