7 #define BOOST_TEST_DYN_LINK
8 #define BOOST_TEST_MODULE "Test module for parallel fields"
13 #include <boost/test/unit_test.hpp>
48 using namespace boost;
56 std::ostream& operator<< (std::ostream& out , const std::vector<T>&
v)
58 for (
Uint i=0; i<
v.size()-1; ++i)
67 std::vector<int> send_strides(send.size());
68 std::vector<int> send_displs(send.size());
69 for (
Uint i=0; i<send.size(); ++i)
70 send_strides[i] = send[i].size();
72 if (send.size()) send_displs[0] = 0;
73 for (
Uint i=1; i<send.size(); ++i)
74 send_displs[i] = send_displs[i-1] + send_strides[i-1];
78 send_linear.
reserve(send_displs.back()+send_strides.back());
79 for (
Uint i=0; i<send.size(); ++i)
80 send_linear.
pack(send[i].begin(),send[i].size());
82 std::vector<int> recv_strides(PE::Comm::instance().size());
83 std::vector<int> recv_displs(PE::Comm::instance().size());
84 PE::Comm::instance().all_to_all(send_strides,recv_strides);
85 if (recv_displs.size()) recv_displs[0] = 0;
86 for (
Uint i=1; i<PE::Comm::instance().size(); ++i)
87 recv_displs[i] = recv_displs[i-1] + recv_strides[i-1];
89 recv.
resize(recv_displs.back()+recv_strides.back());
90 MPI_CHECK_RESULT(MPI_Alltoallv, ((
void*)send_linear.
begin(), &send_strides[0], &send_displs[0], MPI_PACKED, (
void*)recv.
begin(), &recv_strides[0], &recv_displs[0], MPI_PACKED, PE::Comm::instance().communicator()));
97 std::vector<int> send_displs(send_strides.size());
98 if (send_strides.size()) send_displs[0] = 0;
99 for (
Uint i=1; i<send_strides.size(); ++i)
100 send_displs[i] = send_displs[i-1] + send_strides[i-1];
102 recv_strides.resize(PE::Comm::instance().size());
103 std::vector<int> recv_displs(PE::Comm::instance().size());
104 PE::Comm::instance().all_to_all(send_strides,recv_strides);
105 if (recv_displs.size()) recv_displs[0] = 0;
106 for (
Uint i=1; i<PE::Comm::instance().size(); ++i)
107 recv_displs[i] = recv_displs[i-1] + recv_strides[i-1];
109 recv.
resize(recv_displs.back()+recv_strides.back());
110 MPI_CHECK_RESULT(MPI_Alltoallv, ((
void*)send.
begin(), &send_strides[0], &send_displs[0], MPI_PACKED, (
void*)recv.
begin(), &recv_strides[0], &recv_displs[0], MPI_PACKED, PE::Comm::instance().communicator()));
117 std::map<Uint,Uint> glb_node_2_loc_node;
118 std::map<Uint,Uint>::iterator glb_node_not_found = glb_node_2_loc_node.end();
121 if ( glb_node_2_loc_node.find(nodes.
glb_idx()[
n]) == glb_node_not_found )
123 glb_node_2_loc_node[nodes.
glb_idx()[
n]] =
n;
127 std::cout <<
PERank <<
"glb idx " << nodes.
glb_idx()[
n] <<
" already exists... ("<<
n<<
"<-->"<<glb_node_2_loc_node[nodes.
glb_idx()[
n]] <<
")" << std::endl;
146 if (node >=max_node_idx)
148 std::cout <<
PERank <<
"element " <<
e <<
" has node out of range : " << node <<
" >= " << max_node_idx << std::endl;
162 std::map<Uint,Uint> glb_elem_2_loc_elem;
163 std::map<Uint,Uint>::iterator glb_elem_not_found = glb_elem_2_loc_elem.end();
166 if ( glb_elem_2_loc_elem.find(entities.
glb_idx()[
e]) == glb_elem_not_found )
168 glb_elem_2_loc_elem[entities.
glb_idx()[
e]] =
e;
172 std::cout <<
PERank <<
"glb elem idx " << entities.
glb_idx()[
e] <<
" already exists... ("<<
e<<
"<-->"<<glb_elem_2_loc_elem[entities.
glb_idx()[
e]] <<
")" << std::endl;
188 m_argc = boost::unit_test::framework::master_test_suite().argc;
189 m_argv = boost::unit_test::framework::master_test_suite().argv;
212 Core::instance().initiate(m_argc,m_argv);
213 PE::Comm::instance().init(m_argc,m_argv);
221 Core::instance().environment().options().set(
"log_level",(
Uint)
DEBUG);
229 boost::shared_ptr< MeshGenerator > meshgenerator = build_component_abstract_type<MeshGenerator>(
"cf3.mesh.SimpleMeshGenerator",
"1Dgenerator");
230 meshgenerator->options().set(
"mesh",
URI(
"//rect"));
231 std::vector<Uint> nb_cells(2);
232 std::vector<Real> lengths(2);
235 lengths[0] = nb_cells[0];
236 lengths[1] = nb_cells[1];
237 meshgenerator->options().set(
"nb_cells",nb_cells);
238 meshgenerator->options().set(
"lengths",lengths);
239 meshgenerator->options().set(
"bdry",
true);
240 Mesh&
mesh = meshgenerator->generate();
244 boost::shared_ptr< MeshReader > meshreader =
245 build_component_abstract_type<MeshReader>(
"cf3.mesh.neu.Reader",
"meshreader");
247 boost::shared_ptr< Mesh > mesh_ptr = meshreader->create_mesh_from(
"rotation-tg-p1.neu");
249 Mesh& mesh = *mesh_ptr;
250 Core::instance().
root().add_component(mesh_ptr);
254 boost::shared_ptr< MeshReader > meshreader =
255 build_component_abstract_type<MeshReader>(
"cf3.mesh.gmsh.Reader",
"meshreader");
256 boost::shared_ptr< Mesh > mesh_ptr = meshreader->create_mesh_from(
"../../resources/sinusbump-tg-p1.msh");
259 Mesh& mesh = *mesh_ptr;
260 Core::instance().
root().add_component(mesh_ptr);
265 boost::shared_ptr< MeshWriter > tec_writer =
266 build_component_abstract_type<MeshWriter>(
"cf3.mesh.tecplot.Writer",
"tec_writer");
268 boost::shared_ptr< MeshWriter > gmsh_writer =
269 build_component_abstract_type<MeshWriter>(
"cf3.mesh.gmsh.Writer",
"gmsh_writer");
272 tec_writer->write_from_to(mesh,
"parallel_overlap_before"+tec_writer->get_extensions()[0]);
273 CFinfo <<
"parallel_overlap_before_P*"+tec_writer->get_extensions()[0]+
" written" <<
CFendl;
275 gmsh_writer->write_from_to(mesh,
"parallel_overlap_before"+gmsh_writer->get_extensions()[0]);
276 CFinfo <<
"parallel_overlap_before_P*"+gmsh_writer->get_extensions()[0]+
" written" <<
CFendl;
280 boost::shared_ptr< MeshTransformer > glb_numbering = build_component_abstract_type<MeshTransformer>(
"cf3.mesh.actions.GlobalNumbering",
"glb_numbering");
282 glb_numbering->transform(mesh);
286 build_component_abstract_type<MeshTransformer>(
"cf3.mesh.actions.GlobalConnectivity",
"glb_node_elem_connectivity")->transform(mesh);
290 boost::shared_ptr< MeshPartitioner > partitioner_ptr = boost::dynamic_pointer_cast<
MeshPartitioner>(build_component_abstract_type<MeshTransformer>(
"cf3.mesh.zoltan.Partitioner",
"partitioner"));
291 MeshPartitioner&
p = *partitioner_ptr;
292 p.
options().
set(
"graph_package", std::string(
"PHG"));
309 BOOST_CHECK_EQUAL(mesh.
dictionaries()[1]->name() , mesh::Tags::geometry());
311 BOOST_CHECK_EQUAL(mesh.
elements().size(),5u);
349 std::vector<URI> fields_to_output;
350 fields_to_output.push_back(glb_node.
uri());
351 fields_to_output.push_back(glb_elem.
uri());
352 fields_to_output.push_back(elem_rank.
uri());
353 fields_to_output.push_back(P2coords.
uri());
355 tec_writer->options().set(
"fields",fields_to_output);
356 tec_writer->options().set(
"enable_overlap",
true);
357 tec_writer->options().set(
"mesh",mesh.
handle<
Mesh>());
358 tec_writer->options().set(
"file",
URI(
"parallel_overlap"+tec_writer->get_extensions()[0]));
359 tec_writer->execute();
360 CFinfo <<
"parallel_overlap_P*"+tec_writer->get_extensions()[0]+
" written" <<
CFendl;
362 gmsh_writer->options().set(
"fields",fields_to_output);
363 gmsh_writer->options().set(
"enable_overlap",
true);
364 gmsh_writer->options().set(
"mesh",mesh.
handle<
Mesh>());
365 gmsh_writer->options().set(
"file",
URI(
"parallel_overlap"+gmsh_writer->get_extensions()[0]));
366 gmsh_writer->execute();
367 CFinfo <<
"parallel_overlap_P*"+gmsh_writer->get_extensions()[0]+
" written" <<
CFendl;
372 PE::Comm::instance().finalize();
373 Core::instance().terminate();
378 BOOST_AUTO_TEST_SUITE_END()
void reserve(const Uint size)
reserve the buffer to fit memory "size". The buffer gets allocated bigger than necessary in order to ...
#define CFinfo
these are always defined
Field & create_field(const std::string &name, const Uint cols)
Create a new field in this group.
virtual void partition_graph()=0
Uint recursive_elements_count(bool include_ghost_elems) const
void my_all_to_all(const std::vector< PE::Buffer > &send, PE::Buffer &recv)
Safe pointer to an object. This is the supported method for referring to components.
Dictionary & create_discontinuous_space(const std::string &space_name, const std::string &space_lib_name, const std::vector< Handle< Entities > > &entities)
const std::vector< Handle< Entities > > & elements() const
external boost library namespace
Space & geometry_space() const
Parallel Communication Pattern. This class provides functionality to collect communication. For efficiency it works such a way that you submit your request via the constructor or the add/remove/move magic triangle and then call setup to modify the commpattern. The data needed to be kept synchronous can be registered via the insert function. The word node here means any kind of "point of storage", in this context it is not directly related with the computational mesh.
ConstElementsRange elements_range() const
void initialize(Mesh &mesh)
~ParallelOverlapTests_Fixture()
common tear-down for each test case
URI uri() const
Construct the full path.
#define boost_foreach
lowercase version of BOOST_FOREACH
const Field & coordinates() const
common::List< Uint > & rank()
Entities & support() const
Access the geometric support.
Real e()
Definition of the Unit charge [C].
boost::proto::terminal< SFOp< NodesOp > >::type const nodes
Dictionary & geometry_fields() const
Const access to the coordinates.
Static functions for mathematical constants.
const std::vector< Handle< Space > > & spaces() const
Handle< Component const > root() const
void reset()
reset the buffer, without resizing
Uint size() const
return the number of elements
Buffer that can hold multiple data types, useful for MPI communication.
void resize(const Uint size)
resize the buffer to fit memory "size". The buffer gets resized bigger than necessary in order to red...
common::List< Uint > & glb_idx()
Mutable access to the list of nodes.
Basic Classes for Mesh applications used by COOLFluiD.
void pack(const T *data, const Uint data_size)
Pack data in the buffer. The data must be POD (plain old data).
Top-level namespace for coolfluid.
common::List< Uint > & glb_idx()
Return the global index of every field row.
bool check_nodes_sanity(Dictionary &nodes)
void finish()
Apply the changes the mesh adaptor for changes and fix inconsistent state.
int m_argc
possibly common functions used on the tests below
unsigned int Uint
typedef for unsigned int
void migrate()
Migrate the elements and nodes to corresponding processors.
Classes offering a MPI interface for COOLFluiD.
void prepare()
Prepare the mesh adaptor for changes.
bool check_elements_sanity(Entities &entities)
const iterator begin() const
begin iterator
Region & topology() const
Handle< Component > handle()
Get a handle to the component.
BOOST_AUTO_TEST_CASE(init_mpi)
#define MPI_CHECK_RESULT(MPIFunc, Args)
Macro for checking return values of any mpi calls and throws exception on error.
bool check_element_nodes_sanity(Mesh &mesh)
void grow_overlap()
Create an additional cell-layer of overlap between pid's.
Dictionary & geometry_fields() const
ParallelOverlapTests_Fixture()
common setup for each test case
void set(const std::string &pname, const boost::any &val)
MPI communication buffer for mixed data types.
Uint size() const
Number of rows of contained fields.
Uint size() const
The number of elements defined in this space.
Most basic kernel library.
Connectivity & connectivity()
connectivity table to dictionary entries
const std::vector< Handle< Dictionary > > & dictionaries() const