diff --git a/test/test_synchronizer/CMakeLists.txt b/test/test_synchronizer/CMakeLists.txt index b4e23a466..9d2afacdc 100644 --- a/test/test_synchronizer/CMakeLists.txt +++ b/test/test_synchronizer/CMakeLists.txt @@ -1,94 +1,86 @@ #=============================================================================== # @file CMakeLists.txt # # @author Nicolas Richart # # @date creation: Fri Sep 03 2010 # @date last modification: Wed Jan 20 2016 # # @brief configuration for synchronizer tests # # @section LICENSE # # Copyright (©) 2010-2012, 2014, 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 . # # @section DESCRIPTION # #=============================================================================== add_mesh(test_synchronizer_communication_mesh cube.geo 3 2) -register_test(test_synchronizer_communication - SOURCES test_synchronizer_communication.cc - DEPENDS test_synchronizer_communication_mesh - PACKAGE parallel - PARALLEL - ) - -register_test(test_node_synchronizer - SOURCES test_node_synchronizer.cc - DEPENDS test_synchronizer_communication_mesh - PACKAGE parallel - PARALLEL - ) - register_test(test_dof_synchronizer SOURCES test_dof_synchronizer.cc test_data_accessor.hh FILES_TO_COPY bar.msh PACKAGE parallel PARALLEL ) # if(DEFINED AKANTU_DAMAGE_NON_LOCAL) # add_executable(test_grid_synchronizer_check_neighbors test_grid_synchronizer_check_neighbors.cc test_grid_tools.hh) # target_link_libraries(test_grid_synchronizer_check_neighbors akantu) # if(AKANTU_EXTRA_CXX_FLAGS) # set_target_properties(test_grid_synchronizer_check_neighbors PROPERTIES COMPILE_FLAGS ${AKANTU_EXTRA_CXX_FLAGS}) # endif() # endif() # register_test(test_grid_synchronizer # SOURCES test_grid_synchronizer.cc test_data_accessor.hh # DEPENDS test_synchronizer_communication_mesh test_grid_synchronizer_check_neighbors # EXTRA_FILES test_grid_synchronizer_check_neighbors.cc test_grid_tools.hh # PACKAGE damage_non_local # ) -# register_test(test_dof_synchronizer_communication -# SOURCES test_dof_synchronizer_communication.cc test_dof_data_accessor.hh -# DEPENDS test_synchronizer_communication_mesh -# PACKAGE parallel -# ) +register_gtest_sources( + SOURCES test_synchronizer_communication.cc test_data_accessor.hh test_synchronizers_fixture.hh + PACKAGE parallel + ) -register_test(test_data_distribution - SOURCES test_data_distribution.cc - FILES_TO_COPY data_split.msh +register_gtest_sources( + SOURCES test_node_synchronizer.cc test_synchronizers_fixture.hh + PACKAGE parallel + ) + +register_gtest_sources( + SOURCES test_data_distribution.cc test_synchronizers_fixture.hh + DEPENDS test_synchronizer_communication_mesh PACKAGE parallel - PARALLEL ) add_mesh(test_facet_synchronizer_mesh facet.geo 3 2) -register_test(test_facet_synchronizer - SOURCES test_facet_synchronizer.cc test_data_accessor.hh +register_gtest_sources( + SOURCES test_facet_synchronizer.cc test_data_accessor.hh test_synchronizers_fixture.hh DEPENDS test_facet_synchronizer_mesh PACKAGE parallel cohesive_element - PARALLEL_LEVEL 3 ) + +register_gtest_test(test_synchronizers + DEPENDS test_synchronizer_communication_mesh + PARALLEL) diff --git a/test/test_synchronizer/cube.geo b/test/test_synchronizer/cube.geo index 252af1e9e..366bdfec5 100644 --- a/test/test_synchronizer/cube.geo +++ b/test/test_synchronizer/cube.geo @@ -1,47 +1,45 @@ h=0.333; Point(1) = {0, 0, 0, h}; Point(2) = {0, -1, 0, h}; Point(3) = {1, -1, 0, h}; Point(4) = {1, 0, 0, h}; Point(5) = {0, 0, 1, h}; Point(6) = {0, -1, 1, h}; Point(7) = {1, -1, 1, h}; Point(8) = {1, 0, 1, h}; Line(1) = {1, 5}; Line(2) = {5, 8}; Line(3) = {8, 4}; Line(4) = {4, 1}; Line(5) = {6, 2}; Line(6) = {2, 3}; Line(7) = {3, 7}; Line(8) = {7, 6}; Line(9) = {5, 6}; Line(10) = {1, 2}; Line(11) = {4, 3}; Line(12) = {8, 7}; Line Loop(26) = {4, 1, 2, 3}; Plane Surface(26) = {26}; Line Loop(28) = {9, -8, -12, -2}; Plane Surface(28) = {28}; Line Loop(30) = {-7, -11, -3, 12}; Plane Surface(30) = {30}; Line Loop(32) = {-10, -4, 11, -6}; Plane Surface(32) = {32}; Line Loop(34) = {10, -5, -9, -1}; Plane Surface(34) = {34}; Line Loop(36) = {8, 5, 6, 7}; Plane Surface(36) = {36}; Surface Loop(50) = {26, 28, 30, 32, 34, 36}; Volume(50) = {50}; Physical Volume ("PhysVol") = {50}; Physical Surface ("Sides") = {26, 28, 30, 32,34, 36}; // Side faces Physical Line ("Lines") = {1,2,3,4,5,6,7,8,9,10,11,12}; // Side lines - - diff --git a/test/test_synchronizer/test_data_accessor.hh b/test/test_synchronizer/test_data_accessor.hh index 689817595..fbab621f5 100644 --- a/test/test_synchronizer/test_data_accessor.hh +++ b/test/test_synchronizer/test_data_accessor.hh @@ -1,132 +1,125 @@ /** * @file test_data_accessor.hh * * @author Nicolas Richart * @author Marco Vocialta * * @date creation: Thu Apr 11 2013 * @date last modification: Sun Oct 19 2014 * * @brief Data Accessor class for testing * * @section LICENSE * * Copyright (©) 2014, 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 . * */ /* -------------------------------------------------------------------------- */ - -#include "aka_common.hh" #include "data_accessor.hh" #include "mesh.hh" +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ + using namespace akantu; /* -------------------------------------------------------------------------- */ class TestAccessor : public DataAccessor { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: inline TestAccessor(const Mesh & mesh, const ElementTypeMapArray & barycenters); AKANTU_GET_MACRO_BY_ELEMENT_TYPE_CONST(Barycenter, barycenters, Real); /* ------------------------------------------------------------------------ */ /* Ghost Synchronizer inherited members */ /* ------------------------------------------------------------------------ */ protected: inline UInt getNbData(const Array & elements, const SynchronizationTag & tag) const; inline void packData(CommunicationBuffer & buffer, const Array & elements, const SynchronizationTag & tag) const; inline void unpackData(CommunicationBuffer & buffer, const Array & elements, const SynchronizationTag & tag); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ protected: const ElementTypeMapArray & barycenters; const Mesh & mesh; }; /* -------------------------------------------------------------------------- */ /* TestSynchronizer implementation */ /* -------------------------------------------------------------------------- */ inline TestAccessor::TestAccessor(const Mesh & mesh, const ElementTypeMapArray & barycenters) : barycenters(barycenters), mesh(mesh) {} inline UInt TestAccessor::getNbData(const Array & elements, const SynchronizationTag &) const { if (elements.size()) // return Mesh::getSpatialDimension(elements(0).type) * sizeof(Real) * // elements.size(); return mesh.getSpatialDimension() * sizeof(Real) * elements.size(); else return 0; } inline void TestAccessor::packData(CommunicationBuffer & buffer, const Array & elements, const SynchronizationTag &) const { UInt spatial_dimension = mesh.getSpatialDimension(); Array::const_iterator bit = elements.begin(); Array::const_iterator bend = elements.end(); for (; bit != bend; ++bit) { const Element & element = *bit; Vector bary( this->barycenters(element.type, element.ghost_type).storage() + element.element * spatial_dimension, spatial_dimension); buffer << bary; } } inline void TestAccessor::unpackData(CommunicationBuffer & buffer, const Array & elements, - const SynchronizationTag & tag) { + const SynchronizationTag &) { UInt spatial_dimension = mesh.getSpatialDimension(); - Array::const_iterator bit = elements.begin(); - Array::const_iterator bend = elements.end(); - for (; bit != bend; ++bit) { - const Element & element = *bit; + for(const auto & element : elements) { Vector barycenter_loc( this->barycenters(element.type, element.ghost_type).storage() + element.element * spatial_dimension, spatial_dimension); Vector bary(spatial_dimension); buffer >> bary; - std::cout << element << barycenter_loc << std::endl; - Real tolerance = 1e-15; - for (UInt i = 0; i < spatial_dimension; ++i) { - if (!(std::abs(bary(i) - barycenter_loc(i)) <= tolerance)) - AKANTU_DEBUG_ERROR("Unpacking an unknown value for the element: " - << element << "(barycenter[" << i - << "] = " << barycenter_loc(i) << " and buffer[" << i - << "] = " << bary(i) << ") - tag: " << tag); - } + + auto dist = (barycenter_loc - bary).template norm(); + EXPECT_NEAR(0, dist, 1e-15); } } diff --git a/test/test_synchronizer/test_data_distribution.cc b/test/test_synchronizer/test_data_distribution.cc index 59ba6be9b..55ff32aaf 100644 --- a/test/test_synchronizer/test_data_distribution.cc +++ b/test/test_synchronizer/test_data_distribution.cc @@ -1,173 +1,73 @@ /** * @file test_data_distribution.cc * * @author Nicolas Richart * * @date creation: Fri Sep 05 2014 * @date last modification: Sun Oct 19 2014 * * @brief Test the mesh distribution on creation of a distributed synchonizer * * @section LICENSE * * Copyright (©) 2014, 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 . * */ /* -------------------------------------------------------------------------- */ -#include "aka_iterators.hh" -#include "aka_random_generator.hh" -#include "element_group.hh" -#include "element_synchronizer.hh" -#include "mesh_iterators.hh" -#include "mesh_partition_mesh_data.hh" +#include "test_synchronizers_fixture.hh" /* -------------------------------------------------------------------------- */ -#include -/* -------------------------------------------------------------------------- */ - -using namespace akantu; - -int main(int argc, char * argv[]) { - initialize(argc, argv); - - const UInt spatial_dimension = 3; - - Mesh mesh_group_after(spatial_dimension, "after"); - Mesh mesh_group_before(spatial_dimension, "before"); - const auto & comm = Communicator::getStaticCommunicator(); - Int psize = comm.getNbProc(); - Int prank = comm.whoAmI(); +TEST_F(TestSynchronizerFixture, DataDistribution) { + auto & barycenters = this->mesh->registerData("barycenters"); + auto spatial_dimension = this->mesh->getSpatialDimension(); + barycenters.initialize(*this->mesh, _spatial_dimension = _all_dimensions, + _nb_component = spatial_dimension); - if (prank == 0) { - mesh_group_before.read("data_split.msh"); - mesh_group_after.read("data_split.msh"); + this->initBarycenters(barycenters, *this->mesh); + this->distribute(); - mesh_group_before.registerData("global_id"); - mesh_group_after.registerData("global_id"); + for (auto && ghost_type : ghost_types) { + for (const auto & type : + this->mesh->elementTypes(_all_dimensions, ghost_type)) { + auto & barycenters = + this->mesh->getData("barycenters", type, ghost_type); - for (const auto & type : mesh_group_after.elementTypes(_all_dimensions)) { - auto & gidb = mesh_group_before.getDataPointer("global_id", type); - auto & gida = mesh_group_after.getDataPointer("global_id", type); + for (auto && data : enumerate(make_view(barycenters, spatial_dimension))) { + Element element{type, UInt(std::get<0>(data)), ghost_type}; + Vector barycenter(spatial_dimension); + this->mesh->getBarycenter(element, barycenter); - for (auto && data : zip(arange(gida.size()), gida, gidb)) { - std::get<1>(data) = std::get<0>(data); - std::get<2>(data) = std::get<0>(data); + auto dist = (std::get<1>(data) - barycenter).template norm(); + EXPECT_NEAR(dist, 0, 1e-7); } } } +} - RandomGenerator::seed(1); - mesh_group_before.distribute(); - - RandomGenerator::seed(1); - mesh_group_after.distribute(); - - if (prank == 0) - std::cout << mesh_group_after; - - for (const auto & agrp : ElementGroupsIterable(mesh_group_after)) { - const ElementGroup & bgrp = - mesh_group_before.getElementGroup(agrp.getName()); - - for (auto && ghost_type : ghost_types) { - for (const auto & type : bgrp.elementTypes(_all_dimensions, ghost_type)) { - Array & gidb = mesh_group_before.getDataPointer( - "global_id", type, ghost_type); - Array & gida = mesh_group_after.getDataPointer( - "global_id", type, ghost_type); - - Array bgelem(bgrp.getElements(type, ghost_type)); - Array agelem(agrp.getElements(type, ghost_type)); - - std::transform(agelem.begin(), agelem.end(), agelem.begin(), - [&gida](auto & i) { return gida(i); }); - std::transform(bgelem.begin(), bgelem.end(), bgelem.begin(), - [&gidb](auto & i) { return gidb(i); }); - - std::sort(bgelem.begin(), bgelem.end()); - std::sort(agelem.begin(), agelem.end()); - - if (not std::equal(bgelem.begin(), bgelem.end(), agelem.begin())) { - std::cerr << "The filters array for the group " << agrp.getName() - << " and for the element type " << type << ", " - << ghost_type << " do not match" << std::endl; - - debug::setDebugLevel(dblTest); - - std::cerr << bgelem << std::endl; - std::cerr << agelem << std::endl; - debug::debugger.exit(EXIT_FAILURE); - } - } - } - } - - for (const auto & agrp : NodeGroupsIterable(mesh_group_after)) { - const NodeGroup & bgrp = mesh_group_before.getNodeGroup(agrp.getName()); - - const Array & gidb = mesh_group_before.getGlobalNodesIds(); - const Array & gida = mesh_group_after.getGlobalNodesIds(); - - Array bgnode(0, 1); - Array agnode(0, 1); - - for (auto && pair : zip(bgrp, agrp)) { - UInt a,b; - std::tie(b, a) = pair; - if (psize > 1) { - if (mesh_group_before.isLocalOrMasterNode(b)) - bgnode.push_back(gidb(b)); - - if (mesh_group_after.isLocalOrMasterNode(a)) - agnode.push_back(gida(a)); - } - } - - std::sort(bgnode.begin(), bgnode.end()); - std::sort(agnode.begin(), agnode.end()); - - if (!std::equal(bgnode.begin(), bgnode.end(), agnode.begin())) { - std::cerr << "The filters array for the group " << agrp.getName() << " do not match" - << std::endl; +TEST_F(TestSynchronizerFixture, DataDistributionTags) { + this->distribute(); - debug::setDebugLevel(dblTest); + for (const auto & type : this->mesh->elementTypes(_all_dimensions)) { + auto & tags = this->mesh->getData("tag_0", type); + Array::const_vector_iterator tags_it = tags.begin(1); + Array::const_vector_iterator tags_end = tags.end(1); - std::cerr << bgnode << std::endl; - std::cerr << agnode << std::endl; - debug::debugger.exit(EXIT_FAILURE); - } + // The number of tags should match the number of elements on rank" + EXPECT_EQ(this->mesh->getNbElement(type), tags.size()); } - - mesh_group_after.getElementGroup("inside").setBaseName("after_inside"); - mesh_group_after.getElementGroup("inside").dump(); - mesh_group_after.getElementGroup("outside").setBaseName("after_outside"); - mesh_group_after.getElementGroup("outside").dump(); - mesh_group_after.getElementGroup("volume").setBaseName("after_volume"); - mesh_group_after.getElementGroup("volume").dump(); - - mesh_group_before.getElementGroup("inside").setBaseName("before_inside"); - mesh_group_before.getElementGroup("inside").dump(); - mesh_group_before.getElementGroup("outside").setBaseName("before_outside"); - mesh_group_before.getElementGroup("outside").dump(); - mesh_group_before.getElementGroup("volume").setBaseName("before_volume"); - mesh_group_before.getElementGroup("volume").dump(); - - finalize(); - - return EXIT_SUCCESS; } diff --git a/test/test_synchronizer/test_facet_synchronizer.cc b/test/test_synchronizer/test_facet_synchronizer.cc index ca7acdf31..961f03a12 100644 --- a/test/test_synchronizer/test_facet_synchronizer.cc +++ b/test/test_synchronizer/test_facet_synchronizer.cc @@ -1,61 +1,77 @@ /** * @file test_facet_synchronizer.cc * * @author Marco Vocialta * * * @brief Facet synchronizer test * * @section LICENSE * * Copyright (©) 2010-2012, 2014 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * */ - /* -------------------------------------------------------------------------- */ -#include "facet_synchronizer.hh" -#include "mesh_utils.hh" -#include "synchronizer_registry.hh" +#include "test_synchronizers_fixture.hh" #include "test_data_accessor.hh" -#include +/* -------------------------------------------------------------------------- */ +#include "element_synchronizer.hh" +/* -------------------------------------------------------------------------- */ +#include +#include +#include /* -------------------------------------------------------------------------- */ -using namespace akantu; +class TestFacetSynchronizerFixture : public TestSynchronizerFixture { +public: + void SetUp() override { + TestSynchronizerFixture::SetUp(); + this->distribute(); -int main(int argc, char * argv[]) { - akantu::initialize(argc, argv); + this->mesh->initMeshFacets(); - UInt spatial_dimension = 3; - Mesh mesh(spatial_dimension); + /// compute barycenter for each element + barycenters = std::make_unique>("barycenters", "", 0); + this->initBarycenters(*barycenters, this->mesh->getMeshFacets()); - const auto & comm = Communicator::getStaticCommunicator(); - Int prank = comm.whoAmI(); + test_accessor = std::make_unique(*this->mesh, *this->barycenters); + } - /// partition the mesh - if (prank == 0) { - mesh.read("facet.msh"); + void TearDown() override { + barycenters.reset(nullptr); + test_accessor.reset(nullptr); } - mesh.distribute(); +protected: + std::unique_ptr> barycenters; + std::unique_ptr test_accessor; +}; - auto & synchronizer = mesh.getElementSynchronizer(); - /// create facets - Mesh & mesh_facets = mesh.initMeshFacets("mesh_facets"); +/* -------------------------------------------------------------------------- */ +TEST_F(TestFacetSynchronizerFixture, SynchroneOnce) { + auto & synchronizer = this->mesh->getMeshFacets().getElementSynchronizer(); + synchronizer.synchronizeOnce(*this->test_accessor, _gst_test); +} - /// setup facet communications - auto & facet_synchronizer = mesh_facets.getElementSynchronizer(); +/* -------------------------------------------------------------------------- */ +TEST_F(TestFacetSynchronizerFixture, Synchrone) { + auto & synchronizer = this->mesh->getMeshFacets().getElementSynchronizer(); + synchronizer.synchronize(*this->test_accessor, _gst_test); +} - // AKANTU_DEBUG_INFO("Creating TestAccessor"); - // TestAccessor test_accessor(mesh); - // SynchronizerRegistry synch_registry(test_accessor); +/* -------------------------------------------------------------------------- */ +TEST_F(TestFacetSynchronizerFixture, Asynchrone) { + auto & synchronizer = this->mesh->getMeshFacets().getElementSynchronizer(); + synchronizer.asynchronousSynchronize(*this->test_accessor, _gst_test); - // synch_registry.registerSynchronizer(facet_synchronizer, _gst_test); + std::random_device r; + std::default_random_engine engine(r()); + std::uniform_int_distribution uniform_dist(10, 100); + std::chrono::microseconds delay(uniform_dist(engine)); - // /// synchronize facets and check results - // AKANTU_DEBUG_INFO("Synchronizing tag"); - // synch_registry.synchronize(_gst_test); + std::this_thread::sleep_for(delay); - return 0; + synchronizer.waitEndSynchronize(*this->test_accessor, _gst_test); } diff --git a/test/test_synchronizer/test_node_synchronizer.cc b/test/test_synchronizer/test_node_synchronizer.cc index f0c4986fa..63324557f 100644 --- a/test/test_synchronizer/test_node_synchronizer.cc +++ b/test/test_synchronizer/test_node_synchronizer.cc @@ -1,130 +1,160 @@ /** * @file test_node_synchronizer.cc * * @author Nicolas Richart * * @date creation Tue Apr 04 2017 * * @brief test the default node synchronizer present in the mesh * * @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 "test_synchronizers_fixture.hh" +/* -------------------------------------------------------------------------- */ +#include "communicator.hh" #include "data_accessor.hh" #include "mesh.hh" #include "node_synchronizer.hh" -#include "communicator.hh" /* -------------------------------------------------------------------------- */ +#include +#include +#include #include /* -------------------------------------------------------------------------- */ using namespace akantu; class DataAccessorTest : public DataAccessor { public: explicit DataAccessorTest(Array & data) : data(data) {} - UInt getNbData(const Array & nodes, - const SynchronizationTag &) const { + UInt getNbData(const Array & nodes, const SynchronizationTag &) const { return nodes.size() * sizeof(int); } void packData(CommunicationBuffer & buffer, const Array & nodes, const SynchronizationTag &) const { for (auto node : nodes) { buffer << data(node); } } void unpackData(CommunicationBuffer & buffer, const Array & nodes, const SynchronizationTag &) { for (auto node : nodes) { buffer >> data(node); } } protected: Array & data; }; -int main(int argc, char * argv[]) { - initialize(argc, argv); +class TestNodeSynchronizerFixture : public TestSynchronizerFixture { +public: + static constexpr int max_int = std::numeric_limits::max(); + + void SetUp() override { + TestSynchronizerFixture::SetUp(); + this->distribute(); + + UInt nb_nodes = this->mesh->getNbNodes(); + + node_data = std::make_unique>(nb_nodes); + for (auto && data : enumerate(*node_data)) { + auto n = std::get<0>(data); + auto & d = std::get<1>(data); + UInt gn = this->mesh->getNodeGlobalId(n); + + if (this->mesh->isMasterNode(n)) + d = gn; + else if (this->mesh->isLocalNode(n)) + d = -gn; + else if (this->mesh->isSlaveNode(n)) + d = max_int; + else + d = -max_int; + } - UInt spatial_dimension = 3; + data_accessor = std::make_unique(*node_data); + } - Mesh mesh(spatial_dimension); + void TearDown() override { + data_accessor.reset(nullptr); + node_data.reset(nullptr); + } - const auto & comm = Communicator::getStaticCommunicator(); - Int prank = comm.whoAmI(); + void checkData() { + for (auto && data : enumerate(*this->node_data)) { + auto n = std::get<0>(data); + auto & d = std::get<1>(data); + UInt gn = this->mesh->getNodeGlobalId(n); - if (prank == 0) - mesh.read("cube.msh"); + if (this->mesh->isMasterNode(n)) + EXPECT_EQ(d, gn); - mesh.distribute(); + else if (this->mesh->isLocalNode(n)) + EXPECT_EQ(d, -gn); - UInt nb_nodes = mesh.getNbNodes(); - Array node_data(nb_nodes); + else if (this->mesh->isSlaveNode(n)) + EXPECT_EQ(d, gn); - constexpr int max_int = std::numeric_limits::max(); + else - for (UInt n = 0; n < nb_nodes; ++n) { - UInt gn = mesh.getNodeGlobalId(n); - if (mesh.isMasterNode(n)) - node_data(n) = gn; - else if (mesh.isLocalNode(n)) - node_data(n) = -gn; - else if (mesh.isSlaveNode(n)) - node_data(n) = max_int; - else - node_data(n) = -max_int; + EXPECT_EQ(d, -max_int); + } } - DataAccessorTest data_accessor(node_data); - - auto & node_synchronizer = mesh.getNodeSynchronizer(); - node_synchronizer.synchronize(data_accessor, _gst_test); - - - for (UInt n = 0; n < nb_nodes; ++n) { - int gn = mesh.getNodeGlobalId(n); - if(!((mesh.isMasterNode(n) && node_data(n) == gn) || - (mesh.isLocalNode(n) && node_data(n) == -gn) || - (mesh.isSlaveNode(n) && node_data(n) == gn) || - (mesh.isPureGhostNode(n) && node_data(n) == -max_int) - ) - ) - { - debug::setDebugLevel(dblTest); - std::cout << "prank : " << prank << " (node " << gn << "[" << n << "]) - " - << "( isMaster: " << mesh.isMasterNode(n) << " && " << node_data(n) << " == " << gn << ") " - << "( isLocal: " << mesh.isLocalNode(n) << " && " << node_data(n) << " == " << - gn << ") " - << "( isSlave: " << mesh.isSlaveNode(n) << " && " << node_data(n) << " == " << gn << ") " - << "( isPureGhost: " << mesh.isPureGhostNode(n) << " && " << node_data(n) << " == " << -max_int << ") " - << std::endl; - debug::setDebugLevel(dblDebug); - return -1; - } - } +protected: + std::unique_ptr> node_data; + std::unique_ptr data_accessor; +}; + +/* -------------------------------------------------------------------------- */ +TEST_F(TestNodeSynchronizerFixture, SynchroneOnce) { + auto & synchronizer = this->mesh->getNodeSynchronizer(); + synchronizer.synchronizeOnce(*this->data_accessor, _gst_test); + this->checkData(); +} + +/* -------------------------------------------------------------------------- */ +TEST_F(TestNodeSynchronizerFixture, Synchrone) { + auto & node_synchronizer = this->mesh->getNodeSynchronizer(); + node_synchronizer.synchronize(*this->data_accessor, _gst_test); + this->checkData(); +} + +/* -------------------------------------------------------------------------- */ +TEST_F(TestNodeSynchronizerFixture, Asynchrone) { + auto & synchronizer = this->mesh->getNodeSynchronizer(); + synchronizer.asynchronousSynchronize(*this->data_accessor, _gst_test); + + std::random_device r; + std::default_random_engine engine(r()); + std::uniform_int_distribution uniform_dist(10, 100); + std::chrono::microseconds delay(uniform_dist(engine)); - finalize(); + std::this_thread::sleep_for(delay); - return 0; + synchronizer.waitEndSynchronize(*this->data_accessor, _gst_test); + this->checkData(); } diff --git a/test/test_synchronizer/test_synchronizer_communication.cc b/test/test_synchronizer/test_synchronizer_communication.cc index 4c44b7e79..afda377fa 100644 --- a/test/test_synchronizer/test_synchronizer_communication.cc +++ b/test/test_synchronizer/test_synchronizer_communication.cc @@ -1,159 +1,92 @@ /** * @file test_synchronizer_communication.cc * * @author Dana Christen * @author Nicolas Richart * * @date creation: Wed Sep 01 2010 * @date last modification: Sun Oct 19 2014 * * @brief test to synchronize barycenters * * @section LICENSE * * Copyright (©) 2010-2012, 2014, 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 . * */ - /* -------------------------------------------------------------------------- */ - +#include "test_synchronizers_fixture.hh" +#include "test_data_accessor.hh" /* -------------------------------------------------------------------------- */ -#include "aka_common.hh" -#include "aka_random_generator.hh" #include "element_synchronizer.hh" -#include "mesh.hh" -#include "mesh_partition_scotch.hh" -#include "synchronizer_registry.hh" -/* -------------------------------------------------------------------------- */ - -//#define DUMP - -#if defined(AKANTU_USE_IOHELPER) && defined(DUMP) -#include "dumper_paraview.hh" -#endif // AKANTU_USE_IOHELPER - -#include "test_data_accessor.hh" - -using namespace akantu; - /* -------------------------------------------------------------------------- */ -/* Main */ +#include +#include +#include /* -------------------------------------------------------------------------- */ -int main(int argc, char * argv[]) { - initialize(argc, argv); - UInt spatial_dimension = 3; +class TestElementSynchronizerFixture : public TestSynchronizerFixture { +public: + void SetUp() override { + TestSynchronizerFixture::SetUp(); + this->distribute(); - Mesh mesh(spatial_dimension); + /// compute barycenter for each element + barycenters = std::make_unique>("barycenters", "", 0); + this->initBarycenters(*barycenters, *mesh); - const auto & comm = Communicator::getStaticCommunicator(); - Int prank = comm.whoAmI(); - bool wait = true; - if (argc > 1) { - if (prank == 0) - while (wait) - ; + test_accessor = std::make_unique(*this->mesh, *this->barycenters); } - if (prank == 0) - mesh.read("cube.msh"); - - mesh.distribute(); - - /// compute barycenter for each facet - ElementTypeMapArray barycenters("barycenters", "", 0); - barycenters.initialize(mesh, _nb_component = spatial_dimension); - - for (ghost_type_t::iterator gt = ghost_type_t::begin(); - gt != ghost_type_t::end(); ++gt) { - GhostType ghost_type = *gt; - Mesh::type_iterator it = mesh.firstType(spatial_dimension, ghost_type); - Mesh::type_iterator last_type = - mesh.lastType(spatial_dimension, ghost_type); - - for (; it != last_type; ++it) { - UInt nb_element = mesh.getNbElement(*it, ghost_type); - Array & barycenter = barycenters(*it, ghost_type); - barycenter.resize(nb_element); - - Array::iterator> bary_it = - barycenter.begin(spatial_dimension); - - for (UInt elem = 0; elem < nb_element; ++elem, ++bary_it) - mesh.getBarycenter({*it, elem, ghost_type}, *bary_it); - } + void TearDown() override { + barycenters.reset(nullptr); + test_accessor.reset(nullptr); } - AKANTU_DEBUG_INFO("Creating TestAccessor"); - TestAccessor test_accessor(mesh, barycenters); - SynchronizerRegistry synch_registry; - synch_registry.registerDataAccessor(test_accessor); - synch_registry.registerSynchronizer(mesh.getElementSynchronizer(), _gst_test); - - AKANTU_DEBUG_INFO("Synchronizing tag"); - synch_registry.synchronize(_gst_test); - - // Checking the tags in MeshData (not a very good test because they're all - // identical, - // but still...) - Mesh::type_iterator it = mesh.firstType(_all_dimensions); - Mesh::type_iterator last_type = mesh.lastType(_all_dimensions); +protected: + std::unique_ptr> barycenters; + std::unique_ptr test_accessor; +}; - for (; it != last_type; ++it) { - Array & tags = mesh.getData("tag_0", *it); - Array::const_vector_iterator tags_it = tags.begin(1); - Array::const_vector_iterator tags_end = tags.end(1); - AKANTU_DEBUG_ASSERT( - mesh.getNbElement(*it) == tags.size(), - "The number of tags does not match the number of elements on rank " - << prank << "."); - std::cout << std::dec << " I am rank " << prank - << " and here's my MeshData dump for types " << *it - << " (it should contain " << mesh.getNbElement(*it) - << " elements and it has " << tags.size() << "!) :" << std::endl; - std::cout << std::hex; - debug::setDebugLevel(dblTest); - for (; tags_it != tags_end; ++tags_it) { - std::cout << tags_it->operator()(0) << " "; - } +/* -------------------------------------------------------------------------- */ +TEST_F(TestElementSynchronizerFixture, SynchroneOnce) { + auto & synchronizer = this->mesh->getElementSynchronizer(); + synchronizer.synchronizeOnce(*this->test_accessor, _gst_test); +} - debug::setDebugLevel(dblInfo); - std::cout << std::endl; - } +/* -------------------------------------------------------------------------- */ +TEST_F(TestElementSynchronizerFixture, Synchrone) { + auto & synchronizer = this->mesh->getElementSynchronizer(); + synchronizer.synchronize(*this->test_accessor, _gst_test); +} -#if defined(AKANTU_USE_IOHELPER) && defined(DUMP) - DumperParaview dumper("test-scotch-partition"); - dumper.registerMesh(mesh, spatial_dimension, _not_ghost); - dumper.registerField("partitions", - new DumperIOHelper::ElementPartitionField<>( - mesh, spatial_dimension, _not_ghost)); - dumper.dump(); +/* -------------------------------------------------------------------------- */ +TEST_F(TestElementSynchronizerFixture, Asynchrone) { +auto & synchronizer = this->mesh->getElementSynchronizer(); +synchronizer.asynchronousSynchronize(*this->test_accessor, _gst_test); - DumperParaview dumper_ghost("test-scotch-partition-ghost"); - dumper_ghost.registerMesh(mesh, spatial_dimension, _ghost); - dumper_ghost.registerField("partitions", - new DumperIOHelper::ElementPartitionField<>( - mesh, spatial_dimension, _ghost)); - dumper_ghost.dump(); -#endif // AKANTU_USE_IOHELPER + std::random_device r; + std::default_random_engine engine(r()); + std::uniform_int_distribution uniform_dist(10, 100); + std::chrono::microseconds delay(uniform_dist(engine)); - finalize(); + std::this_thread::sleep_for(delay); - return EXIT_SUCCESS; + synchronizer.waitEndSynchronize(*this->test_accessor, _gst_test); } diff --git a/test/test_synchronizer/test_synchronizers_fixture.hh b/test/test_synchronizer/test_synchronizers_fixture.hh new file mode 100644 index 000000000..5d7f7b168 --- /dev/null +++ b/test/test_synchronizer/test_synchronizers_fixture.hh @@ -0,0 +1,49 @@ +/* -------------------------------------------------------------------------- */ +#include "aka_iterators.hh" +#include "communicator.hh" +#include "mesh.hh" +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ + +using namespace akantu; + +class TestSynchronizerFixture : public ::testing::Test { +public: + virtual void SetUp() { + const UInt spatial_dimension = 3; + + mesh = std::make_unique(spatial_dimension); + + const auto & comm = Communicator::getStaticCommunicator(); + Int prank = comm.whoAmI(); + + if (prank == 0) { + this->mesh->read("cube.msh"); + } + } + + virtual void TearDown() { this->mesh.reset(nullptr); } + + void initBarycenters(ElementTypeMapArray & barycenters, Mesh & mesh) { + auto spatial_dimension = mesh.getSpatialDimension(); + barycenters.initialize(mesh, _spatial_dimension = _all_dimensions, + _nb_component = spatial_dimension, + _with_nb_element = true); + + for (auto && ghost_type : ghost_types) { + for (const auto & type : mesh.elementTypes(_all_dimensions, ghost_type)) { + for (auto && data : enumerate( + make_view(barycenters(type, ghost_type), spatial_dimension))) { + Element element{type, UInt(std::get<0>(data)), ghost_type}; + mesh.getBarycenter(element, std::get<1>(data)); + } + } + } + } + + void distribute() { this->mesh->distribute(); } + +protected: + std::unique_ptr mesh; +};