COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
ptest-proto-parallel.cpp
Go to the documentation of this file.
1 // Copyright (C) 2010-2011 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 benchmarking proto operators"
9 
10 #include <boost/foreach.hpp>
11 #include <boost/lexical_cast.hpp>
12 #include <boost/test/unit_test.hpp>
13 
14 #include "common/Core.hpp"
15 #include "common/Log.hpp"
16 
17 #include "common/PE/all_reduce.hpp"
18 #include "common/PE/debug.hpp"
19 #include "common/PE/Comm.hpp"
20 
21 #include "math/MatrixTypes.hpp"
22 
23 #include "mesh/Domain.hpp"
24 #include "mesh/Mesh.hpp"
25 #include "mesh/MeshTransformer.hpp"
26 #include "mesh/Region.hpp"
27 #include "mesh/Elements.hpp"
28 #include "mesh/MeshWriter.hpp"
29 #include "mesh/ElementData.hpp"
30 #include "mesh/FieldManager.hpp"
31 #include "mesh/Dictionary.hpp"
32 
34 #include "mesh/LagrangeP0/Hexa.hpp"
36 
38 
39 #include "physics/PhysModel.hpp"
40 
41 #include "solver/Model.hpp"
42 #include "solver/Solver.hpp"
43 #include "solver/Tags.hpp"
44 
47 
54 
58 
59 using namespace cf3;
60 using namespace cf3::solver;
61 using namespace cf3::solver::actions;
62 using namespace cf3::solver::actions::Proto;
63 using namespace cf3::mesh;
64 using namespace cf3::common;
65 
67 
69  //public Tools::Testing::ProfiledTestFixture,
71 {
73  root(Core::instance().root()),
74  length(12.),
75  half_height(0.5),
76  width(6.)
77  {
78  int argc = boost::unit_test::framework::master_test_suite().argc;
79  char** argv = boost::unit_test::framework::master_test_suite().argv;
80  cf3_assert(argc == 4);
81  x_segs = boost::lexical_cast<Uint>(argv[1]);
82  y_segs = boost::lexical_cast<Uint>(argv[2]);
83  z_segs = boost::lexical_cast<Uint>(argv[3]);
84  }
85 
86  // Setup a model under root
87  Model& setup(const std::string& model_name)
88  {
89  Model& model = *Core::instance().root().create_component<Model>(model_name);
90  physics::PhysModel& phys_model = model.create_physics("cf3.physics.DynamicModel");
91  Domain& dom = model.create_domain("Domain");
92  Solver& solver = model.create_solver("cf3.solver.SimpleSolver");
93 
94  Mesh& mesh = *dom.create_component<Mesh>("mesh");
95 
96  const Real ratio = 0.1;
97 
99  Tools::MeshGeneration::create_channel_3d(blocks, length, half_height, width, x_segs, y_segs/2, z_segs, ratio);
100  blocks.partition_blocks(PE::Comm::instance().size(), XX);
101  blocks.options().set("overlap", 0u);
102  blocks.create_mesh(mesh);
103 
104  // Set up variables
105  phys_model.variable_manager().create_descriptor("variables", "CellVolume, CellRank");
106 
107  // Create field
108  mesh.create_discontinuous_space("elems_P0","cf3.mesh.LagrangeP0");
109 
110  return model;
111  }
112 
114  const Real length;
115  const Real half_height;
116  const Real width;
117  typedef boost::mpl::vector2<LagrangeP1::Hexa3D, LagrangeP0::Hexa> ElementsT;
118 
122 };
123 
124 
125 BOOST_AUTO_TEST_SUITE( ProtoParallelSuite )
126 
127 
129 BOOST_AUTO_TEST_CASE( Initialize )
130 {
131  PE::Comm::instance().init(boost::unit_test::framework::master_test_suite().argc, boost::unit_test::framework::master_test_suite().argv);
132  //common::PE::wait_for_debugger(1);
133 }
134 
136 {
137  const Real rank = static_cast<Real>(PE::Comm::instance().rank());
138 
139  Model& model = setup("NoOverlap");
140  Mesh& mesh = *model.domain().get_child("mesh")->handle<Mesh>();
141  Dictionary& elems_P0 = mesh.create_discontinuous_space("elems_P0","cf3.mesh.LagrangeP0");
142  model.solver().field_manager().create_field("variables", elems_P0);
143 
144  FieldVariable<0, ScalarField> V("CellVolume", "variables");
145  FieldVariable<1, ScalarField> R("CellRank", "variables");
146 
147  model.solver()
149  (
150  "ComputeVolumeAndRank",
152  (
153  ElementsT(),
154  group
155  (
156  V = volume,
157  R = rank
158  )
159  )
160  );
161 
162  std::vector<URI> root_regions;
163  root_regions.push_back(mesh.topology().uri());
164  model.solver().configure_option_recursively(solver::Tags::regions(), root_regions);
165 }
166 
168 
170 {
171  root.get_child("NoOverlap")->handle<Model>()->simulate();
172 }
173 
175 
177 {
178  Model& model = setup("Overlap");
179  Mesh& mesh = *model.domain().get_child("mesh")->handle<Mesh>();
180 
181  const Real rank = static_cast<Real>(PE::Comm::instance().rank());
182 
183  FieldVariable<0, ScalarField> V("CellVolume", "variables");
184  FieldVariable<1, ScalarField> R("CellRank", "variables");
185 
186  model.solver()
188  (
189  "ComputeVolumeAndRank",
191  (
192  ElementsT(),
193  group
194  (
195  V = volume,
196  R = rank
197  )
198  )
199  );
200 
201  std::vector<URI> root_regions;
202  root_regions.push_back(mesh.topology().uri());
203  model.solver().configure_option_recursively(solver::Tags::regions(), root_regions);
204 }
205 
207 {
208  Model& model = *root.get_child("Overlap")->handle<Model>();
209  Mesh& mesh = *model.domain().get_child("mesh")->handle<Mesh>();
210 
211  MeshTransformer& global_conn = *model.domain().create_component("GlobalConnectivity", "cf3.mesh.actions.GlobalConnectivity")->handle<MeshTransformer>();
212  global_conn.transform(mesh);
213 }
214 
216 {
217  Model& model = *root.get_child("Overlap")->handle<Model>();
218  Mesh& mesh = *model.domain().get_child("mesh")->handle<Mesh>();
219 
220  MeshTransformer& grow_overlap = *model.domain().create_component("GrowOverlap", "cf3.mesh.actions.GrowOverlap")->handle<MeshTransformer>();
221  grow_overlap.transform(mesh);
222 }
223 
225 {
226  Model& model = *root.get_child("Overlap")->handle<Model>();
227  Mesh& mesh = *model.domain().get_child("mesh")->handle<Mesh>();
228 
229  Dictionary& elems_P0 = mesh.create_discontinuous_space("elems_P0","cf3.mesh.LagrangeP0");
230  model.solver().field_manager().create_field("variables", elems_P0);
231 }
232 
234 
236 {
237  root.get_child("Overlap")->handle<Model>()->simulate();
238 }
239 
241 
242 // Check the volume results
244 {
245  FieldVariable<0, ScalarField> V("CellVolume", "variables");
246 
247  const Real wanted_volume = width*length*half_height*2.;
248 
249  Mesh& mesh = find_component_recursively_with_name<Mesh>(*root.get_child("NoOverlap"), "mesh");
250  std::cout << "Checking volume for mesh " << mesh.uri().path() << std::endl;
251  Real vol_check = 0;
252  for_each_element< ElementsT >(mesh.topology(), vol_check += V);
253 
254  if(PE::Comm::instance().is_active())
255  {
256  Real total_volume_check;
257  PE::all_reduce(PE::Comm::instance().communicator(), PE::plus(), &vol_check, 1, &total_volume_check);
258  BOOST_CHECK_CLOSE(total_volume_check, wanted_volume, 1e-6);
259  }
260 
261  MeshWriter& writer = *root.create_component("Writer", "cf3.mesh.VTKXML.Writer")->handle<MeshWriter>();
262  std::vector<URI> fields;
263  fields.push_back(find_component_ptr_recursively_with_name<Field>(mesh, "variables")->uri());
264  writer.options().set("mesh",mesh.handle<Mesh>());
265  writer.options().set("fields",fields);
266  writer.options().set("file",URI("utest-proto-parallel_output-" + mesh.parent()->parent()->name() + ".pvtu"));
267  writer.execute();
268 }
269 
270 // Check the volume results
272 {
273  const Uint nb_procs = PE::Comm::instance().size();
274  FieldVariable<0, ScalarField> V("CellVolume", "variables");
275 
276  const Real wanted_volume = width*length*half_height*2.;
277  std::cout << "wanted_volume: " << wanted_volume << ", nb_procs: " << nb_procs << ", x_segs: " << x_segs << std::endl;
278  const Real wanted_volume_overlap = wanted_volume + (nb_procs-1)*2.*wanted_volume/x_segs;
279 
280  Mesh& mesh = find_component_recursively_with_name<Mesh>(*root.get_child("Overlap"), "mesh");
281  Real vol_check = 0;
282  for_each_element< ElementsT >(mesh.topology(), vol_check += V);
283 
284  if(PE::Comm::instance().is_active())
285  {
286  Real total_volume_check;
287  PE::all_reduce(PE::Comm::instance().communicator(), PE::plus(), &vol_check, 1, &total_volume_check);
288  BOOST_CHECK_CLOSE(total_volume_check, wanted_volume_overlap, 1e-6);
289  }
290 
291  MeshWriter& writer = *root.create_component("Writer", "cf3.mesh.VTKXML.Writer")->handle<MeshWriter>();
292  std::vector<URI> fields;
293  fields.push_back(find_component_ptr_recursively_with_name<Field>(mesh, "variables")->uri());
294  writer.options().set("fields",fields);
295  writer.options().set("mesh",mesh.handle<Mesh>());
296  writer.options().set("file",URI("utest-proto-parallel_output-" + mesh.parent()->parent()->name() + ".pvtu"));
297  writer.execute();
298 }
299 
300 
302 
303 BOOST_AUTO_TEST_SUITE_END()
304 
305 
virtual void execute()
execute the action
Definition: MeshWriter.cpp:151
virtual mesh::Domain & create_domain(const std::string &name)
creates a domain in this model
Definition: Model.cpp:201
Dictionary & create_discontinuous_space(const std::string &space_name, const std::string &space_lib_name, const std::vector< Handle< Entities > > &entities)
Definition: Mesh.cpp:316
virtual physics::PhysModel & create_physics(const std::string &builder)
Definition: Model.cpp:182
Real R()
Definition of the ideal gas constant [J/mol K].
Definition: Consts.hpp:36
void configure_option_recursively(const std::string &optname, const boost::any &val)
Definition: Component.cpp:1157
virtual void transform(Handle< Mesh > mesh)
boost::proto::terminal< SFOp< VolumeOp > >::type const volume
Static terminals that can be used in proto expressions.
std::string path() const
Definition: URI.cpp:253
mesh::FieldManager & field_manager()
Access to the FieldManager, which is a static subcomponent of Solver.
Definition: Solver.cpp:115
virtual Solver & solver()
gets the solver from this model
Definition: Model.cpp:168
#define cf3_assert(a)
Definition: Assertions.hpp:93
Basic Classes for Solver applications used by CF.
Definition: Action.cpp:29
URI uri() const
Construct the full path.
Definition: Component.cpp:248
common::URI uri(ComponentWrapper &self)
tuple root
Definition: coolfluid.py:24
boost::shared_ptr< ElementsExpression< ExprT, ElementTypes > > elements_expression(ElementTypes, const ExprT &expr)
Definition: Expression.hpp:292
Any test using this fixture (or a derivative) will be timed.
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
void partition_blocks(const Uint nb_partitions, const Uint direction)
Definition: BlockData.cpp:1495
Definition: Defs.hpp:17
Model & setup(const std::string &model_name)
virtual mesh::Domain & domain()
gets the domain from this model
Definition: Model.cpp:161
virtual Solver & create_solver(const std::string &builder)
Definition: Model.cpp:211
Handle< Component > parent() const
Definition: Component.cpp:256
Basic Classes for Mesh applications used by COOLFluiD.
tuple model
Global confifuration.
Handle< Component > get_child(const std::string &name)
Definition: Component.cpp:441
BOOST_AUTO_TEST_CASE(Initialize)
Top-level namespace for coolfluid.
Definition: Action.cpp:18
void create_channel_3d(BlockArrays &blocks, const Real length, const Real half_height, const Real width, const Uint x_segs, const Uint y_segs_half, const Uint z_segs, const Real ratio)
boost::mpl::vector2< LagrangeP1::Hexa3D, LagrangeP0::Hexa > ElementsT
std::vector< URI > fields
common::Component & root() const
Gives the default root component.
Definition: Core.cpp:145
static boost::proto::terminal< ExpressionGroupTag >::type group
Use group(expr1, expr2, ..., exprN) to evaluate a group of expressions.
T * all_reduce(const Communicator &comm, const Op &op, const T *in_values, const int in_n, T *out_values, const int stride=1)
Definition: all_reduce.hpp:117
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
BOOST_FIXTURE_TEST_CASE(SetupNoOverlap, ProtoParallelFixture)
boost::shared_ptr< ProtoAction > create_proto_action(const std::string &name, const boost::shared_ptr< Expression > &expression)
Create a new ProtoAction, immediatly setting the expression.
Region & topology() const
Definition: Mesh.hpp:51
static Core & instance()
Definition: Core.cpp:37
Handle< Component > handle()
Get a handle to the component.
Definition: Component.hpp:179
void create_field(const std::string &tag, cf3::mesh::Dictionary &dict)
Create fields. Looks up the VariablesDescriptor with the given tag, and creates a field with the same...
OptionList & options()
Definition: Component.cpp:856
Base class for defining CF components.
Definition: Component.hpp:82
void set(const std::string &pname, const boost::any &val)
Definition: OptionList.cpp:132
Handle< Component > create_component(const std::string &name, const std::string &builder)
Build a (sub)component of this component using the extended type_name of the component.
Definition: Component.cpp:568
Most basic kernel library.
Definition: Action.cpp:19
Send comments to:
COOLFluiD Web Admin