COOLFluiD  Release kernel
COOLFluiD is a Collaborative Simulation Environment (CSE) focused on complex MultiPhysics simulations.
utest-ufem-teko-blocks.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 teko matrix blocking functions"
9 
10 #include <boost/assign.hpp>
11 #include <boost/test/unit_test.hpp>
12 
13 #include <Teko_EpetraHelpers.hpp>
14 #include <Teko_Utilities.hpp>
15 
16 #include <Thyra_EpetraLinearOp.hpp>
17 #include <Thyra_VectorStdOps.hpp>
18 
19 #include "common/Core.hpp"
20 #include "common/Environment.hpp"
21 
23 
24 #include "math/LSS/System.hpp"
25 #include "math/LSS/SolveLSS.hpp"
29 
30 #include "mesh/Domain.hpp"
32 
33 #include "solver/Model.hpp"
34 
37 
39 #include "mesh/MeshGenerator.hpp"
40 
41 #include "UFEM/LSSAction.hpp"
42 #include "UFEM/Solver.hpp"
43 #include "UFEM/SparsityBuilder.hpp"
44 #include "UFEM/Tags.hpp"
45 
46 using namespace cf3;
47 using namespace cf3::solver;
48 using namespace cf3::solver::actions;
49 using namespace cf3::solver::actions::Proto;
50 using namespace cf3::common;
51 using namespace cf3::math;
52 using namespace cf3::math::Consts;
53 using namespace cf3::mesh;
54 
55 using namespace boost::assign;
56 
58 {
60  root( Core::instance().root() )
61  {
62  }
63 
64  void apply_block(const int i, const int j, Teuchos::RCP<Epetra_Vector>& output)
65  {
66  const Teuchos::RCP<const Epetra_Operator> block = blocked_op->GetBlock(i,j);
67  Epetra_Vector testvec(block->OperatorDomainMap());
68  int num_entries = block->OperatorDomainMap().NumMyElements();
69  std::vector<int> indices(num_entries);
70  for(int i = 0; i != num_entries; ++i)
71  indices[i] = i;
72  if(j ==0)
73  testvec.ReplaceMyValues(num_entries, &u_test_vec[0], &indices[0]);
74  else
75  testvec.ReplaceMyValues(num_entries, &p_test_vec[0], &indices[0]);
76 
77  output = Teuchos::rcp(new Epetra_Vector(block->OperatorRangeMap()));
78  block->Apply(testvec, *output);
79  }
80 
81  Component& root;
82  Teuchos::RCP<Teko::Epetra::BlockedEpetraOperator> blocked_op;
83  std::vector<Real> u_test_vec, p_test_vec;
84 };
85 
86 
87 
88 BOOST_FIXTURE_TEST_SUITE( UFEMBuildSparsitySuite, UFEMBuildSparsityFixture )
89 
91 {
92  common::PE::Comm::instance().init(boost::unit_test::framework::master_test_suite().argc, boost::unit_test::framework::master_test_suite().argv);
93  BOOST_CHECK_EQUAL(common::PE::Comm::instance().size(), 1);
94 }
95 
96 BOOST_AUTO_TEST_CASE( Blocked2DQuads )
97 {
98  Core::instance().environment().options().set("log_level", 4u);
99 
100  // Parameters
101  Real length = 5.;
102  const Uint nb_segments = 3;
103  const Uint nb_nodes = (nb_segments+1) * (nb_segments+1);
104 
105  // Setup a model
106  Model& model = *root.create_component<Model>("Model");
107  Domain& domain = model.create_domain("Domain");
108 
109  UFEM::Solver& solver = *model.create_component<UFEM::Solver>("Solver");
110 
111  Handle<UFEM::LSSAction> lss_action(solver.add_direct_solver("cf3.UFEM.LSSAction"));
112  lss_action->options().set("blocked_system", false);
113 
114  // Proto placeholders
115  FieldVariable<0, VectorField> u("u", UFEM::Tags::solution());
116  FieldVariable<1, ScalarField> p("p", UFEM::Tags::solution());
117 
118  // Allowed elements (reducing this list improves compile times)
119  boost::mpl::vector1<mesh::LagrangeP1::Quad2D> allowed_elements;
120 
121  // add the top-level actions (assembly, BC and solve)
122  lss_action->add_component(create_proto_action
123  (
124  "Assembly",
126  (
127  allowed_elements,
128  group
129  (
130  _A = _0,
132  (
133  _A(u[_i], u[_i]) += transpose(N(u))*N(u),
134  _A(u[_i],p) += -transpose(nabla(u)[_i])*N(p),
135  _A(p,u[_i]) += transpose(N(p))*nabla(u)[_i],
136  _A(p,p) += transpose(nabla(p))*nabla(p)
137  ),
138  lss_action->system_matrix += _A
139  )
140  )
141  ));
142 
143  physics::PhysModel& physical_model = model.create_physics("cf3.UFEM.NavierStokesPhysics");
144 
145  // Setup mesh
146  Mesh& mesh = *domain.create_component<Mesh>("Mesh");
147  BlockMesh::BlockArrays& blocks = *domain.create_component<BlockMesh::BlockArrays>("blocks");
148 
149  *blocks.create_points(2, 4) << 0. << 0. << length << 0. << length << length << 0. << length;
150  *blocks.create_blocks(1) << 0 << 1 << 2 << 3;
151  *blocks.create_block_subdivisions() << nb_segments << nb_segments;
152  *blocks.create_block_gradings() << 1. << 1. << 1. << 1.;
153 
154  *blocks.create_patch("bottom", 1) << 0 << 1;
155  *blocks.create_patch("right", 1) << 1 << 2;
156  *blocks.create_patch("top", 1) << 2 << 3;
157  *blocks.create_patch("left", 1) << 3 << 0;
158 
159  blocks.partition_blocks(PE::Comm::instance().size(), YY);
160  blocks.create_mesh(mesh);
161 
162  lss_action->options().set("matrix_builder", std::string("cf3.math.LSS.TrilinosCrsMatrix"));
163  LSS::System& lss = lss_action->create_lss();
164  lss_action->options().set("regions", std::vector<URI>(1, mesh.topology().uri()));
165 
166  model.simulate();
167 
168  // Initialize the solution vector
169  u_test_vec.resize(nb_nodes*2);
170  p_test_vec.resize(nb_nodes);
171  for(Uint i = 0; i != nb_nodes; ++i)
172  {
173  lss.solution()->set_value(i, 0, i*3);
174  lss.solution()->set_value(i, 1, i*3+1);
175  lss.solution()->set_value(i, 2, i*3+2);
176  u_test_vec[i*2] = i*3;
177  u_test_vec[i*2+1] = i*3+1;
178  p_test_vec[i] = i*3+2;
179  }
180 
181  // Apply the complete matrix to the solution vector
184  Handle<math::LSS::TrilinosVector> tri_rhs(lss.rhs());
185  BOOST_CHECK(crs_mat);
186  crs_mat->epetra_matrix()->Apply(*tri_sol->epetra_vector(), *tri_rhs->epetra_vector());
187 
188  // Create matrix subblocks
189  math::VariablesDescriptor& descriptor = common::find_component_with_tag<VariablesDescriptor>(physical_model.variable_manager(), UFEM::Tags::solution());
190  blocked_op = math::LSS::create_teko_blocked_operator(*crs_mat, descriptor);
191 
192  Teuchos::RCP<Epetra_Vector> uu_output;
193  apply_block(0, 0, uu_output);
194 
195  Teuchos::RCP<Epetra_Vector> up_output;
196  apply_block(0, 1, up_output);
197 
198  Teuchos::RCP<Epetra_Vector> pu_output;
199  apply_block(1, 0, pu_output);
200 
201  Teuchos::RCP<Epetra_Vector> pp_output;
202  apply_block(1, 1, pp_output);
203 
204  // Check if the result of applying blocks is the same as the result of applying the whole matrix
205  for(Uint i = 0; i != nb_nodes; ++i)
206  {
207  Real u_check, v_check, p_check;
208  tri_rhs->get_value(i, 0, u_check);
209  tri_rhs->get_value(i, 1, v_check);
210  tri_rhs->get_value(i, 2, p_check);
211 
212  BOOST_CHECK_CLOSE((*uu_output)[i*2] + (*up_output)[i*2], u_check, 1e-8);
213  BOOST_CHECK_CLOSE((*uu_output)[i*2+1] + (*up_output)[i*2+1], v_check, 1e-8);
214  BOOST_CHECK_CLOSE((*pu_output)[i] + (*pp_output)[i], p_check, 1e-8);
215  }
216 
217  Teuchos::RCP<const Thyra::LinearOpBase<Real> > Aup = Thyra::epetraLinearOp(blocked_op->GetBlock(0,1));
218  Teuchos::RCP<const Thyra::LinearOpBase<Real> > Apu = Thyra::epetraLinearOp(blocked_op->GetBlock(1,0));
219  Teuchos::RCP<const Thyra::LinearOpBase<Real> > K = Teko::explicitMultiply(Apu,Aup);
220  Teuchos::RCP<Thyra::VectorBase<Real> > b = Thyra::createMember(K->range());
221  Teuchos::RCP<Thyra::VectorBase<Real> > x = Thyra::createMember(K->domain());
222 
223  for(Uint i = 0; i != nb_nodes; ++i)
224  {
225  Thyra::set_ele(i, p_test_vec[i], b.ptr());
226  }
227  Thyra::apply(*K, Thyra::NOTRANS, *b, x.ptr());
228 
229  for(Uint i = 0; i != nb_nodes; ++i)
230  {
231  BOOST_CHECK((*pp_output)[i] != Thyra::get_ele(*x, i));
232  }
233 
234  Teuchos::RCP<std::ofstream> k_out = Teuchos::rcp(new std::ofstream("K.txt", std::ios::out));
235  Teuchos::RCP<Teuchos::FancyOStream> k_fancy_out = Teuchos::fancyOStream(k_out);
236  Thyra::describeLinearOp(*K, *k_fancy_out, Teuchos::VERB_EXTREME);
237 
238  Teuchos::RCP<const Thyra::LinearOpBase<Real> > App = Thyra::epetraLinearOp(blocked_op->GetBlock(1,1));
239  Teuchos::RCP<std::ofstream> app_out = Teuchos::rcp(new std::ofstream("App.txt", std::ios::out));
240  Teuchos::RCP<Teuchos::FancyOStream> app_fancy_out = Teuchos::fancyOStream(app_out);
241  Thyra::describeLinearOp(*App, *app_fancy_out, Teuchos::VERB_EXTREME);
242 }
243 
244 BOOST_AUTO_TEST_CASE( FinalizeMPI )
245 {
247 }
248 
250 
251 BOOST_AUTO_TEST_SUITE_END()
252 
253 
boost::proto::terminal< SFOp< ShapeFunctionOp > >::type const N
Handle< LSS::Vector > solution()
Accessor to solution.
Definition: System.hpp:151
static boost::proto::terminal< ZeroTag >::type _0
Placeholder for the zero matrix.
Definition: Terminals.hpp:209
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
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_direct_solver(const std::string &builder_name)
Definition: Solver.cpp:128
CGAL::Exact_predicates_inexact_constructions_kernel K
This header collects all the headers needed for the linear system solver, also including configure-ti...
Basic Classes for Mathematical applications used by COOLFluiD.
Parallel Communication Pattern. This class provides functionality to collect communication. For efficiency it works such a way that you submit your request via the constructor or the add/remove/move magic triangle and then call setup to modify the commpattern. The data needed to be kept synchronous can be registered via the insert function. The word node here means any kind of "point of storage", in this context it is not directly related with the computational mesh.
Basic Classes for Solver applications used by CF.
Definition: Action.cpp:29
URI uri() const
Construct the full path.
Definition: Component.cpp:248
Handle< LSS::Matrix > matrix()
Accessor to matrix.
Definition: System.hpp:145
static boost::proto::terminal< ElementQuadratureTag >::type element_quadrature
Use element_quadrature(expr1, expr2, ..., exprN) to evaluate a group of expressions.
tuple root
Definition: coolfluid.py:24
boost::shared_ptr< ElementsExpression< ExprT, ElementTypes > > elements_expression(ElementTypes, const ExprT &expr)
Definition: Expression.hpp:292
Manage a collection of UFEM solvers.
Definition: Solver.hpp:31
Real e()
Definition of the Unit charge [C].
Definition: Consts.hpp:30
BOOST_AUTO_TEST_CASE(InitMPI)
Static functions for mathematical constants.
Definition: Consts.hpp:25
void apply_block(const int i, const int j, Teuchos::RCP< Epetra_Vector > &output)
boost::proto::terminal< TransposeFunction >::type const transpose
boost::proto::terminal< SFOp< NablaOp > >::type const nabla
Basic Classes for Mesh applications used by COOLFluiD.
tuple model
Global confifuration.
void init(int argc=0, char **args=0)
Definition: Comm.cpp:80
Top-level namespace for coolfluid.
Definition: Action.cpp:18
Handle< LSS::Vector > rhs()
Accessor to right hand side.
Definition: System.hpp:148
static boost::proto::terminal< IndexTag< boost::mpl::int_< 0 > > >::type const _i
Index looping over the dimensions of a variable.
Teuchos::RCP< Teko::Epetra::BlockedEpetraOperator > blocked_op
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
virtual void simulate()
Simulates this model.
Definition: Model.cpp:132
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
Definition: Defs.hpp:17
math::VariableManager & variable_manager()
Access to the VariableManager.
Definition: PhysModel.cpp:42
OptionList & options()
Definition: Component.cpp:856
Teuchos::RCP< Teko::Epetra::BlockedEpetraOperator > create_teko_blocked_operator(TrilinosCrsMatrix &matrix, const math::VariablesDescriptor &vars)
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