LifeV
examples/stokes_repeated_mesh/main_2d.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 /*!
28  @file
29  @brief
30 
31  @author Antonio Cervone <ant.cervone@gmail.com>
32  @date 2013-07-15
33  */
34 
35 
36 #include <Epetra_ConfigDefs.h>
37 #ifdef EPETRA_MPI
38 #include <mpi.h>
39 #include <Epetra_MpiComm.h>
40 #else
41 #include <Epetra_SerialComm.h>
42 #endif
43 
44 
45 #include <lifev/core/LifeV.hpp>
46 
47 #include <lifev/core/util/LifeChronoManager.hpp>
48 
49 #include <lifev/core/array/MatrixEpetraStructured.hpp>
50 #include <lifev/core/array/VectorEpetraStructured.hpp>
51 
52 #include <lifev/core/fem/FESpace.hpp>
53 
54 #include <lifev/core/mesh/MeshPartitioner.hpp>
55 #include <lifev/core/mesh/RegionMesh2DStructured.hpp>
56 #include <lifev/core/mesh/RegionMesh.hpp>
57 #include <lifev/core/mesh/MeshData.hpp>
58 
59 #include <lifev/eta/fem/ETFESpace.hpp>
60 #include <lifev/eta/expression/Integrate.hpp>
61 
62 using namespace LifeV;
63 
64 Real exactSolution ( const Real& /* t */, const Real& x, const Real& y, const Real& /* z */, const ID& /* i */ )
65 {
66  return sin ( x ) + y * y / 2.;
67 }
68 
69 Real fRhs ( const Real& /* t */, const Real& /* x */, const Real& /* y */, const Real& /* z */ , const ID& i )
70 {
71  switch ( i )
72  {
73  case 0:
74  return 0.;
75  break;
76  case 1:
77  return 1.;
78  break;
79  default:
80  ERROR_MSG ( "component not available!" );
81  }
82 
83  return 0.;
84 }
85 
86 
89 
91 
96 
103 
104 int main ( int argc, char** argv )
105 {
106 
107 #ifdef HAVE_MPI
108  MPI_Init (&argc, &argv);
109 #endif
110 
111  int returnValue = 0;
112 
113  // introducing a local scope in order to properly destroy all objects
114  // before calling MPI_Finalize()
115  {
116 #ifdef HAVE_MPI
117  commPtr_Type comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
118 #else
119  commPtr_Type comm ( new Epetra_SerialComm );
120 #endif
121  LifeChronoManager<> chronoMgr ( comm );
122 
123  LifeChrono initTime;
124  chronoMgr.add ( "Initialization Time", &initTime );
125  initTime.start();
126 
127  GetPot dataFile ( "data_2d" );
128  const bool isLeader ( comm->MyPID() == 0 );
129  const bool verbose ( dataFile ( "miscellaneous/verbose", 0 ) && isLeader );
130 
131 #ifdef HAVE_LIFEV_DEBUG
132  std::ofstream debugOut (
133  ( "rm." +
134  ( comm->NumProc() > 1 ? std::to_string ( comm->MyPID() ) : "s" ) +
135  ".out" ).c_str() );
136 #else
137  std::ofstream debugOut ( "/dev/null" );
138 #endif
139 
140  initTime.stop();
141 
142  // Build and partition the mesh
143 
144  LifeChrono meshTime;
145  chronoMgr.add ( "Mesh reading/creation Time", &initTime );
146  meshTime.start();
147 
148  if ( verbose )
149  {
150  std::cout << " -- Reading the mesh ... " << std::flush;
151  }
152  meshPtr_Type fullMeshPtr (new mesh_Type() );
153  if ( dataFile ( "mesh/mesh_type", "structured" ) == "structured" )
154  {
155  regularMesh2D ( *fullMeshPtr, 0,
156  dataFile ( "mesh/nx", 20 ), dataFile ( "mesh/ny", 20 ),
157  dataFile ( "mesh/verbose", false ),
158  dataFile ( "mesh/lx", 1. ), dataFile ( "mesh/ly", 1. ) );
159  }
160  else
161  {
162  MeshData meshData (dataFile, "mesh");
163  readMesh (*fullMeshPtr, meshData);
164  }
165  if ( verbose )
166  {
167  std::cout << " done ! " << std::endl;
168  }
169  if ( isLeader )
170  {
171  std::cout << "mesh elements = " << fullMeshPtr->numElements() << "\n"
172  << "mesh points = " << fullMeshPtr->numPoints() << std::endl;
173  }
174 
175  meshTime.stop();
176 
177  if ( verbose )
178  {
179  std::cout << " -- Partitioning the mesh ... " << std::flush;
180  }
181 
182  LifeChrono partTime;
183  chronoMgr.add ( "Partition Time", &partTime );
184  partTime.start();
185  meshPtr_Type localMesh;
186  {
187  MeshPartitioner< mesh_Type > meshPart;
188  meshPart.doPartition ( fullMeshPtr, comm );
189  localMesh = meshPart.meshPartition();
190  }
191  partTime.stop();
192 
193  Int localMeshNum[ 2 ];
194  localMeshNum[ 0 ] = localMesh->numElements();
195  localMeshNum[ 1 ] = localMesh->numPoints();
196  Int maxMeshNum[ 2 ] = { 0, 0 };
197  comm->MaxAll ( localMeshNum, maxMeshNum, 2 );
198 
199  if ( isLeader )
200  {
201  std::cout << "part mesh elements = " << maxMeshNum[ 0 ] << "\n"
202  << "part mesh points = " << maxMeshNum[ 1 ] << std::endl;
203  }
204 
205  LifeChrono partTimeR;
206  chronoMgr.add ( "Partition Time (R)", &partTimeR );
207  partTimeR.start();
208  meshPtr_Type localMeshR;
209  {
210  MeshPartitioner< mesh_Type > meshPartR;
211  meshPartR.setPartitionOverlap ( 1 );
212  meshPartR.doPartition ( fullMeshPtr, comm );
213  localMeshR = meshPartR.meshPartition();
214  }
215  partTimeR.stop();
216 
217  localMeshNum[ 0 ] = localMeshR->numElements();
218  localMeshNum[ 1 ] = localMeshR->numPoints();
219  maxMeshNum[ 0 ] = 0;
220  maxMeshNum[ 1 ] = 0;
221  comm->MaxAll ( localMeshNum, maxMeshNum, 2 );
222 
223  if ( isLeader )
224  {
225  std::cout << "part mesh elements (R) = " << maxMeshNum[ 0 ] << "\n"
226  << "part mesh points (R) = " << maxMeshNum[ 1 ] << std::endl;
227  }
228 
229  if ( verbose )
230  {
231  std::cout << " done ! " << std::endl;
232  }
233 
234  if ( verbose )
235  {
236  std::cout << " -- Freeing the global mesh ... " << std::flush;
237  }
238 
239  fullMeshPtr.reset();
240 #ifdef HAVE_LIFEV_DEBUG
241  ASSERT ( fullMeshPtr.use_count() == 0, "full mesh not properly freed." );
242 #endif
243  if ( verbose )
244  {
245  std::cout << " done ! " << std::endl;
246  }
247 
248  // Build the FESpaces
249 
250  if ( verbose )
251  {
252  std::cout << " -- Building FESpaces ... " << std::flush;
253  }
254  LifeChrono feSpaceTime;
255  chronoMgr.add ( "FESpace creation Time", &feSpaceTime );
256  feSpaceTime.start();
257  uSpaceStdPtr_Type uSpaceStd ( new uSpaceStd_Type ( localMesh, "P2", 2, comm ) );
258  uSpacePtr_Type uSpace ( new uSpace_Type ( localMesh, &feTriaP2, & (uSpaceStd->fe().geoMap() ), comm) );
259  pSpacePtr_Type pSpace ( new pSpace_Type ( localMesh, &feTriaP1, & (uSpaceStd->fe().geoMap() ), comm) );
260  feSpaceTime.stop();
261 
262  LifeChrono feSpaceTimeR;
263  chronoMgr.add ( "FESpace creation Time (R)", &feSpaceTimeR );
264  feSpaceTimeR.start();
265  uSpaceStdPtr_Type uSpaceStdR ( new uSpaceStd_Type ( localMeshR, "P2", 2, comm ) );
266  uSpacePtr_Type uSpaceR ( new uSpace_Type ( localMeshR, &feTriaP2, & (uSpaceStdR->fe().geoMap() ), comm) );
267  pSpacePtr_Type pSpaceR ( new pSpace_Type ( localMeshR, &feTriaP1, & (uSpaceStdR->fe().geoMap() ), comm) );
268  feSpaceTimeR.stop();
269 
270  if ( verbose )
271  {
272  std::cout << " done ! " << std::endl;
273  }
274  if ( verbose )
275  {
276  std::cout << " ---> Dofs: " << uSpace->dof().numTotalDof() << std::endl;
277  }
278 
279  // Build the assembler and the matrices
280 
281  if ( verbose )
282  {
283  std::cout << " -- Defining and filling the matrix ... " << std::flush;
284  }
285 
286  LifeChrono matTime;
287  chronoMgr.add ( "Matrix creation Time", &matTime );
288  matTime.start();
289  matrixPtr_Type systemMatrix ( new matrix_Type ( uSpace->map() | pSpace->map() ) );
290  matTime.stop();
291 
292  LifeChrono assemblyTime;
293  chronoMgr.add ( "Assembly Time", &assemblyTime );
294  assemblyTime.start();
295  {
296  using namespace ExpressionAssembly;
297 
298  integrate ( elements ( localMesh ),
299  quadRuleTria3pt,
300  uSpace,
301  uSpace,
302 
303  dot ( grad (phi_i) , grad (phi_j) )
304 
305  )
306  >> systemMatrix->block (0, 0);
307 
308  integrate ( elements ( localMesh ),
309  quadRuleTria3pt,
310  uSpace,
311  pSpace,
312 
313  phi_j * div (phi_i)
314 
315  )
316  >> systemMatrix->block (0, 1);
317 
318  integrate ( elements ( localMesh ),
319  quadRuleTria3pt,
320  pSpace,
321  uSpace,
322 
323  phi_i * div (phi_j)
324 
325  )
326  >> systemMatrix->block (1, 0);
327  }
328  systemMatrix->globalAssemble();
329  assemblyTime.stop();
330 
331  LifeChrono matTimeR;
332  chronoMgr.add ( "Matrix creation Time (R)", &matTimeR );
333  matTimeR.start();
334  matrixPtr_Type systemMatrixR ( new matrix_Type ( uSpaceR->map() | pSpaceR->map(), 50, true ) );
335  matTimeR.stop();
336 
337  LifeChrono assemblyTimeR;
338  chronoMgr.add ( "Assembly Time (R)", &assemblyTimeR );
339  assemblyTimeR.start();
340  {
341  using namespace ExpressionAssembly;
342 
343  integrate ( elements ( localMeshR ),
344  quadRuleTria3pt,
345  uSpaceR,
346  uSpaceR,
347 
348  dot ( grad (phi_i) , grad (phi_j) )
349 
350  )
351  >> systemMatrixR->block (0, 0);
352 
353  integrate ( elements ( localMeshR ),
354  quadRuleTria3pt,
355  uSpaceR,
356  pSpaceR,
357 
358  phi_j * div (phi_i)
359 
360  )
361  >> systemMatrixR->block (0, 1);
362 
363  integrate ( elements ( localMeshR ),
364  quadRuleTria3pt,
365  pSpaceR,
366  uSpaceR,
367 
368  phi_i * div (phi_j)
369 
370  )
371  >> systemMatrixR->block (1, 0);
372  }
373  systemMatrixR->fillComplete();
374  assemblyTime.stop();
375 
376  if ( verbose )
377  {
378  std::cout << " done! " << std::endl;
379  }
380 
381  // check that the assembled matrices are the same
382 
383  LifeChrono checkMatTime;
384  chronoMgr.add ( "Check (Matrix) Time", &checkMatTime );
385  checkMatTime.start();
386  matrix_Type matrixDiff ( *systemMatrix );
387  matrixDiff -= *systemMatrixR;
388 
389  Real diff = matrixDiff.normInf();
390  checkMatTime.stop();
391 
392  if ( isLeader )
393  {
394  std::cout << "Norm of the difference between the 2 matrices = " << diff << std::endl;
395  }
396 
397  if ( verbose )
398  {
399  std::cout << " -- Building the RHS ... " << std::flush;
400  }
401 
402  LifeChrono rhsTime;
403  chronoMgr.add ( "Rhs build Time", &rhsTime );
404  rhsTime.start();
405  vector_Type rhs ( uSpaceStd->map() | pSpace->map(), Unique );
406 
407  vectorStd_Type fInterpolated ( uSpace->map(), Repeated );
408  uSpaceStd->interpolate ( static_cast<uSpaceStd_Type::function_Type> (fRhs), fInterpolated, 0.0 );
409 
410  {
411  using namespace ExpressionAssembly;
412 
413  integrate ( elements ( localMesh ),
414  quadRuleTria3pt,
415  uSpace,
416  dot (value (uSpace, fInterpolated), phi_i)
417  )
418  >> rhs.block (0);
419  }
420  rhs.globalAssemble();
421  rhsTime.stop();
422 
423  LifeChrono rhsTimeR;
424  chronoMgr.add ( "Rhs build Time (R)", &rhsTimeR );
425  rhsTimeR.start();
426  vector_Type rhsR ( uSpaceStdR->map() | pSpaceR->map(), Unique, Zero );
427 
428  vectorStd_Type fInterpolatedR ( uSpaceR->map(), Repeated );
429  uSpaceStdR->interpolate ( static_cast<uSpaceStd_Type::function_Type> (fRhs), fInterpolatedR, 0.0 );
430 
431  {
432  using namespace ExpressionAssembly;
433 
434  integrate ( elements ( localMeshR ),
435  quadRuleTria3pt,
436  uSpaceR,
437  dot (value (uSpaceR, fInterpolatedR), phi_i)
438  )
439  >> rhsR.block (0);
440  }
441  rhsR.globalAssemble();
442  rhsTimeR.stop();
443 
444  LifeChrono checkVecTime;
445  chronoMgr.add ( "Check (Vector) Time", &checkVecTime );
446  checkVecTime.start();
447  vector_Type vectorDiff ( rhs );
448  vectorDiff -= rhsR;
449 
450  Real diffNormV = vectorDiff.normInf();
451  checkVecTime.stop();
452 
453  if ( isLeader )
454  {
455  std::cout << "Norm of the difference between the 2 vectors = " << diffNormV << std::endl;
456  }
457 
458  diff += diffNormV;
459 
460  if ( diff < 1.e-14 )
461  {
462  returnValue = EXIT_SUCCESS;
463  if ( isLeader )
464  {
465  std::cout << "End Result: TEST PASSED" << std::endl;
466  }
467  }
468  else
469  {
470  returnValue = EXIT_FAILURE;
471  }
472 
473  // print out times
474  chronoMgr.print();
475  }
476 
477 #ifdef HAVE_MPI
478  MPI_Finalize();
479 #endif
480 
481  return returnValue;
482 }
VectorEpetra - The Epetra Vector format Wrapper.
int main(int argc, char **argv)
Real exactSolution(const Real &, const Real &x, const Real &y, const Real &, const ID &)
std::shared_ptr< uSpaceStd_Type > uSpaceStdPtr_Type
Real fRhs(const Real &, const Real &, const Real &, const Real &, const ID &i)
FESpace< mesh_Type, MapEpetra > uSpaceStd_Type
MatrixEpetraStructured< Real > matrix_Type
ETFESpace< mesh_Type, MapEpetra, 2, 1 > pSpace_Type
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
VectorEpetraStructured - class of block vector.
VectorEpetraStructured vector_Type
VectorEpetra vectorStd_Type
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
std::shared_ptr< pSpace_Type > pSpacePtr_Type
uint32_type ID
IDs.
Definition: LifeV.hpp:194
RegionMesh< LinearTriangle > mesh_Type
ETFESpace< mesh_Type, MapEpetra, 2, 2 > uSpace_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
std::shared_ptr< Epetra_Comm > commPtr_Type
MatrixEpetraStructured - class of block matrix.
class ETFESpace A light, templated version of the FESpace
Definition: ETFESpace.hpp:93
std::shared_ptr< uSpace_Type > uSpacePtr_Type
std::shared_ptr< mesh_Type > meshPtr_Type
std::shared_ptr< matrix_Type > matrixPtr_Type