LifeV
ETA_Blocks2DTest.cpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 *******************************************************************************
4 
5  Copyright (C) 2004, 2005, 2007 EPFL, Politecnico di Milano, INRIA
6  Copyright (C) 2010 EPFL, Politecnico di Milano, Emory University
7 
8  This file is part of LifeV.
9 
10  LifeV is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation, either version 3 of the License, or
13  (at your option) any later version.
14 
15  LifeV is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with LifeV. If not, see <http://www.gnu.org/licenses/>.
22 
23 *******************************************************************************
24 */
25 //@HEADER
26 /**
27  @file ETA_Blocks2DTest.cpp
28  @author L. Pasquale <luca.pasquale@mail.polimi.it>
29  @date 2012-11-20
30  */
31 
32 // ===================================================
33 //! Includes
34 // ===================================================
35 
37 
38 #include <lifev/eta/fem/ETFESpace.hpp>
39 #include <lifev/eta/expression/Integrate.hpp>
40 
41 
42 // ===================================================
43 //! Namespaces & define
44 // ===================================================
45 
46 // ---------------------------------------------------------------
47 // We work in the LifeV namespace and define the mesh, matrix and
48 // vector types that we will need several times.
49 // ---------------------------------------------------------------
50 
51 using namespace LifeV;
52 
54 typedef MatrixEpetra<Real> matrix_Type;
55 typedef VectorEpetra vector_Type;
56 typedef MatrixEpetraStructured<Real> blockMatrix_Type;
57 typedef VectorEpetraStructured blockVector_Type;
58 
59 // ---------------------------------------------------------------
60 // We define then a function, which represents a velocity field,
61 // of magnitude 1 in the y direction (supposing an (x,y)
62 // reference frame).
63 // ---------------------------------------------------------------
64 
65 
66 // ===================================================
67 //! Functions
68 // ===================================================
69 
70 // ---------------------------------------------------------------
71 // We define a function that is supposed to represent a
72 // force acting on the fluid.
73 // ---------------------------------------------------------------
74 
75 Real forceFct ( const Real& /*t*/, const Real& /*x*/, const Real& y, const Real& /*z*/ , const ID& /*i*/)
76 {
77  return y * y;
78 }
79 
80 // ===================================================
81 //! Constructors
82 // ===================================================
83 
84 ETA_Blocks2DTest::ETA_Blocks2DTest ()
85 {
86 
87 #ifdef EPETRA_MPI
88  M_comm.reset ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
89 #else
90  M_comm.reset ( new Epetra_SerialComm() );
91 #endif
92 
93 }
94 
95 // ===================================================
96 //! Methods
97 // ===================================================
98 
99 std::vector<Real>
100 ETA_Blocks2DTest::run()
101 {
102  bool verbose (M_comm->MyPID() == 0);
103  // ---------------------------------------------------------------
104  // We define the mesh and parition it. We use the domain
105  // (-1,1)x(-1,1) and a structured mesh.
106  // ---------------------------------------------------------------
107 
108  if (verbose)
109  {
110  std::cout << " -- Building and partitioning the mesh ... " << std::flush;
111  }
112 
113  const UInt Nelements (10);
114 
115  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type);
116 
117  regularMesh2D ( *fullMeshPtr, 0, Nelements, Nelements, false,
118  2.0, 2.0,
119  -0.0, -0.0);
120 
121  std::shared_ptr< mesh_Type > meshPtr;
122  {
123  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, M_comm);
124  meshPtr = meshPart.meshPartition();
125  }
126 
127  fullMeshPtr.reset();
128 
129  if (verbose)
130  {
131  std::cout << " done ! " << std::endl;
132  }
133 
134  // ---------------------------------------------------------------
135  // We define now the ETFESpaces. We need one space for the
136  // velocity (vectorial, P2) and one space for the pressure
137  // (scalar, P1).
138  //
139  // We also define velocity FESpace to use the interpolation.
140  // ---------------------------------------------------------------
141 
142  if (verbose)
143  {
144  std::cout << " -- Building the spaces ... " << std::flush;
145  }
146 
147  std::string uOrder ("P2");
148  std::shared_ptr<FESpace< mesh_Type, MapEpetra > > uSpace
149  ( new FESpace< mesh_Type, MapEpetra > (meshPtr, uOrder, 1, M_comm) );
150 
151  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 2, 2 > > ETuSpace
152  ( new ETFESpace< mesh_Type, MapEpetra, 2, 2 > (meshPtr, &feTriaP2, & (uSpace->fe().geoMap() ), M_comm) );
153 
154  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 2, 1 > > ETpSpace
155  ( new ETFESpace< mesh_Type, MapEpetra, 2, 1 > (meshPtr, &feTriaP1, & (uSpace->fe().geoMap() ), M_comm) );
156 
157  if (verbose)
158  {
159  std::cout << " done ! " << std::endl;
160  }
161  if (verbose)
162  {
163  std::cout << " ---> Velocity dofs: " << ETuSpace->dof().numTotalDof() << std::endl;
164  }
165  if (verbose)
166  {
167  std::cout << " ---> Pressure dofs: " << ETpSpace->dof().numTotalDof() << std::endl;
168  }
169 
170  // ---------------------------------------------------------------
171  // We want to assemble a Stokes matrix. This matrix is divided
172  // into four blocks (with the (1,1)-block empty). We define it
173  // using a special constructor with "|" operators, which
174  // separates the different blocks.
175  // ---------------------------------------------------------------
176 
177  if (verbose)
178  {
179  std::cout << " -- Assembly of the Stokes matrix ... " << std::flush;
180  }
181 
182  std::shared_ptr<blockMatrix_Type> ETsystemMatrix (new blockMatrix_Type ( ETuSpace->map() | ETpSpace->map() ) );
183  *ETsystemMatrix *= 0.0;
184 
185  // ---------------------------------------------------------------
186  // To fill them, we simply have to call one integrate for each
187  // non-empty block and indicate in which block the contribution
188  // has to go.
189  //
190  // Remark that, depending on the block assembled, the spaces for
191  // the test and trial functions are different.
192  // ---------------------------------------------------------------
193 
194  {
195  using namespace ExpressionAssembly;
196 
197  integrate ( elements (ETuSpace->mesh() ),
198  quadRuleTetra4pt,
199  ETuSpace,
200  ETuSpace,
201 
202  dot ( grad (phi_i) , grad (phi_j) )
203 
204  )
205  >> ETsystemMatrix->block (0, 0);
206 
207  integrate ( elements (ETuSpace->mesh() ),
208  quadRuleTetra4pt,
209  ETuSpace,
210  ETpSpace,
211 
212  phi_j * div (phi_i)
213 
214  )
215  >> ETsystemMatrix->block (0, 1);
216 
217  integrate ( elements (ETuSpace->mesh() ),
218  quadRuleTetra4pt,
219  ETpSpace,
220  ETuSpace,
221 
222  phi_i * div (phi_j)
223 
224  )
225  >> ETsystemMatrix->block (1, 0);
226  }
227 
228  ETsystemMatrix->globalAssemble();
229 
230  if (verbose)
231  {
232  std::cout << " done! " << std::endl;
233  }
234 
235 
236  // ---------------------------------------------------------------
237  // For testing purposes, we also compute the norm of the matrix.
238  // ---------------------------------------------------------------
239 
240  Real matrixNorm (ETsystemMatrix->normInf() );
241 
242  std::cout.precision (15);
243  if (verbose)
244  {
245  std::cout << " Matrix norm " << matrixNorm << std::endl;
246  }
247 
248  // ---------------------------------------------------------------
249  // In a very similar way, we can assemble the block right hand
250  // side. Here, we suppose that a force acts on the fluid, so
251  // only the block associated to the velocity is not empty.
252  // ---------------------------------------------------------------
253 
254  if (verbose)
255  {
256  std::cout << " -- Building the rhs ... " << std::flush;
257  }
258 
259  vector_Type fInterpolated (ETuSpace->map(), Repeated);
260 
261  fInterpolated *= 0.0;
262 
263  uSpace->interpolate (static_cast<FESpace< mesh_Type, MapEpetra >::function_Type> (forceFct), fInterpolated, 0.0);
264 
265  blockVector_Type ETrhs (ETuSpace->map() | ETpSpace->map() , Repeated);
266  ETrhs *= 0.0;
267 
268  {
269  using namespace ExpressionAssembly;
270 
271  integrate ( elements (ETuSpace->mesh() ),
272  quadRuleTetra4pt,
273  ETuSpace,
274  dot (value (ETuSpace, fInterpolated), phi_i)
275  )
276  >> ETrhs.block (0);
277  }
278 
279  ETrhs.globalAssemble();
280 
281  if (verbose)
282  {
283  std::cout << " done! " << std::endl;
284  }
285 
286  // ---------------------------------------------------------------
287  // For testing purposes, we also compute the norm of the rhs. To
288  // take the norm, we need a unique vector (globalAssemble is not
289  // sufficient).
290  // ---------------------------------------------------------------
291 
292  blockVector_Type ETrhsUnique (ETrhs, Unique);
293 
294  Real rhsNorm (ETrhsUnique.normInf() );
295 
296  if (verbose)
297  {
298  std::cout << " Rhs norm " << rhsNorm << std::endl;
299  }
300 
301  // ---------------------------------------------------------------
302  // Finally we return a vector containing both norms
303  // ---------------------------------------------------------------
304 
305  std::vector<Real> errorNorms (2);
306  errorNorms[0] = matrixNorm;
307  errorNorms[1] = rhsNorm;
308 
309  return errorNorms;
310 
311 } // run
MatrixEpetraStructured< Real > blockMatrix_Type
MatrixEpetra< Real > matrix_Type
VectorEpetra vector_Type
Real forceFct(const Real &, const Real &, const Real &y, const Real &, const ID &)
Functions.
uint32_type ID
IDs.
Definition: LifeV.hpp:194
double Real
Generic real data.
Definition: LifeV.hpp:175
RegionMesh< LinearTriangle > mesh_Type
VectorEpetraStructured blockVector_Type
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191