LifeV
lifev/eta/testsuite/static_graph/main.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 Test for building matrices with a static graph and ETA
30 
31  @author Radu Popescu <radu.popescu@epfl.ch>
32  @date 2012-03-19
33  */
34 
35 #include <cstdlib>
36 
37 #include <Epetra_ConfigDefs.h>
38 #ifdef EPETRA_MPI
39 #include <mpi.h>
40 #include <Epetra_MpiComm.h>
41 #else
42 #include <Epetra_SerialComm.h>
43 #endif
44 
45 #include <Epetra_FECrsGraph.h>
46 
47 #include <lifev/core/LifeV.hpp>
48 #include <lifev/core/util/LifeChrono.hpp>
49 
50 #include <lifev/core/mesh/MeshPartitioner.hpp>
51 #include <lifev/core/mesh/RegionMesh3DStructured.hpp>
52 #include <lifev/core/mesh/RegionMesh.hpp>
53 
54 #include <lifev/core/array/MatrixEpetra.hpp>
55 
56 #include <lifev/eta/fem/ETFESpace.hpp>
57 
58 #include <lifev/eta/expression/Integrate.hpp>
59 #include <lifev/eta/expression/BuildGraph.hpp>
60 
61 
62 #include <boost/shared_ptr.hpp>
63 
64 
65 using namespace LifeV;
66 
68 typedef MatrixEpetra<Real> matrix_Type;
69 
70 int main ( int argc, char** argv )
71 {
72 
73 #ifdef HAVE_MPI
74  MPI_Init (&argc, &argv);
75  std::shared_ptr<Epetra_Comm> Comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
76 #else
77  std::shared_ptr<Epetra_Comm> Comm (new Epetra_SerialComm);
78 #endif
79 
80  const bool verbose (Comm->MyPID() == 0);
81 
82  if (argc != 2)
83  {
84  if (verbose)
85  {
86  std::cout << "Please run program as " << argv[0]
87  << " " << "<num_elements>\n";
88  return EXIT_FAILURE;
89  }
90  }
91 
92  const UInt Nelements = std::atoi (argv[1]);
93 
94  if (verbose)
95  {
96  std::cout << " -- Building and partitioning the mesh ... " << std::flush;
97  }
98 
99  std::shared_ptr< mesh_Type > fullMeshPtr (new mesh_Type);
100 
101  regularMesh3D ( *fullMeshPtr, 1, Nelements, Nelements, Nelements, false,
102  2.0, 2.0, 2.0,
103  -1.0, -1.0, -1.0);
104 
105  MeshPartitioner< mesh_Type > meshPart (fullMeshPtr, Comm);
106 
107  fullMeshPtr.reset();
108 
109  if (verbose)
110  {
111  std::cout << " done ! " << std::endl;
112  }
113 
114 
115  if (verbose)
116  {
117  std::cout << " -- Building ETFESpaces ... " << std::flush;
118  }
119 
120  std::shared_ptr<ETFESpace< mesh_Type, MapEpetra, 3, 1 > > uSpace
121  ( new ETFESpace< mesh_Type, MapEpetra, 3, 1 > (meshPart, &feTetraP1, Comm) );
122 
123  if (verbose)
124  {
125  std::cout << " done ! " << std::endl;
126  }
127  if (verbose)
128  {
129  std::cout << " ---> Dofs: " << uSpace->dof().numTotalDof() << std::endl;
130  }
131 
132  std::shared_ptr<matrix_Type> closedSystemMatrix;
133  std::shared_ptr<matrix_Type> openSystemMatrix;
134 
135  if (verbose)
136  {
137  std::cout << " -- Precomputing matrix graph ... " << std::flush;
138  }
139 
140  LifeChrono feLoopTimer;
141  feLoopTimer.start();
142  std::shared_ptr<Epetra_FECrsGraph> matrixGraph;
143  {
144  using namespace ExpressionAssembly;
145 
146  // We first build a static graph for our problem matrix
147  matrixGraph.reset (new Epetra_FECrsGraph (Copy, * (uSpace->map().map (Unique) ), 0) );
148 
149  buildGraph ( elements (uSpace->mesh() ),
150  quadRuleTetra4pt,
151  uSpace,
152  uSpace,
153  dot ( grad (phi_i) , grad (phi_j) )
154  ) >> matrixGraph;
155  }
156  matrixGraph->GlobalAssemble();
157  feLoopTimer.stop();
158 
159  if (verbose)
160  {
161  std::cout << " done in " << feLoopTimer.diff() << "s." << std::endl;
162  }
163 
164  if (verbose)
165  {
166  std::cout << " -- Assembling the Laplace matrix with a precomputed graph ... " << std::flush;
167  }
168 
169  feLoopTimer.start();
170  {
171  using namespace ExpressionAssembly;
172 
173  // We build the system matrix using the precomputed graph
174  closedSystemMatrix.reset (new matrix_Type ( uSpace->map(), *matrixGraph ) );
175  *closedSystemMatrix *= 0.0;
176 
177  // Finally, we perform the FE assembly, which should be faster with
178  // a closed matrix
179  integrate ( elements (uSpace->mesh() ),
180  quadRuleTetra4pt,
181  uSpace,
182  uSpace,
183  dot ( grad (phi_i) , grad (phi_j) )
184  ) >> closedSystemMatrix;
185 
186  closedSystemMatrix->globalAssemble();
187  }
188  feLoopTimer.stop();
189 
190  if (verbose)
191  {
192  std::cout << " done in " << feLoopTimer.diff() << "s." << std::endl;
193  }
194 
195  if (verbose)
196  {
197  std::cout << " -- Assembling the Laplace matrix without graph ... " << std::flush;
198  }
199 
200  feLoopTimer.start();
201  {
202  using namespace ExpressionAssembly;
203 
204  openSystemMatrix.reset (new matrix_Type ( uSpace->map() ) );
205  *openSystemMatrix *= 0.0;
206 
207  // Finally, we perform the FE assembly, which should be faster with
208  // a closed matrix
209  integrate ( elements (uSpace->mesh() ),
210  quadRuleTetra4pt,
211  uSpace,
212  uSpace,
213  dot ( grad (phi_i) , grad (phi_j) )
214  ) >> openSystemMatrix;
215 
216  openSystemMatrix->globalAssemble();
217  }
218  feLoopTimer.stop();
219 
220  if (verbose)
221  {
222  std::cout << " done in " << feLoopTimer.diff() << "s." << std::endl;
223  }
224 
225  Real closedMatrixNorm ( closedSystemMatrix->normInf() );
226  Real openMatrixNorm ( openSystemMatrix->normInf() );
227 
228  if (verbose)
229  {
230  std::cout << " Closed matrix norm : " << closedMatrixNorm << std::endl;
231  std::cout << " Open matrix norm : " << openMatrixNorm << std::endl;
232  }
233 
234 #ifdef HAVE_MPI
235  MPI_Finalize();
236 #endif
237 
238  Real closedMatrixNormDiff (std::abs (closedMatrixNorm - 3.2) );
239  Real openMatrixNormDiff (std::abs (openMatrixNorm - 3.2) );
240 
241  if (verbose)
242  {
243  std::cout << " Error (closed): " << closedMatrixNormDiff << std::endl;
244  std::cout << " Error (open): " << openMatrixNormDiff << std::endl;
245  }
246 
247  Real testTolerance (1e-10);
248 
249  if ( closedMatrixNormDiff >= testTolerance )
250  {
251  return ( EXIT_FAILURE );
252  }
253  if ( openMatrixNormDiff >= testTolerance )
254  {
255  return ( EXIT_FAILURE );
256  }
257  return ( EXIT_SUCCESS );
258 
259 }
int main(int argc, char **argv)
MatrixEpetra< Real > matrix_Type
double Real
Generic real data.
Definition: LifeV.hpp:175
RegionMesh< LinearTetra > mesh_Type