LifeV
testsuite/repeated_mesh_2D/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 05-2012
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/LifeChrono.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 
88 
93 
100 
101 int main ( int argc, char** argv )
102 {
103 
104 #ifdef HAVE_MPI
105  MPI_Init (&argc, &argv);
106 #endif
107 
108  // introducing a local scope in order to properly destroy all objects
109  // before calling MPI_Finalize()
110  {
111 
112 #ifdef HAVE_MPI
113  std::shared_ptr<Epetra_Comm> comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
114 #else
115  std::shared_ptr<Epetra_Comm> comm ( new Epetra_SerialComm );
116 #endif
117 
118  GetPot dataFile ( "data_2d" );
119  const bool isLeader ( comm->MyPID() == 0 );
120  const bool verbose ( dataFile ( "miscellaneous/verbose", 0 ) && isLeader );
121 
122 #ifdef HAVE_LIFEV_DEBUG
123  std::ofstream debugOut (
124  ( "rm." +
125  ( comm->NumProc() > 1 ? std::to_string ( comm->MyPID() ) : "s" ) +
126  ".out" ).c_str() );
127 #else
128  std::ofstream debugOut ( "/dev/null" );
129 #endif
130 
131  // Build and partition the mesh
132 
133  if ( verbose )
134  {
135  std::cout << " -- Reading the mesh ... " << std::flush;
136  }
137  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type() );
138  if ( dataFile ( "mesh/mesh_type", "structured" ) == "structured" )
139  {
140  regularMesh2D ( *fullMeshPtr, 0,
141  dataFile ( "mesh/nx", 20 ), dataFile ( "mesh/ny", 20 ),
142  dataFile ( "mesh/verbose", false ),
143  dataFile ( "mesh/lx", 1. ), dataFile ( "mesh/ly", 1. ) );
144  }
145  else
146  {
147  MeshData meshData (dataFile, "mesh");
148  readMesh (*fullMeshPtr, meshData);
149  }
150  if ( verbose )
151  {
152  std::cout << " done ! " << std::endl;
153  }
154  if ( isLeader )
155  {
156  std::cout << "mesh elements = " << fullMeshPtr->numElements() << "\n"
157  << "mesh points = " << fullMeshPtr->numPoints() << std::endl;
158  }
159 
160  if ( verbose )
161  {
162  std::cout << " -- Partitioning the mesh ... " << std::flush;
163  }
164 
165  LifeChrono partTime;
166  partTime.start();
167  std::shared_ptr< mesh_Type > localMesh;
168  {
169  MeshPartitioner< mesh_Type > meshPart;
170  meshPart.doPartition ( fullMeshPtr, comm );
171  localMesh = meshPart.meshPartition();
172  }
173  partTime.stop();
174  if ( isLeader )
175  {
176  std::cout << "partitioning time = " << partTime.diff() << std::endl;
177  }
178  if ( isLeader )
179  {
180  std::cout << "part mesh elements = " << localMesh->numElements() << "\n"
181  << "part mesh points = " << localMesh->numPoints() << std::endl;
182  }
183 
184  // localMesh->mesh_Type::showMe( true, debugOut );
185 
186  LifeChrono partTimeR;
187  partTimeR.start();
188  std::shared_ptr< mesh_Type > localMeshR;
189  {
190  MeshPartitioner< mesh_Type > meshPartR;
191  meshPartR.setPartitionOverlap ( 1 );
192  meshPartR.doPartition ( fullMeshPtr, comm );
193  localMeshR = meshPartR.meshPartition();
194  }
195  partTimeR.stop();
196  if ( isLeader )
197  {
198  std::cout << "partitioningR time = " << partTimeR.diff() << std::endl;
199  }
200 
201  // debugOut << "============================" << std::endl;
202  // localMeshR->mesh_Type::showMe( true, debugOut );
203  if ( verbose )
204  {
205  std::cout << " done ! " << std::endl;
206  }
207 
208  if ( verbose )
209  {
210  std::cout << " -- Freeing the global mesh ... " << std::flush;
211  }
212  fullMeshPtr.reset();
213  if ( verbose )
214  {
215  std::cout << " done ! " << std::endl;
216  }
217 
218  // Build the FESpaces
219 
220  if ( verbose )
221  {
222  std::cout << " -- Building FESpaces ... " << std::flush;
223  }
224  uSpaceStdPtr_Type uSpaceStd ( new uSpaceStd_Type ( localMesh, "P2", 2, comm ) );
225  uSpaceStdPtr_Type uSpaceStdR ( new uSpaceStd_Type ( localMeshR, "P2", 2, comm ) );
226 
227  uSpacePtr_Type uSpace ( new uSpace_Type ( localMesh, &feTriaP2, & (uSpaceStd->fe().geoMap() ), comm) );
228  uSpacePtr_Type uSpaceR ( new uSpace_Type ( localMeshR, &feTriaP2, & (uSpaceStdR->fe().geoMap() ), comm) );
229 
230  pSpacePtr_Type pSpace ( new pSpace_Type ( localMesh, &feTriaP1, & (uSpaceStd->fe().geoMap() ), comm) );
231  pSpacePtr_Type pSpaceR ( new pSpace_Type ( localMeshR, &feTriaP1, & (uSpaceStdR->fe().geoMap() ), comm) );
232 
233  if ( verbose )
234  {
235  std::cout << " done ! " << std::endl;
236  }
237  if ( verbose )
238  {
239  std::cout << " ---> Dofs: " << uSpace->dof().numTotalDof() << std::endl;
240  }
241 
242  // Build the assembler and the matrices
243 
244  if ( verbose )
245  {
246  std::cout << " -- Defining the matrix ... " << std::flush;
247  }
248  matrixPtr_Type systemMatrix ( new matrix_Type ( uSpace->map() | pSpace->map() ) );
249  matrixPtr_Type systemMatrixR ( new matrix_Type ( uSpaceR->map() | pSpaceR->map(), 50, true ) );
250  if ( verbose )
251  {
252  std::cout << " done! " << std::endl;
253  }
254 
255  {
256  using namespace ExpressionAssembly;
257 
258  integrate ( elements ( localMesh ),
259  quadRuleTria3pt,
260  uSpace,
261  uSpace,
262 
263  dot ( grad (phi_i) , grad (phi_j) )
264 
265  )
266  >> systemMatrix->block (0, 0);
267 
268  integrate ( elements ( localMesh ),
269  quadRuleTria3pt,
270  uSpace,
271  pSpace,
272 
273  phi_j * div (phi_i)
274 
275  )
276  >> systemMatrix->block (0, 1);
277 
278  integrate ( elements ( localMesh ),
279  quadRuleTria3pt,
280  pSpace,
281  uSpace,
282 
283  phi_i * div (phi_j)
284 
285  )
286  >> systemMatrix->block (1, 0);
287  }
288 
289  systemMatrix->globalAssemble();
290 
291  {
292  using namespace ExpressionAssembly;
293 
294  integrate ( elements ( localMeshR ),
295  quadRuleTria3pt,
296  uSpaceR,
297  uSpaceR,
298 
299  dot ( grad (phi_i) , grad (phi_j) )
300 
301  )
302  >> systemMatrixR->block (0, 0);
303 
304  integrate ( elements ( localMeshR ),
305  quadRuleTria3pt,
306  uSpaceR,
307  pSpaceR,
308 
309  phi_j * div (phi_i)
310 
311  )
312  >> systemMatrixR->block (0, 1);
313 
314  integrate ( elements ( localMeshR ),
315  quadRuleTria3pt,
316  pSpaceR,
317  uSpaceR,
318 
319  phi_i * div (phi_j)
320 
321  )
322  >> systemMatrixR->block (1, 0);
323  }
324 
325  systemMatrixR->fillComplete();
326 
327  // SPY
328  //systemMatrix->spy("matrixNoBC");
329  //systemMatrixR->spy("matrixNoBCR");
330 
331  // check that the assembled matrices are the same
332 
333  matrix_Type matrixDiff ( *systemMatrix );
334  matrixDiff -= *systemMatrixR;
335 
336  Real diff = matrixDiff.normInf();
337 
338  if ( isLeader )
339  {
340  std::cout << "Norm of the difference between the 2 matrices = " << diff << std::endl;
341  }
342 
343  if ( verbose )
344  {
345  std::cout << " -- Building the RHS ... " << std::flush;
346  }
347 
348  vector_Type rhs ( uSpaceStd->map() | pSpace->map(), Unique );
349 
350  vectorStd_Type fInterpolated ( uSpace->map(), Repeated );
351  uSpaceStd->interpolate ( static_cast<uSpaceStd_Type::function_Type> (fRhs), fInterpolated, 0.0 );
352 
353  {
354  using namespace ExpressionAssembly;
355 
356  integrate ( elements ( localMesh ),
357  quadRuleTria3pt,
358  uSpace,
359  dot (value (uSpace, fInterpolated), phi_i)
360  )
361  >> rhs.block (0);
362  }
363 
364  debugOut << "noGA\n" << rhs.epetraVector();
365 
366  rhs.globalAssemble();
367 
368  debugOut << "\n" << rhs.epetraVector();
369 
370  vector_Type rhsR ( uSpaceStdR->map() | pSpaceR->map(), Unique, Zero );
371 
372  vectorStd_Type fInterpolatedR ( uSpaceR->map(), Repeated );
373  uSpaceStdR->interpolate ( static_cast<uSpaceStd_Type::function_Type> (fRhs), fInterpolatedR, 0.0 );
374 
375  {
376  using namespace ExpressionAssembly;
377 
378  integrate ( elements ( localMeshR ),
379  quadRuleTria3pt,
380  uSpaceR,
381  dot (value (uSpaceR, fInterpolatedR), phi_i)
382  )
383  >> rhsR.block (0);
384  }
385 
386  debugOut << "RnoGA\n" << rhsR.epetraVector();
387 
388  rhsR.globalAssemble();
389 
390  debugOut << "R\n" << rhsR.epetraVector();
391 
392  vector_Type vectorDiff ( rhs );
393  vectorDiff -= rhsR;
394 
395  Real diffNormV = vectorDiff.normInf();
396 
397  if ( isLeader )
398  {
399  std::cout << "Norm of the difference between the 2 vectors = " << diffNormV << std::endl;
400  }
401 
402  diff += diffNormV;
403 
404  if ( diff < 1.e-14 )
405  {
406  if ( isLeader )
407  {
408  std::cout << "End Result: TEST PASSED" << std::endl;
409  }
410  }
411  else
412  {
413  return EXIT_FAILURE;
414  }
415  }
416 
417 #ifdef HAVE_MPI
418  MPI_Finalize();
419 #endif
420 
421  return EXIT_SUCCESS;
422 }
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
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< matrix_Type > matrixPtr_Type