COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-proto-unsteady.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 heat-conduction related proto operations"
9 
10 #include <boost/test/unit_test.hpp>
11 
12 #define BOOST_PROTO_MAX_ARITY 10
13 #ifdef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
14  #undef BOOST_MPL_LIMIT_METAFUNCTION_ARITY
15  #define BOOST_MPL_LIMIT_METAFUNCTION_ARITY 10
16 #endif
17 
18 #include "common/Core.hpp"
19 #include "common/Environment.hpp"
20 
21 #include "mesh/Domain.hpp"
22 #include "mesh/MeshGenerator.hpp"
23 
24 #include "solver/ModelUnsteady.hpp"
25 #include "solver/Time.hpp"
27 #include "solver/CriterionTime.hpp"
29 
32 
34 
36 #include "UFEM/Solver.hpp"
37 #include "UFEM/Tags.hpp"
38 #include "math/LSS/ZeroLSS.hpp"
39 #include "math/LSS/SolveLSS.hpp"
40 
41 
42 using namespace cf3;
43 using namespace cf3::solver;
44 using namespace cf3::solver::actions;
45 using namespace cf3::solver::actions::Proto;
46 using namespace cf3::common;
47 using namespace cf3::math::Consts;
48 using namespace cf3::mesh;
49 
50 using namespace boost;
51 
52 typedef std::vector<std::string> StringsT;
53 typedef std::vector<Uint> SizesT;
54 
56 inline void
57 check_close(const Real a, const Real b, const Real threshold)
58 {
59  BOOST_CHECK_CLOSE(a, b, threshold);
60 }
61 
62 static boost::proto::terminal< void(*)(Real, Real, Real) >::type const _check_close = {&check_close};
63 
65 {
67  length(5.),
68  ambient_temp(500.),
69  initial_temp(150.),
70  nb_segments(100),
71  k(1.),
72  alpha(1.),
73  start_time(0.),
74  end_time(10.),
75  dt(0.05),
76  t(start_time),
77  write_interval(100)
78  {
79  }
80 
82  void set_analytical_solution(Region& region, const std::string& field_name, const std::string& var_name)
83  {
84  FieldVariable<0, ScalarField > T(field_name, var_name);
85 
86  if(t == 0.)
87  {
89  (
90  region,
91  T = initial_temp
92  );
93  }
94  else
95  {
96  // Zero the field
98  (
99  region,
100  T = 0.
101  );
102 
103  const Real Fo = alpha * t / (0.25*length*length); // Fourier number
104  for(Uint i = 0; i != 100; ++i) // First 100 (to be sure ;) terms of the series that makes up the analytical solution (in terms of adimensional temperature)
105  {
106  const Real n = 1. + 2. * static_cast<Real>(i);
108  (
109  region,
110  T += 4./(pi()*n) * _exp( -0.25*n*n*pi()*pi()*Fo ) * _sin(0.5*n*pi()*(coordinates[0]/(0.5*length)))
111  );
112  }
113 
114  // Convert the result from the adimensional form to a real temperature
116  (
117  region,
118  T = T*(initial_temp - ambient_temp) + ambient_temp
119  );
120  }
121  }
122 
123  const Real length;
124  const Real ambient_temp;
125  const Real initial_temp;
127  const Real k;
128  const Real alpha;
129  const Real start_time;
130  const Real end_time;
131  const Real dt;
133  Real t;
134 };
135 
136 BOOST_FIXTURE_TEST_SUITE( ProtoUnsteadySuite, ProtoUnsteadyFixture )
137 
139 {
140  common::PE::Comm::instance().init(boost::unit_test::framework::master_test_suite().argc, boost::unit_test::framework::master_test_suite().argv);
141  BOOST_CHECK_EQUAL(common::PE::Comm::instance().size(), 1);
142 }
143 
144 BOOST_AUTO_TEST_CASE( Heat1DUnsteady )
145 {
146  // debug output
147  Core::instance().environment().options().set("log_level", 4u);
148 
149  // Setup a model
151  Domain& domain = model.create_domain("Domain");
152  UFEM::Solver& solver = *model.create_component<UFEM::Solver>("Solver");
153  Handle<UFEM::LSSActionUnsteady> lss_action(solver.add_unsteady_solver("cf3.UFEM.LSSActionUnsteady"));
154  Handle<common::ActionDirector> ic(solver.get_child("InitialConditions"));
155 
156 
157  boost::shared_ptr<solver::actions::Iterate> time_loop = allocate_component<solver::actions::Iterate>("TimeLoop");
158  time_loop->create_component<solver::CriterionTime>("CriterionTime");
159 
160  // Proto placeholders
161  FieldVariable<0, ScalarField> temperature("Temperature", UFEM::Tags::solution());
162  FieldVariable<1, ScalarField> temperature_analytical("TemperatureAnalytical", UFEM::Tags::source_terms());
163 
164  // Allowed elements (reducing this list improves compile times)
165  boost::mpl::vector1<mesh::LagrangeP1::Line1D> allowed_elements;
166 
167  // BCs
168  boost::shared_ptr<UFEM::BoundaryConditions> bc = allocate_component<UFEM::BoundaryConditions>("BoundaryConditions");
169 
170  // add the top-level actions (assembly, BC and solve)
171  *ic
172  << create_proto_action("Initialize", nodes_expression(temperature = initial_temp))
173  << create_proto_action("InitializeAnalytical", nodes_expression(temperature_analytical = initial_temp));
174  *lss_action
175  << allocate_component<math::LSS::ZeroLSS>("ZeroLSS")
176  << create_proto_action
177  (
178  "Assembly",
180  (
181  allowed_elements,
182  group
183  (
184  _A = _0, _T = _0,
186  (
187  _A(temperature) += alpha * transpose(nabla(temperature))*nabla(temperature),
188  _T(temperature) += lss_action->invdt() * transpose(N(temperature))*N(temperature)
189  ),
190  lss_action->system_matrix += _T + 0.5 * _A,
191  lss_action->system_rhs += -_A * nodal_values(temperature)
192  )
193  )
194  )
195  << bc
196  << allocate_component<math::LSS::SolveLSS>("SolveLSS")
197  << create_proto_action("Increment", nodes_expression(temperature += lss_action->solution(temperature)));
198 
199  // Setup physics
200  model.create_physics("cf3.physics.DynamicModel");
201 
202  // Setup mesh
203  // Mesh& mesh = *domain.create_component<Mesh>("Mesh");
204  // Tools::MeshGeneration::create_line(mesh, length, nb_segments);
205  boost::shared_ptr<MeshGenerator> create_line = build_component_abstract_type<MeshGenerator>("cf3.mesh.SimpleMeshGenerator","create_line");
206  create_line->options().set("mesh",domain.uri()/"Mesh");
207  create_line->options().set("lengths",std::vector<Real>(DIM_1D, length));
208  create_line->options().set("nb_cells",std::vector<Uint>(DIM_1D, nb_segments));
209  Mesh& mesh = create_line->generate();
210 
211  lss_action->options().set("regions", std::vector<URI>(1, mesh.topology().uri()));
212  ic->get_child("Initialize")->options().set("regions", std::vector<URI>(1, mesh.topology().uri()));
213  ic->get_child("InitializeAnalytical")->options().set("regions", std::vector<URI>(1, mesh.topology().uri()));
214 
215  bc->add_constant_bc("xneg", "Temperature", ambient_temp);
216  bc->add_constant_bc("xpos", "Temperature", ambient_temp);
217 
218  // Configure timings
219  Time& time = model.create_time();
220  time.options().set("time_step", dt);
221  time.options().set("end_time", end_time);
222 
223  // Run the solver
224  model.simulate();
225 
226  // Check result
227  t = model.time().current_time();
228  std::cout << "Checking solution at time " << t << std::endl;
229  set_analytical_solution(mesh.topology(), "TemperatureAnalytical", UFEM::Tags::source_terms());
231  (
232  mesh.topology(),
233  _check_close(temperature_analytical, temperature, 1.)
234  );
235 
236  std::cout << solver.tree() << std::endl;
237 };
238 
239 BOOST_AUTO_TEST_SUITE_END()
boost::proto::terminal< SFOp< ShapeFunctionOp > >::type const N
std::vector< std::string > StringsT
Time & create_time(const std::string &name="Time")
Create Time component.
static boost::proto::terminal< ZeroTag >::type _0
Placeholder for the zero matrix.
Definition: Terminals.hpp:209
void create_line(Mesh &mesh, const Real x_len, const Uint x_segments)
Create a 1D line mesh.
virtual mesh::Domain & create_domain(const std::string &name)
creates a domain in this model
Definition: Model.cpp:201
Safe pointer to an object. This is the supported method for referring to components.
Definition: Handle.hpp:39
external boost library namespace
virtual physics::PhysModel & create_physics(const std::string &builder)
Definition: Model.cpp:182
static boost::proto::terminal< ElementSystemMatrix< boost::mpl::int_< 0 > > >::type const _A
Some predefined element matrices (more can be user-defined, but you have to change the number in the ...
Handle< common::Action > add_unsteady_solver(const std::string &builder_name)
Definition: Solver.cpp:138
static boost::proto::terminal< ElementSystemMatrix< boost::mpl::int_< 1 > > >::type const _T
Basic Classes for Solver applications used by CF.
Definition: Action.cpp:29
URI uri() const
Construct the full path.
Definition: Component.cpp:248
static boost::proto::terminal< NodalValuesTag >::type const nodal_values
static boost::proto::terminal< ElementQuadratureTag >::type element_quadrature
Use element_quadrature(expr1, expr2, ..., exprN) to evaluate a group of expressions.
boost::shared_ptr< ElementsExpression< ExprT, ElementTypes > > elements_expression(ElementTypes, const ExprT &expr)
Definition: Expression.hpp:292
static boost::proto::terminal< double(*)(double) >::type const _exp
Definition: Terminals.hpp:243
Manage a collection of UFEM solvers.
Definition: Solver.hpp:31
void for_each_node(mesh::Region &root_region, const ExprT &expr)
Definition: NodeLooper.hpp:239
Static functions for mathematical constants.
Definition: Consts.hpp:25
std::vector< Uint > SizesT
Storage for time, and time steps for unsteady simulation.
Definition: Time.hpp:26
boost::proto::terminal< TransposeFunction >::type const transpose
boost::proto::terminal< SFOp< NablaOp > >::type const nabla
Real pi()
Definition of the Pi constant.
Definition: Consts.hpp:48
void check_close(const Real a, const Real b, const Real threshold)
Check close, fo testing purposes.
Basic Classes for Mesh applications used by COOLFluiD.
BOOST_AUTO_TEST_CASE(InitMPI)
tuple model
Global confifuration.
Handle< Component > get_child(const std::string &name)
Definition: Component.cpp:441
static boost::proto::terminal< void(*)(Real, Real, Real) >::type const _check_close
void init(int argc=0, char **args=0)
Definition: Comm.cpp:80
Top-level namespace for coolfluid.
Definition: Action.cpp:18
virtual void simulate()
Simulates this model.
std::string tree(bool basic_mode=false, Uint depth=0, Uint recursion_level=0) const
Definition: Component.cpp:785
Real & current_time()
Definition: Time.hpp:41
boost::proto::terminal< SFOp< CoordinatesOp > >::type const coordinates
static boost::proto::terminal< double(*)(double) >::type const _sin
Definition: Terminals.hpp:240
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.
common::Environment & environment() const
Definition: Core.cpp:168
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
boost::shared_ptr< NodesExpression< ExprT, boost::mpl::range_c< Uint, 1, 4 > > > nodes_expression(const ExprT &expr)
Definition: Expression.hpp:308
OptionList & options()
Definition: Component.cpp:856
Time & time()
Reference to the time.
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
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
void set_analytical_solution(Region &region, const std::string &field_name, const std::string &var_name)
Write the analytical solution, according to "A Heat transfer textbook", section 5.3.
Send comments to:
COOLFluiD Web Admin