COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
ptest-proto-benchmark.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 "math/MatrixTypes.hpp"
18 
19 #include "mesh/Domain.hpp"
20 #include "mesh/Mesh.hpp"
21 #include "mesh/Region.hpp"
22 #include "mesh/Elements.hpp"
23 #include "mesh/MeshWriter.hpp"
24 #include "mesh/ElementData.hpp"
25 #include "mesh/FieldManager.hpp"
26 #include "mesh/Dictionary.hpp"
27 
29 #include "mesh/LagrangeP0/Hexa.hpp"
30 
32 
33 #include "physics/PhysModel.hpp"
34 
35 #include "solver/Model.hpp"
36 #include "solver/Solver.hpp"
37 #include "solver/Tags.hpp"
38 
41 
48 
52 
53 using namespace cf3;
54 using namespace cf3::solver;
55 using namespace cf3::solver::actions;
56 using namespace cf3::solver::actions::Proto;
57 using namespace cf3::mesh;
58 using namespace cf3::common;
59 
61 
65 {
67  root(Core::instance().root()),
68  length(12.),
69  half_height(0.5),
70  width(6.)
71  {
72  }
73 
74  // Setup a model under root
75  Model& setup(const std::string& model_name)
76  {
77  int argc = boost::unit_test::framework::master_test_suite().argc;
78  char** argv = boost::unit_test::framework::master_test_suite().argv;
79 
80  cf3_assert(argc == 4);
81  const Uint x_segs = boost::lexical_cast<Uint>(argv[1]);
82  const Uint y_segs = boost::lexical_cast<Uint>(argv[2]);
83  const Uint z_segs = boost::lexical_cast<Uint>(argv[3]);
84 
85  Model& model = *Core::instance().root().create_component<Model>(model_name);
86  physics::PhysModel& phys_model = model.create_physics("cf3.physics.DynamicModel");
87  Domain& dom = model.create_domain("Domain");
88  Solver& solver = model.create_solver("cf3.solver.SimpleSolver");
89 
90  Mesh& mesh = *dom.create_component<Mesh>("mesh");
91 
92  const Real ratio = 0.1;
93 
95  Tools::MeshGeneration::create_channel_3d(blocks, length, half_height, width, x_segs, y_segs/2, z_segs, ratio);
96  blocks.create_mesh(mesh);
97 
98  mesh.check_sanity();
99 
100  // Set up variables
101  phys_model.variable_manager().create_descriptor("volume", "CellVolume");
102 
103  // Create field
104  Dictionary& elems_P0 = mesh.create_discontinuous_space("elems_P0","cf3.mesh.LagrangeP0");
105  solver.field_manager().create_field("volume", elems_P0);
106 
107  return model;
108  }
109 
111  {
112  DirectArrays(const Table<Real>& p_coords, const Table<Uint>::ArrayT& p_conn, Field& p_vol_field, const Uint p_offset) :
113  coords(p_coords),
114  conn(p_conn),
115  vol_field(p_vol_field),
116  offset(p_offset)
117  {
118  }
119 
123  const Uint offset;
124  };
125 
127  const Real length;
128  const Real half_height;
129  const Real width;
130  typedef boost::mpl::vector2<LagrangeP1::Hexa3D, LagrangeP0::Hexa> ElementsT;
131 
133  static boost::shared_ptr<DirectArrays> direct_arrays;
134 };
135 
136 boost::shared_ptr<ProtoBenchmarkFixture::DirectArrays> ProtoBenchmarkFixture::direct_arrays;
137 
138 
139 BOOST_FIXTURE_TEST_SUITE( ProtoBenchmarkSuite, ProtoBenchmarkFixture )
140 
141 
143 BOOST_AUTO_TEST_CASE( SetupProto )
144 {
145  Model& model = setup("Proto");
146 
147  FieldVariable<0, ScalarField> V("CellVolume", "volume");
148 
149  model.solver() << create_proto_action("ComputeVolume", elements_expression(ElementsT(), V = volume));
150 
151  std::vector<URI> root_regions;
152  root_regions.push_back(model.domain().get_child("mesh")->handle<Mesh>()->topology().uri());
153  model.solver().configure_option_recursively(solver::Tags::regions(), root_regions);
154 }
155 
157 
158 BOOST_AUTO_TEST_CASE( SetupDirect )
159 {
160  Model& model = setup("Direct");
161  Handle<Mesh> mesh(model.domain().get_child("mesh"));
162  Elements& elements = find_component_recursively_with_filter<Elements>(mesh->topology(), IsElementsVolume());
163  Field& vol_field = find_component_recursively_with_tag<Field>(*mesh, "volume");
164 
165  direct_arrays.reset(new DirectArrays
166  (
167  mesh->geometry_fields().coordinates(),
168  elements.geometry_space().connectivity().array(),
169  vol_field,
170  vol_field.dict().space(elements).connectivity()[0][0]
171  ));
172 }
173 
175 
176 BOOST_AUTO_TEST_CASE( SetupVolumeComputer )
177 {
178  Model& model = setup("VolumeComputer");
179 
180  Loop& elem_loop = *model.solver().create_component< ForAllElements >("elem_loop");
181  model.solver() << elem_loop;
182 
183  std::vector<URI> root_regions;
184  root_regions.push_back(model.domain().get_child("mesh")->handle<Mesh>()->topology().uri());
185  model.solver().configure_option_recursively(solver::Tags::regions(), root_regions);
186 
187  Handle<Mesh> mesh(model.domain().get_child("mesh"));
188  Field& vol_field = find_component_recursively_with_tag<Field>(*mesh, "volume");
189  Elements& elements = find_component_recursively_with_filter<Elements>(mesh->topology(), IsElementsVolume());
190 
191  LoopOperation& volume_computer = elem_loop.create_loop_operation("cf3.solver.actions.ComputeVolume");
192  volume_computer.options().set("volume",vol_field.uri());
193  volume_computer.options().set("elements",elements.uri());
194 }
195 
197 
198 BOOST_AUTO_TEST_CASE( SimulateProto )
199 {
200  root.get_child("Proto")->handle<Model>()->simulate();
201 }
202 
204 
205 BOOST_AUTO_TEST_CASE( SimulateDirect )
206 {
207  const Table<Uint>::ArrayT& conn = direct_arrays->conn;
208  const Table<Real>& coords = direct_arrays->coords;
209  Field& vol_field = direct_arrays->vol_field;
210 
211  LagrangeP1::Hexa3D::NodesT nodes;
212  const Uint offset = direct_arrays->offset;
213  const Uint elems_begin = 0;
214  const Uint elems_end = conn.size();
215  for(Uint elem = elems_begin; elem != elems_end; ++elem)
216  {
217  fill(nodes, coords, conn[elem]);
218  vol_field[elem+offset][0] = LagrangeP1::Hexa3D::volume(nodes);
219  }
220 }
221 
223 
224 BOOST_AUTO_TEST_CASE( SimulateVolumeComputer )
225 {
226  root.get_child("VolumeComputer")->handle<Model>()->simulate();
227 }
228 
230 
231 // Check the volume results (uses proto)
232 BOOST_AUTO_TEST_CASE( CheckResult )
233 {
234  FieldVariable<0, ScalarField> V("CellVolume", "volume");
235 
236  const Real wanted_volume = width*length*half_height*2.;
237 
238  BOOST_FOREACH(Mesh& mesh, find_components_recursively_with_name<Mesh>(root, "mesh"))
239  {
240  std::cout << "Checking volume for mesh " << mesh.uri().path() << std::endl;
241  Real vol_check = 0;
242  for_each_element< ElementsT >(mesh.topology(), vol_check += V);
243  BOOST_CHECK_CLOSE(vol_check, wanted_volume, 1e-6);
244  }
245 }
246 
248 
249 BOOST_AUTO_TEST_SUITE_END()
250 
251 
Model & setup(const std::string &model_name)
bool check_sanity() const
Definition: Mesh.cpp:460
LoopOperation & create_loop_operation(const std::string action_provider)
Definition: Loop.cpp:35
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
void configure_option_recursively(const std::string &optname, const boost::any &val)
Definition: Component.cpp:1157
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
static boost::shared_ptr< DirectArrays > direct_arrays
Arrays used by the direct method.
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
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
boost::proto::terminal< SFOp< NodesOp > >::type const nodes
Any test using this fixture (or a derivative) will be profiled.
Uint size() const
Definition: Table.hpp:127
virtual mesh::Domain & domain()
gets the domain from this model
Definition: Model.cpp:161
boost::mpl::vector2< LagrangeP1::Hexa3D, LagrangeP0::Hexa > ElementsT
DirectArrays(const Table< Real > &p_coords, const Table< Uint >::ArrayT &p_conn, Field &p_vol_field, const Uint p_offset)
Basic Classes for Mesh applications used by COOLFluiD.
tuple model
Global confifuration.
Handle< Component > get_child(const std::string &name)
Definition: Component.cpp:441
Top-level namespace for coolfluid.
Definition: Action.cpp:18
void fill(NodeValuesT &to_fill, const common::Table< Real > &data_array, const RowT &element_row, const Uint start=0)
Fill STL-vector like per-node data storage.
Definition: ElementData.hpp:28
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)
common::Component & root() const
Gives the default root component.
Definition: Core.cpp:145
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
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
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
BOOST_AUTO_TEST_CASE(SetupProto)
Send comments to:
COOLFluiD Web Admin