COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-neumann.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 //explained in boost doc
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 #include "common/Libraries.hpp"
21 
22 #include "math/LSS/System.hpp"
23 
24 #include "mesh/Domain.hpp"
25 #include "mesh/LagrangeP0/Quad.hpp"
27 #include <mesh/LagrangeP0/Line.hpp>
29 
30 #include "solver/Model.hpp"
31 
32 #include "math/LSS/SolveLSS.hpp"
33 
36 
38 
40 #include <mesh/FieldManager.hpp>
41 
42 #include "UFEM/LSSAction.hpp"
43 #include "UFEM/Solver.hpp"
44 #include "UFEM/Tags.hpp"
46 
47 using namespace cf3;
48 using namespace cf3::solver;
49 using namespace cf3::solver::actions;
50 using namespace cf3::solver::actions::Proto;
51 using namespace cf3::common;
52 using namespace cf3::math::Consts;
53 using namespace cf3::mesh;
54 
55 using namespace boost;
56 
57 
58 typedef std::vector<std::string> StringsT;
59 typedef std::vector<Uint> SizesT;
60 
62 inline void
63 check_close(const Real a, const Real b, const Real threshold)
64 {
65  BOOST_CHECK_CLOSE(a, b, threshold);
66 }
67 
68 static boost::proto::terminal< void(*)(Real, Real, Real) >::type const _check_close = {&check_close};
69 
71 {
73  root( Core::instance().root() )
74  {
75  }
76 
78 
79 };
80 
81 BOOST_FIXTURE_TEST_SUITE( NeumannSuite, NeumannFixture )
82 
84 {
85  common::PE::Comm::instance().init(boost::unit_test::framework::master_test_suite().argc, boost::unit_test::framework::master_test_suite().argv);
86  BOOST_CHECK_EQUAL(common::PE::Comm::instance().size(), 1);
87 }
88 
89 BOOST_AUTO_TEST_CASE( NeumannTest )
90 {
91  Core::instance().environment().options().set("log_level", 4u);
92  //Core::instance().environment().options().set("exception_aborts", true);
93 
94  // Setup a model
95  Model& model = *root.create_component<Model>("Model");
96  Domain& domain = model.create_domain("Domain");
97  physics::PhysModel& physics = model.create_physics("cf3.UFEM.NavierStokesPhysics");
98  // Add a UFEM solver, the top layer for the simulation
99  Handle<UFEM::Solver> solver(model.create_solver("cf3.UFEM.Solver").handle());
100  // This steady heat conduction solver will be used on the bottom region:
101  Handle<UFEM::LSSAction> hc_bottom(solver->add_direct_solver("cf3.UFEM.HeatConductionSteady"));
102  // coupling_bc will hold the actions related to the heat transfer coupling condition between the regions
103  Handle<solver::ActionDirector> coupling_bc = solver->create_component<solver::ActionDirector>("heat_bc");
104  // hc_top solves the heat conduction equation in the top part of the mesh
105  Handle<UFEM::LSSAction> hc_top(solver->add_direct_solver("cf3.UFEM.HeatConductionSteady"));
106 
107  // Handles to boundary conditions
108  Handle<UFEM::BoundaryConditions> bc_bot(hc_bottom->get_child("BoundaryConditions"));
109  Handle<UFEM::BoundaryConditions> bc_top(hc_top->get_child("BoundaryConditions"));
110 
111 
113  // Special-purpose boundary condition //
115 
116  // Represents the temperature field, as calculated
117  FieldVariable<0, ScalarField> T("Temperature", "solution");
118  // Represents the gradient of the temperature, to be stored in an (element based) field
119  FieldVariable<1, VectorField> GradT("GradT", "element_fields", Core::instance().libraries().library<mesh::LagrangeP0::LibLagrangeP0>()->library_namespace());
120 
121  // For quads, the center is at mapped coordinates (0,0)
122  RealVector2 center; center.setZero();
123 
124  // Calculate the gradient, at the cell centroid:
125  // nabla(T, center) is the shape function gradient matrix evaluated at the element center
126  // T are the nodal values for the temperature
127  boost::shared_ptr<Expression> grad_t_expr = elements_expression
128  (
129  boost::mpl::vector2<mesh::LagrangeP0::Quad, mesh::LagrangeP1::Quad2D>(),
130  GradT = nabla(T, center)*nodal_values(T)
131  );
132 
133  // Register the variables, making sure a field description for GradT exists
134  grad_t_expr->register_variables(physics);
135 
136  // Add an action to do the gradient calculation
137  (*coupling_bc ) << create_proto_action("GradT", grad_t_expr);
138 
139  // This will create values at the boundary starting from the cell next to the wall
140  common::Action& create_boundary_gradient = *coupling_bc->create_component<UFEM::AdjacentCellToFace>("CreateBoundaryGradient");
141  // Must be the tag for the field we want to copy, in this case GradT:
142  create_boundary_gradient.options().set("field_tag", std::string("element_fields"));
143 
144  // Add the neumann boundary condition, which is expressed using a proto action:
145  Component& neumann_bc = bc_top->add_component(create_proto_action("NeumannHeat", elements_expression
146  (
147  boost::mpl::vector2<mesh::LagrangeP0::Line, mesh::LagrangeP1::Line2D>(), // Valid for surface element types
148  hc_top->system_rhs(T) += integral<1>(transpose(N(T))*GradT*normal) // Classical Neumann condition formulation for finite elements
149  )));
150 
151  // Build the mesh
152  Handle<BlockMesh::BlockArrays> blocks = domain.create_component<BlockMesh::BlockArrays>("blocks");
153  (*blocks->create_points(2, 6)) << 0. << 0.
154  << 1. << 0.
155  << 0. << 0.5
156  << 1. << 0.5
157  << 0. << 1.
158  << 1. << 1.;
159 
160  (*blocks->create_blocks(2)) << 0 << 1 << 3 << 2
161  << 2 << 3 << 5 << 4;
162 
163  (*blocks->create_block_subdivisions()) << 40 << 20 << 40 << 20;
164  (*blocks->create_block_gradings()) << 1. << 1. << 1. << 1. << 1. << 1. << 1. << 1.;
165 
166  *blocks->create_patch("left", 2) << 2 << 0 << 4 << 2;
167  *blocks->create_patch("right", 2) << 1 << 3 << 3 << 5;
168  *blocks->create_patch("top", 1) << 5 << 4;
169  *blocks->create_patch("bottom", 1) << 0 << 1;
170 
171  // Setup a different region for each of the two blocks
172  std::vector<std::string> block_regions(2); block_regions[0] = "solid_bottom"; block_regions[1] = "solid_top";
173  blocks->options().set("block_regions", block_regions);
174 
175  Handle<Mesh> mesh = domain.create_component<Mesh>("Mesh");
176  blocks->create_mesh(*mesh);
177 
178  // Set up the regular bottom and top solvers
179  hc_bottom->options().set("regions", std::vector<URI>(1, mesh->access_component("topology/solid_bottom")->uri()));
180  hc_top->options().set("regions", std::vector<URI>(1, mesh->access_component("topology/solid_top")->uri()));
181 
182  math::LSS::System& bot_lss = hc_bottom->create_lss();
183  math::LSS::System& top_lss = hc_top->create_lss();
184 
185  bc_bot->options().set("regions", std::vector<URI>(1, mesh->topology().uri()));
186  bc_bot->add_constant_bc("bottom", "Temperature")->options().set("value", 10.);
187  bc_bot->add_constant_bc("region_bnd_solid_bottom_solid_top", "Temperature")->options().set("value", 50.);
188 
189  bc_top->options().set("regions", std::vector<URI>(1, mesh->topology().uri()));
190  bc_top->add_constant_bc("top", "Temperature")->options().set("value", 10.);
191 
192 
193  // Set up the regions (needs to be done after mesh creation)
194  coupling_bc->get_child("GradT")->options().set("regions", std::vector<URI>(1, mesh->access_component("topology/solid_bottom")->uri()));
195  neumann_bc.options().set("regions", std::vector<URI>(1, mesh->access_component("topology/region_bnd_solid_top_solid_bottom")->uri()));
196  create_boundary_gradient.options().set("regions", std::vector<URI>(1, mesh->access_component("topology/region_bnd_solid_top_solid_bottom")->uri()));
197 
198  // Run the simulation and save the mesh
199  model.simulate();
200  top_lss.rhs()->print_native(std::cout);
201  domain.write_mesh("utest-neumann.msh");
202 }
203 
205 
206 BOOST_AUTO_TEST_SUITE_END()
207 
208 
boost::proto::terminal< SFOp< ShapeFunctionOp > >::type const N
void check_close(const Real a, const Real b, const Real threshold)
Check close, for testing purposes.
boost::proto::terminal< SFOp< NormalOp > >::type const normal
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
This header collects all the headers needed for the linear system solver, also including configure-ti...
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
std::vector< Uint > SizesT
Handle< common::Table< Uint > > create_block_subdivisions()
Definition: BlockData.cpp:1315
tuple root
Definition: coolfluid.py:24
boost::shared_ptr< ElementsExpression< ExprT, ElementTypes > > elements_expression(ElementTypes, const ExprT &expr)
Definition: Expression.hpp:292
Handle< Component > access_component(const URI &path) const
Definition: Component.cpp:487
Handle< common::Table< Uint > > create_blocks(const Uint nb_blocks)
Create the table that holds the blocks.
Definition: BlockData.cpp:1299
Static functions for mathematical constants.
Definition: Consts.hpp:25
boost::proto::terminal< TransposeFunction >::type const transpose
boost::proto::terminal< SFOp< NablaOp > >::type const nabla
virtual Solver & create_solver(const std::string &builder)
Definition: Model.cpp:211
Basic Classes for Mesh applications used by COOLFluiD.
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
std::vector< std::string > StringsT
Handle< common::Table< Real > > create_block_gradings()
Definition: BlockData.cpp:1329
Handle< LSS::Vector > rhs()
Accessor to right hand side.
Definition: System.hpp:148
Handle< common::Table< Uint > > create_patch(const std::string &name, const Uint nb_faces)
Definition: BlockData.cpp:1343
Component that executes an action. Implementation of the IAction interface as a component, exposing the execute function as a signal.
Definition: Action.hpp:21
common::Environment & environment() const
Definition: Core.cpp:168
virtual void simulate()
Simulates this model.
Definition: Model.cpp:132
Eigen::Matrix< Real, 2, 1 > RealVector2
Fixed size 2x1 column vector.
Definition: MatrixTypes.hpp:40
Component & root
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
OptionList & options()
Definition: Component.cpp:856
BOOST_AUTO_TEST_CASE(InitMPI)
static Comm & instance()
Return a reference to the current PE.
Definition: Comm.cpp:44
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
Handle< common::Table< Real > > create_points(const Uint dimensions, const Uint nb_points)
Create the table that holds the points for the blocks.
Definition: BlockData.cpp:1287
Send comments to:
COOLFluiD Web Admin