LifeV
test_q2_mesh.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 test_q2_mesh.cpp
29  * @brief Fair comparison between a Q1 mesh and a Q2 mesh (2D).
30  * @author Simone Pezzuto <simone.pezzuto@mail.polimi.it>
31 **/
32 
33 #include <Epetra_ConfigDefs.h>
34 #ifdef HAVE_MPI
35 #include <mpi.h>
36 #include <Epetra_MpiComm.h>
37 #else
38 #include <Epetra_SerialComm.h>
39 #endif
40 
41 #include <boost/shared_ptr.hpp>
42 
43 #include <lifev/core/LifeV.cpp>
44 #include <lifev/core/filter/ParserGmsh.hpp>
45 #include <lifev/core/mesh/ConvertBareMesh.hpp>
46 
47 #include <lifev/core/fem/GeometricMap.hpp>
48 #include <lifev/core/fem/ReferenceFEScalar.hpp>
49 #include <lifev/core/fem/CurrentFE.hpp>
50 
51 #include <cstdlib>
52 #include <iostream>
53 #include <cmath>
54 
55 template <typename S>
56 struct tester
57 {
58  typedef typename LifeV::BareMesh<S> baremesh_t;
59  typedef typename LifeV::RegionMesh<S> mesh_t;
63 
64  typedef typename mesh_t::elements_Type elms_t;
65  typedef typename elms_t::const_iterator elms_citer;
66 
68  const reffem_t& reffem,
69  const geomap_t& geomap,
70  comm_t comm)
71  {
72  bool ilead = (comm->MyPID() == 0);
73 
74  baremesh_t baremesh;
75 
76  if (!LifeV::MeshIO::ReadGmshFile (filename, baremesh, 1, ilead) )
77  {
78  return false;
79  }
80 
81  // Convert the mesh
82  std::shared_ptr<mesh_t> mesh (new mesh_t (comm) );
83  LifeV::convertBareMesh (baremesh, *mesh, ilead);
84 
85  // The current finite element
86  LifeV::CurrentFE curFE (reffem, geomap, LifeV::quadRuleQuad4pt);
87  // List of all the elements
88  elms_t& elms = mesh->elementList();
89 
90  LifeV::Real area (0.0);
91 
92  // For every element ...
93  for (elms_citer it = elms.begin(); it != elms.end(); ++it)
94  {
95  // Need to update only the weighted determinant
96  curFE.update (*it, LifeV::UPDATE_WDET);
97 
98  const LifeV::UInt nbQuadPt (curFE.nbQuadPt() );
99  // Loop on the quadrature nodes
100  for (LifeV::UInt iQuadPt (0); iQuadPt < nbQuadPt; ++iQuadPt)
101  {
102  area += curFE.wDetJacobian (iQuadPt);
103  }
104  }
105  return area;
106  }
107 };
108 
109 int main (int argc, char* argv[])
110 {
111 
112 #ifdef HAVE_MPI
113  MPI_Init (&argc, &argv);
114  std::shared_ptr<Epetra_Comm> comm (new Epetra_MpiComm (MPI_COMM_WORLD) );
115 #else
116  std::shared_ptr<Epetra_Comm> comm (new Epetra_SerialComm);
117 #endif
118 
119  // Parse command-line
120  if (argc < 3)
121  {
122  std::cout << "Usage: " << argv[0] << " [mesh_2D_Q1] [mesh_2D_Q2]" << std::endl;
123  return EXIT_SUCCESS;
124  }
125 
126  // Files
127  std::string file1 = argv[1];
128  std::string file2 = argv[2];
129 
130  bool ilead = (comm->MyPID() == 0);
131 
132  // Exact area
133  LifeV::Real area_exact = 3. * M_PI;
134 
135  if (ilead)
136  {
137  std::cout << "\n ====== LINEAR MESH ====== \n\n";
138  }
139 
140  LifeV::Real v1 = tester<LifeV::LinearQuad>::volume
141  (file1, LifeV::feQuadQ1, LifeV::geoBilinearQuad, comm);
142 
143  if (ilead) std::cout << "\n :: Total area = "
144  << std::setprecision (10) << v1
145  << "\n :: Exact area = "
146  << area_exact
147  << "\n :: Error = "
148  << std::setprecision (3)
149  << std::abs (v1 - area_exact) / area_exact * 100 << " %"
150  << std::endl;
151 
152  if (ilead)
153  {
154  std::cout << "\n ====== QUADRATIC MESH ====== \n\n";
155  }
156 
157  LifeV::Real v2 = tester<LifeV::QuadraticQuad>::volume
158  (file2, LifeV::feQuadQ2, LifeV::geoBiquadraticQuad, comm);
159 
160  if (ilead) std::cout << "\n :: Total area = "
161  << std::setprecision (10) << v2
162  << "\n :: Exact area = "
163  << area_exact
164  << "\n :: Error = "
165  << std::setprecision (3)
166  << std::abs (v2 - area_exact) / area_exact * 100 << " %\n"
167  << std::endl;
168 
169 #ifdef HAVE_MPI
170  MPI_Finalize();
171 #endif
172 
173  return EXIT_SUCCESS;
174 }
LifeV::ReferenceFE reffem_t
static LifeV::Real volume(std::string &filename, const reffem_t &reffem, const geomap_t &geomap, comm_t comm)
#define M_PI
Definition: winmath.h:20
LifeV::RegionMesh< S > mesh_t
std::shared_ptr< Epetra_Comm > comm_t
LifeV::GeometricMap geomap_t
int main(int argc, char **argv)
elms_t::const_iterator elms_citer