COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-mesh-lagrangep1-line3d.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 the LagrangeP1 Line3D Element types"
9 
10 #include <boost/assign/list_of.hpp>
11 #include <boost/test/unit_test.hpp>
12 
13 #include "common/Log.hpp"
14 
15 #include "math/Consts.hpp"
16 
17 #include "mesh/ElementType.hpp"
18 #include "common/Table.hpp"
19 #include "mesh/ElementData.hpp"
22 
23 
24 
26 
27 using namespace boost::assign;
28 using namespace cf3;
29 using namespace cf3::common;
30 using namespace cf3::math;
31 using namespace cf3::mesh;
32 using namespace cf3::mesh::Integrators;
33 using namespace cf3::mesh::LagrangeP1;
34 using namespace cf3::Tools::Testing;
35 
37 
38 typedef Line3D ETYPE;
39 
41 {
44  LagrangeP1Line3DFixture() : mapped_coords((ETYPE::MappedCoordsT() << .2).finished()), nodes((NodesT() << 5., 7., 2.,
45  10., 3., 3.).finished())
46  {
47  }
48 
51  {
52  }
53 
55  void create_helix(Table<Real>& coordinates, Table<Uint>& connectivity, const Real radius, const Real height, const Real tours, const Uint segments)
56  {
57  const Uint dim = ETYPE::dimension;
58  const Uint nb_nodes = ETYPE::nb_nodes;
59  const Real start_angle = 0.;
60  const Real end_angle = tours*2.*Consts::pi();
61 
62  coordinates.set_row_size(dim);
63  Table<Real>::ArrayT& coord_array = coordinates.array();
64  coord_array.resize(boost::extents[segments + 1][dim]);
65 
66  connectivity.set_row_size(nb_nodes);
67  Table<Uint>::ArrayT& conn_array = connectivity.array();
68  conn_array.resize(boost::extents[segments][nb_nodes]);
69  const Real height_step = height / segments;
70  for(Uint u = 0; u != segments; ++u)
71  {
72  const Real theta = start_angle + (end_angle - start_angle) * (static_cast<Real>(u) / static_cast<Real>(segments));
73  Table<Real>::Row coord_row = coord_array[u];
74 
75  coord_row[XX] = radius * cos(theta);
76  coord_row[YY] = radius * sin(theta);
77  coord_row[ZZ] = u*height_step;
78 
79  Table<Uint>::Row nodes = conn_array[u];
80  nodes[0] = u;
81  nodes[1] = u+1;
82  }
83  Table<Real>::Row coord_row = coord_array[segments];
84  coord_row[XX] = radius * cos(end_angle);
85  coord_row[YY] = radius * sin(end_angle);
86  coord_row[ZZ] = segments * height_step;
87  }
88 
90  const NodesT nodes;
91 
92  struct ConstFunctor
93  {
94  ConstFunctor(const NodesT& node_list) : m_nodes(node_list) {}
95 
96  Real operator()() const
97  {
98  ETYPE::JacobianT jac;
99  ETYPE::compute_jacobian(mapped_coords, m_nodes, jac);
100  return jac.norm();
101  }
103  private:
104  const NodesT& m_nodes;
105  };
106 
109 
110  template<typename NodesT>
111  Real operator()(const ETYPE::MappedCoordsT& mapped_coords, const NodesT& nodes)
112  {
113  ETYPE::JacobianT jac;
114  ETYPE::compute_jacobian(mapped_coords, nodes, jac);
115  Real result = 0.;
116  for(Uint i = 0; i != ETYPE::dimension; ++i)
117  {
118  result += jac(0, i) * jac(0, i);
119  }
120  return sqrt(result);
121  }
122  };
123 
124  Real square(const Real a)
125  {
126  return a*a;
127  }
128 };
129 
131 template<typename ResultT, typename FunctorT>
132 void integrate_region(ResultT& result, FunctorT functor, const Table<Real>& coordinates, const Table<Uint>& connectivity)
133 {
134  const Uint nb_elems = connectivity.array().size();
135  for(Uint elem_idx = 0; elem_idx != nb_elems; ++ elem_idx)
136  {
138  fill(nodes, coordinates, connectivity.array()[elem_idx]);
139  integrate_element(result, functor, nodes);
140  }
141 }
142 
144 template<typename ResultT, typename FunctorT, typename NodesT>
145 void integrate_element(ResultT& result, FunctorT functor, const NodesT& nodes)
146 {
147  static const double mu = 0.;
148  static const double w = 2.;
149  static const ETYPE::MappedCoordsT mapped_coords((ETYPE::MappedCoordsT() << mu).finished());
150  result += w * functor(mapped_coords, nodes);
151 }
152 
154 
155 BOOST_FIXTURE_TEST_SUITE( LagrangeP1Line3DSuite, LagrangeP1Line3DFixture )
156 
157 
160 {
161  NodesT nodes_line3D;
162  nodes_line3D << 2., 2., 2.,
163  1., 1., 1.;
164  BOOST_CHECK_EQUAL(ETYPE::length(nodes_line3D),std::sqrt(3.));
165 }
166 
168 {
169  ETYPE::SF::ValueT reference_result;
170  reference_result << 0.4, 0.6;
171  ETYPE::SF::ValueT result;
172  ETYPE::SF::compute_value(mapped_coords, result);
173  Accumulator accumulator;
174  vector_test(result, reference_result, accumulator);
175  BOOST_CHECK_LT(boost::accumulators::max(accumulator.ulps), 10); // Maximal difference can't be greater than 10 times the least representable unit
176 }
177 
178 BOOST_AUTO_TEST_CASE( MappedGradient )
179 {
180  ETYPE::SF::GradientT result;
181  ETYPE::SF::GradientT expected(-0.5, 0.5);
182  ETYPE::SF::compute_gradient(mapped_coords, result);
183  Accumulator accumulator;
184  vector_test(result, expected, accumulator);
185  BOOST_CHECK_LT(boost::accumulators::max(accumulator.ulps), 2);
186 }
187 
189 {
190  ETYPE::JacobianT expected(2.5, -2., 0.5);
191  ETYPE::JacobianT result;
192  ETYPE::compute_jacobian(mapped_coords, nodes, result);
193  Accumulator accumulator;
194  vector_test(result, expected, accumulator);
195  BOOST_CHECK_LT(boost::accumulators::max(accumulator.ulps), 2);
196 }
197 
198 BOOST_AUTO_TEST_CASE( IntegrateConst )
199 {
200  ConstFunctor ftor(nodes);
201  const Real len = ETYPE::length(nodes);
202 
203  Real result1 = 0.0;
204  Real result2 = 0.0;
205  Real result4 = 0.0;
206  Real result8 = 0.0;
207  Real result16 = 0.0;
208  Real result32 = 0.0;
209 
210  gauss_integrate<1, GeoShape::LINE>(ftor, ftor.mapped_coords, result1);
211  gauss_integrate<2, GeoShape::LINE>(ftor, ftor.mapped_coords, result2);
212  gauss_integrate<4, GeoShape::LINE>(ftor, ftor.mapped_coords, result4);
213  gauss_integrate<8, GeoShape::LINE>(ftor, ftor.mapped_coords, result8);
214  gauss_integrate<16, GeoShape::LINE>(ftor, ftor.mapped_coords, result16);
215  gauss_integrate<32, GeoShape::LINE>(ftor, ftor.mapped_coords, result32);
216 
217  BOOST_CHECK_CLOSE(result1, len, 0.00001);
218  BOOST_CHECK_CLOSE(result2, len, 0.00001);
219  BOOST_CHECK_CLOSE(result4, len, 0.00001);
220  BOOST_CHECK_CLOSE(result8, len, 0.00001);
221  BOOST_CHECK_CLOSE(result16, len, 0.00001);
222  BOOST_CHECK_CLOSE(result32, len, 0.00001);
223 }
224 
225 BOOST_AUTO_TEST_CASE( LineIntegral )
226 {
227  // Create an approximation of a helix
228  const Real radius = 1.;
229  const Real height = 5.;
230  const Real tours = 3.;
231  const Uint segments = 10000;
232 
233  // complete circle
234  boost::shared_ptr< Table<Real> > coordinates(common::allocate_component< Table<Real> >(mesh::Tags::coordinates()));
235  boost::shared_ptr< Table<Uint> > connectivity(common::allocate_component< Table<Uint> >("connectivity"));
236  create_helix(*coordinates, *connectivity, radius, height, tours, segments);
237 
238  // Check the length, using the line integral of one times the norm of the tangent vector
239  Real length = 0.;
240  integrate_region(length, TangentVectorNorm(), *coordinates, *connectivity);
241  BOOST_CHECK_CLOSE(length, tours*sqrt((square(2.*Consts::pi()*radius)+square(height/tours))), 0.01);
242 }
243 
245 
246 BOOST_AUTO_TEST_SUITE_END()
247 
248 
LagrangeP1Line3DFixture()
common setup for each test case
cf3::Real result2[213]
ArrayT & array()
Definition: Table.hpp:92
void create_helix(Table< Real > &coordinates, Table< Uint > &connectivity, const Real radius, const Real height, const Real tours, const Uint segments)
Fills the given coordinate and connectivity data to create a helix along the Z-axis, consisting of ETYPE elements.
Returns the norm of the tangen vector to the curve.
void integrate_element(ResultT &result, FunctorT functor, const NodesT &nodes)
Integral over an element.
Basic Classes for Mathematical applications used by COOLFluiD.
static void compute_jacobian(const MappedCoordsT &mapped_coord, const NodesT &nodes, MatrixType &jacobian)
~LagrangeP1Line3DFixture()
common tear-down for each test case
cf3::Real result1[201]
Real max(const Real a, const Real b)
Maximum between two scalars.
Definition: Terminals.hpp:228
boost::proto::terminal< SFOp< NodesOp > >::type const nodes
Definition: Defs.hpp:17
Definition: Defs.hpp:17
void integrate_region(ResultT &result, FunctorT functor, const Table< Real > &coordinates, const Table< Uint > &connectivity)
Integral over a region.
Eigen::Matrix< Real, nb_nodes, Hexa3D_traits::dimension > NodesT
BOOST_AUTO_TEST_CASE(Length)
Lagrange P1 Triangular Element type This class provides the lagrangian shape function describing the ...
Definition: Line3D.hpp:38
Real pi()
Definition of the Pi constant.
Definition: Consts.hpp:48
boost::accumulators::accumulator_set< Real, boost::accumulators::stats< boost::accumulators::tag::min, boost::accumulators::tag::mean, boost::accumulators::tag::max, boost::accumulators::tag::median, boost::accumulators::tag::lazy_variance > > ulps
Stores statistics for comparisons of inexact (floating-point) types using Units in the Last Place (UL...
Definition: Difference.hpp:55
Basic Classes for Mesh applications used by COOLFluiD.
namespace holding LagrangeP1 shape functions and elements
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
Functions to provide integration over elements.
Definition: Gauss.hpp:26
Real operator()(const ETYPE::MappedCoordsT &mapped_coords, const NodesT &nodes)
boost::proto::terminal< SFOp< CoordinatesOp > >::type const coordinates
void set_row_size(const Uint nb_cols)
Definition: Table.hpp:78
unsigned int Uint
typedef for unsigned int
Definition: CF.hpp:90
Definition: Defs.hpp:17
void vector_test(const VectorT &A, const VectorT &B, Accumulator &Result)
Compares vector-like sequences.
Definition: Difference.hpp:139
Eigen::Matrix< Real, Hexa3D_traits::SF::dimensionality, Hexa3D_traits::dimension > JacobianT
Most basic kernel library.
Definition: Action.cpp:19
boost::shared_ptr< T > allocate_component(const std::string &name)
Stand-alone function to allocate components of a given type.
Definition: Component.hpp:55
2D Lagrange P1 Triangular Element type This class provides the lagrangian shape function describing t...
Definition: Hexa3D.hpp:36
Stores the results of the difference::test() function.
Definition: Difference.hpp:49
Real square(const Real x)
Definition: TaylorGreen.cpp:47
virtual void resize(const Uint nb_rows)
Definition: Table.hpp:85
const ETYPE::MappedCoordsT mapped_coords
Send comments to:
COOLFluiD Web Admin