COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-mesh-meshadaptor.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2013 von Karman Institute for Fluid Dynamics, Belgium
2 //
3 // This software is distributed under the terms of the
4 // GNU Lesser General Public License version 3 (LGPLv3).
5 // See doc/lgpl.txt and doc/gpl.txt for the license text.
6 
7 #define BOOST_TEST_DYN_LINK
8 #define BOOST_TEST_MODULE "Test module for Mesh Manipulations"
9 
10 #include <boost/test/unit_test.hpp>
11 
12 #include "common/Log.hpp"
13 #include "common/OptionList.hpp"
14 #include "common/PropertyList.hpp"
15 #include "common/Core.hpp"
16 
17 #include "common/PE/Comm.hpp"
18 #include "common/PE/debug.hpp"
19 
20 #include "mesh/Mesh.hpp"
21 #include "mesh/Space.hpp"
22 #include "mesh/Connectivity.hpp"
23 #include "mesh/Region.hpp"
24 #include "mesh/MeshWriter.hpp"
25 #include "mesh/MeshGenerator.hpp"
26 #include "mesh/MeshTransformer.hpp"
27 #include "mesh/MeshAdaptor.hpp"
28 
29 #include "common/DynTable.hpp"
30 #include "common/List.hpp"
31 #include "common/Table.hpp"
32 #include "mesh/Dictionary.hpp"
33 
34 using namespace std;
35 using namespace boost;
36 using namespace cf3;
37 using namespace cf3::mesh;
38 using namespace cf3::common;
39 
41 
43 {
46  {
47  m_argc = boost::unit_test::framework::master_test_suite().argc;
48  m_argv = boost::unit_test::framework::master_test_suite().argv;
49  }
50 
53  {
54  }
56 
57 
59  int m_argc;
60  char** m_argv;
61 
62 };
63 
65 
66 BOOST_FIXTURE_TEST_SUITE( MeshManipulationsTests_TestSuite, MeshManipulationsTests_Fixture )
67 
68 
71 {
72  PE::Comm::instance().init(m_argc,m_argv);
73 }
74 
76 
77 BOOST_AUTO_TEST_CASE( test_manipulations_general_use )
78 {
79  // Generate a simple 1D line-mesh of 10 cells
80  boost::shared_ptr< MeshGenerator > meshgenerator = build_component_abstract_type<MeshGenerator>("cf3.mesh.SimpleMeshGenerator","1Dgenerator");
81  meshgenerator->options().set("mesh",URI("//line2"));
82  meshgenerator->options().set("nb_cells",std::vector<Uint>(1,10));
83  meshgenerator->options().set("lengths",std::vector<Real>(1,10.));
84  Mesh& mesh = meshgenerator->generate();
85 
86  // Create a MeshAdaptor object to manipulate the elements
87  MeshAdaptor mesh_adaptor(mesh);
88 
89  // Allocations (not important)
90  PE::Buffer buf;
91  PackedElement unpacked_elem(mesh);
92  PackedNode unpacked_node(mesh);
93 
94  // Prepare the mesh-adaptor, rebuilding element-node connectivity tables to become global
95  BOOST_CHECK_NO_THROW( mesh_adaptor.prepare() );
96 
97  // Pack an element and a node
98  PackedElement elem(mesh, /* entities_idx= */ 0, /* loc_elem_idx = */ 0);
99  PackedNode node(mesh, /* dictionary_idx= */ 0, /* loc_node_idx = */ 0);
100 
101  // Load the element and node into a buffer
102  buf << elem << node;
103 
104  // Remove the element and node from the mesh (not applied until finish() is called)
105  BOOST_CHECK_NO_THROW( mesh_adaptor.remove_element(elem) );
106  BOOST_CHECK_NO_THROW( mesh_adaptor.remove_node(node) );
107 
108  // Unload the same element and node from the buffer
109  buf >> unpacked_elem >> unpacked_node;
110 
111  // Add the same element and node back into the mesh (not applied until finish() is called)
112  BOOST_CHECK_NO_THROW( mesh_adaptor.add_element(unpacked_elem) );
113  BOOST_CHECK_NO_THROW( mesh_adaptor.add_node(unpacked_node) );
114 
115  // Finish the mesh-adaptor, applying all changes (in this case the changes cancel out),
116  // and restore the element-node connectivity tables to become local
117  BOOST_CHECK_NO_THROW( mesh_adaptor.finish() );
118 }
119 
121 
122 BOOST_AUTO_TEST_CASE( test_move_elements )
123 {
124  // Generate a simple 1D line-mesh of 10 cells
125  boost::shared_ptr< MeshGenerator > meshgenerator = build_component_abstract_type<MeshGenerator>("cf3.mesh.SimpleMeshGenerator","1Dgenerator");
126  meshgenerator->options().set("mesh",URI("//line3"));
127  meshgenerator->options().set("nb_cells",std::vector<Uint>(1,10));
128  meshgenerator->options().set("lengths",std::vector<Real>(1,10.));
129  Mesh& mesh = meshgenerator->generate();
130 
131  // Create a MeshAdaptor object to manipulate the elements
132  MeshAdaptor mesh_adaptor(mesh);
133 
134  // Allocations (not important)
135  PE::Buffer buf;
136  PackedElement unpacked_elem(mesh);
137  PackedNode unpacked_node(mesh);
138 
139  // Prepare the mesh-adaptor, rebuilding element-node connectivity tables to become global
140 
141 
142  BOOST_CHECK_EQUAL(mesh.elements().size(), 3u);
143 
144  std::vector< std::vector<std::vector<Uint> > > change_set(PE::Comm::instance().size(),
145  std::vector<std::vector<Uint> >(mesh.elements().size()));
146 
147  if (PE::Comm::instance().size() >= 2)
148  {
149 
150  switch (PE::Comm::instance().rank())
151  {
152  case 0:
153 // BOOST_CHECK(change_set.size() == PE::Comm::instance().size());
154  change_set[1][0].push_back(4);
155  break;
156  case 1:
157  change_set[0][0].push_back(4);
158  break;
159  }
160 }
161  BOOST_CHECK(true);
162 
163  BOOST_CHECK_NO_THROW( mesh_adaptor.prepare() );
164 
165  BOOST_CHECK_NO_THROW(mesh_adaptor.move_elements(change_set));
166 
167  // Finish the mesh-adaptor, applying all changes (in this case the changes cancel out),
168  // and restore the element-node connectivity tables to become local
169  BOOST_CHECK_NO_THROW( mesh_adaptor.finish() );
170 }
171 
172 
174 
175 BOOST_AUTO_TEST_CASE( test_element_node_connectivity_rebuilding )
176 {
177 
178  // Generate a simple 1D line-mesh of 10 cells
179  boost::shared_ptr< MeshGenerator > meshgenerator = build_component_abstract_type<MeshGenerator>("cf3.mesh.SimpleMeshGenerator","1Dgenerator");
180  meshgenerator->options().set("mesh",URI("//line"));
181  meshgenerator->options().set("nb_cells",std::vector<Uint>(1,10));
182  meshgenerator->options().set("lengths",std::vector<Real>(1,10.));
183  Mesh& mesh = meshgenerator->generate();
185 
186  // Create a MeshAdaptor object to manipulate the elements
187  MeshAdaptor mesh_adaptor(mesh);
188  mesh_adaptor.create_element_buffers();
189 
190  // Remove an element
191  mesh_adaptor.remove_element(0,1);
192  mesh_adaptor.flush_elements();
193 
194  if (PE::Comm::instance().size() == 2)
195  {
196  BOOST_CHECK_EQUAL(mesh.elements()[0]->size(),4u);
197  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][0], 0u);
198  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][1], 1u);
199  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][0], 4u);
200  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][1], 5u);
201  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][0], 2u);
202  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][1], 3u);
203  }
204 
205  // Make all element-node connectivities use global node indices
206  BOOST_CHECK_NO_THROW(mesh_adaptor.make_element_node_connectivity_global());
207 
208  if (PE::Comm::instance().size() == 2)
209  {
210  switch (PE::Comm::instance().rank())
211  {
212  case 0:
213  BOOST_CHECK_EQUAL(mesh.elements()[0]->size(),4u);
214  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][0], 0u);
215  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][1], 1u);
216  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][0], 4u);
217  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][1], 5u);
218  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][0], 2u);
219  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][1], 3u);
220  break;
221  case 1:
222  BOOST_CHECK_EQUAL(mesh.elements()[0]->size(),4u);
223  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][0], 5u);
224  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][1], 6u);
225  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][0], 9u);
226  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][1], 10u);
227  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][0], 7u);
228  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][1], 8u);
229  break;
230  }
231  }
232 
233  BOOST_CHECK(true);
234 
235  // entities_idx: index as it appears in mesh.elements() vector; can be found through mesh.find_elements_idx()
236  const Uint entities_idx = mesh.access_component_checked("topology/interior/Line")->handle<Entities>()->entities_idx();
237  BOOST_CHECK(true);
238  BOOST_CHECK_EQUAL(entities_idx , 0u);
239 
240  const Uint elem_idx = 1u; // index local to entities component
241  BOOST_CHECK(true);
242 
243  PackedElement packed_elem(mesh,entities_idx,elem_idx);
244 
245  BOOST_CHECK(true);
246 
247  // dict_idx: index as it appears in mesh.dictionaries() vector; can be found through mesh.find_dictionary_idx()
248  const Uint dict_idx = 0u;//mesh.find_dictionary_idx(mesh.geometry_fields().handle<Dictionary>() );
249  const Uint node_idx = 2u;
250  PackedNode packed_node(mesh,dict_idx,node_idx);
251 
252  BOOST_CHECK(true);
253  PE::Buffer buf;
254 
255  buf << packed_elem;
256  buf << packed_node;
257 
258  BOOST_CHECK(true);
259 
260  PackedElement unpacked_elem(mesh);
261  PackedNode unpacked_node(mesh);
262 
263  buf >> unpacked_elem;
264  buf >> unpacked_node;
265 
266  BOOST_CHECK(true);
267 
268  BOOST_CHECK_EQUAL(unpacked_node.loc_idx(), packed_node.loc_idx());
269  BOOST_CHECK_EQUAL(unpacked_node.glb_idx(), packed_node.glb_idx());
270  BOOST_CHECK_EQUAL(unpacked_node.rank(), packed_node.rank());
271  BOOST_CHECK(unpacked_node.field_values() == packed_node.field_values());
272 
273  // Restore the node-connectivity to normal
274  BOOST_CHECK_NO_THROW(mesh_adaptor.restore_element_node_connectivity());
275 
276  if (PE::Comm::instance().size() == 2)
277  {
278  BOOST_CHECK_EQUAL(mesh.elements()[0]->size(),4u);
279  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][0], 0u);
280  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[0][1], 1u);
281  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][0], 4u);
282  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[1][1], 5u);
283  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][0], 2u);
284  BOOST_CHECK_EQUAL(mesh.elements()[0]->geometry_space().connectivity()[2][1], 3u);
285  }
286 
287 }
288 
290 
291 BOOST_AUTO_TEST_CASE( finalize_mpi )
292 {
293  PE::Comm::instance().finalize();
294 }
295 
297 
298 BOOST_AUTO_TEST_SUITE_END()
299 
300 
~MeshManipulationsTests_Fixture()
common tear-down for each test case
const std::vector< Handle< Entities > > & elements() const
Definition: Mesh.hpp:70
external boost library namespace
void move_elements(const std::vector< std::vector< std::vector< Uint > > > &exported_elements_loc_id)
Move elements and attached nodes between processors, according to an elements_changeset.
void add_element(const PackedElement &packed_element)
Add element to the mesh.
int m_argc
possibly common functions used on the tests below
void remove_element(const PackedElement &packed_element)
Remove element from the mesh.
Class that contains all stand-alone global information of an element.
MeshManipulationsTests_Fixture()
common setup for each test case
STL namespace.
void make_element_node_connectivity_global()
Element-node connectivity is replaced with global indices.
void flush_elements()
Apply all changes to elements.
void remove_node(const PackedNode &packed_node)
Remove node from the mesh.
void restore_element_node_connectivity()
Element-node connectivity is restored with local indices.
Class that contains all stand-alone global information of point in a dictionary.
Buffer that can hold multiple data types, useful for MPI communication.
Definition: Buffer.hpp:34
Basic Classes for Mesh applications used by COOLFluiD.
Class to adapt the mesh.
Definition: MeshAdaptor.hpp:45
Top-level namespace for coolfluid.
Definition: Action.cpp:18
void finish()
Apply the changes the mesh adaptor for changes and fix inconsistent state.
BOOST_AUTO_TEST_CASE(init_mpi)
void create_element_buffers()
Creates buffers for element changes.
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
void prepare()
Prepare the mesh adaptor for changes.
void add_node(const PackedNode &packed_node)
Add node from the mesh.
Dictionary & geometry_fields() const
Definition: Mesh.cpp:339
Most basic kernel library.
Definition: Action.cpp:19
Handle< Component > access_component_checked(const URI &path)
Definition: Component.cpp:550
Send comments to:
COOLFluiD Web Admin