LifeV
entity_selection.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 Example usage of MeshEntityContainer features
30 
31  @author Antonio Cervone <ant.cervone@gmail.com>
32  @contributor
33  @maintainer Antonio Cervone <ant.cervone@gmail.com>
34 
35  @date 07-08-2012
36 
37  Extract elements and facets from a mesh based on a functor
38 
39  */
40 
41 // ===================================================
42 //! Includes
43 // ===================================================
44 
45 #include <Epetra_ConfigDefs.h>
46 #ifdef HAVE_MPI
47 #include <mpi.h>
48 #include <Epetra_MpiComm.h>
49 #else
50 #include <Epetra_SerialComm.h>
51 #endif
52 
53 
54 #include <lifev/core/LifeV.hpp>
55 
56 #include <lifev/core/filter/GetPot.hpp>
57 
58 #include <lifev/core/mesh/RegionMesh.hpp>
59 #include <lifev/core/mesh/RegionMesh2DStructured.hpp>
60 #include <lifev/core/mesh/MeshEntityContainer.hpp>
61 
62 using namespace LifeV;
63 
64 // put all local stuff in a local namespace
65 namespace
66 {
67 
70 
71 // interrogator that checks if the barycenter of the mesh entity satisfies the condition
72 // given in the constructor wrt the given circle
73 // (default: barycenter inside the circle)
74 template < typename MeshEntityType,
75  typename ComparisonPolicyType = std::function < bool (
76  Real const&,
77  Real const& ) > >
79 {
80 public:
81  typedef MeshEntityType meshEntity_Type;
82  typedef ComparisonPolicyType comparisonPolicy_Type;
83 
84  CircleInterrogator ( Vector3D const& center,
85  Real radius,
86  comparisonPolicy_Type const& policy = std::less<Real>() )
87  : M_center ( center ),
88  M_radius ( radius ),
89  M_policy ( policy ) {}
90 
91  bool operator() ( const meshEntity_Type& entity ) const
92  {
93  // compute the barycenter of the entity
94  // (this should be a method of the object)
95  Vector3D barycenter;
96  for ( UInt k = 0; k < meshEntity_Type::S_numPoints; k++ )
97  {
98  barycenter += entity.point ( k ).coordinates();
99  }
100  barycenter /= meshEntity_Type::S_numPoints;
101 
102  // check if the distance between the barycenter and the center of the circle
103  // satisfies the policy (default: distance less than the radius)
104  return M_policy ( ( barycenter - M_center ).norm(), M_radius );
105  }
106 
107 private:
109  const Real M_radius;
111 
112 }; // CircleInterrogator
113 
114 // interrogator that checks if there is a change in sign at the points
115 // of the entity of the level set function that is passed to the constructor
116 template < typename MeshEntityType >
118 {
119 public:
120  typedef MeshEntityType meshEntity_Type;
122 
123  explicit LevelSetInterrogator ( distanceFunction_Type const& distFun ) : M_distanceFunction ( distFun ) {}
124 
125  bool operator() ( meshEntity_Type const& entity ) const
126  {
127  // get the value of the level set in each point of the entity
128  std::vector<Real> sign ( meshEntity_Type::S_numPoints );
129  for ( UInt k = 0; k < meshEntity_Type::S_numPoints; k++ )
130  {
131  sign[ k ] = M_distanceFunction ( entity.point ( k ).coordinates() );
132  }
133 
134  // if there is a change in sign the level set is crossing
135  // try all combinations between points
136  for ( UInt i = 0; i < meshEntity_Type::S_numPoints - 1; i++ )
137  for ( UInt j = i + 1; j < meshEntity_Type::S_numPoints; j++ )
138  if ( sign[ i ] * sign[ j ] < 0. )
139  {
140  return true;
141  }
142 
143  return false;
144  }
145 
146 private:
148 
149 }; // LevelSetInterrogator
150 
151 // the simplest form of level set is the signed distance to a line in the 2D Cartesian plane
153 {
154 public:
155  lineDistance ( Real a, Real b, Real c ) :
156  M_a ( a ),
157  M_b ( b ),
158  M_c ( c ) {}
159 
160  // this is the distance of a generic point from the line: ( a*x + b*y - c ) / sqrt( a^2 + b^2 )
161  Real operator() ( Vector3D const& point )
162  {
163  return ( M_a * point[ 0 ] + M_b * point[ 1 ] + M_c ) / std::sqrt ( M_a * M_a + M_b * M_b );
164  }
165 
166 private:
167  Real const M_a;
168  Real const M_b;
169  Real const M_c;
170 
171 }; // lineDistance
172 
173 } // anonymous namespace
174 
175 int main ( int argc, char** argv )
176 {
177  // verbosity
178  bool verbose = 1;
179 
180  // communicator
181 #ifdef HAVE_MPI
182  MPI_Init (&argc, &argv);
183  std::shared_ptr<Epetra_Comm> comm ( new Epetra_MpiComm ( MPI_COMM_WORLD ) );
184  verbose = comm->MyPID() == 0;
185 #else
186  std::shared_ptr<Epetra_Comm> comm ( new Epetra_SerialComm );
187 #endif
188 
189  // number of elements for each direction in the mesh
190  const UInt numMeshElem = 3;
191 
192  // init mesh
193  meshPtr_Type mesh ( new mesh_Type ( comm ) );
194 
195  // build 2D mesh on the unit square
196  regularMesh2D ( *mesh,
197  1,
198  numMeshElem, numMeshElem,
199  false,
200  1.0, 1.0,
201  0.0, 0.0 );
202 
203  // ===== TEST 1 =====
204  {
205  // get all elements that are inside the circle of center (0.5,0.5) and radius 0.25
206  CircleInterrogator<mesh_Type::element_Type> myCircleInterrogator ( Vector3D ( 0.5, 0.5, 0.0 ), 0.25 );
207 
208  // get the number of entities that satisfy the predicate
209  UInt numExtractedElements = mesh->elementList().countAccordingToPredicate ( myCircleInterrogator );
210  if ( verbose ) std::cout << "the number of elements that stay inside the circle is "
211  << numExtractedElements << std::endl;
212 
213  std::vector<mesh_Type::element_Type const*> extractedElements ( numExtractedElements ); // i love c++11 auto...
214 
215  // get a const pointer to those entities
216  extractedElements = mesh->elementList().extractAccordingToPredicate ( myCircleInterrogator );
217  if ( verbose )
218  {
219  std::cout << "the elements ids are: ";
220  }
221  for ( UInt k = 0; k < numExtractedElements; k++ )
222  {
223  if ( verbose )
224  {
225  std::cout << extractedElements[ k ]->id() << " ";
226  }
227  }
228  if ( verbose )
229  {
230  std::cout << std::endl;
231  }
232  }
233  // ==================
234 
235  // ===== TEST 2 =====
236  {
237  // define a line that crosses the mesh
238  // ( the case when the level set passes exactly through a point is left to the reader )
239  lineDistance myLine ( 1., 1., -1.1 );
240 
241  // create the interrogator that uses the line defined above
242  LevelSetInterrogator<mesh_Type::facet_Type> myLevelSetInterrogator ( myLine ); // here a lambda function would reduce code
243 
244  // get the number of entities that satisfy the predicate
245  UInt numExtractedFacets = mesh->facetList().countAccordingToPredicate ( myLevelSetInterrogator );
246  if ( verbose ) std::cout << "the number of facets that are crossed by the level set is "
247  << numExtractedFacets << std::endl;
248 
249  std::vector<mesh_Type::facet_Type const*> extractedFacets ( numExtractedFacets ); // i love c++11 auto...
250 
251  // get a const pointer to those entities
252  extractedFacets = mesh->facetList().extractAccordingToPredicate ( myLevelSetInterrogator );
253  if ( verbose )
254  {
255  std::cout << "the facets ids are: ";
256  }
257  for ( UInt k = 0; k < numExtractedFacets; k++ )
258  {
259  if ( verbose )
260  {
261  std::cout << extractedFacets[ k ]->id() << " ";
262  }
263  }
264  if ( verbose )
265  {
266  std::cout << std::endl;
267  }
268  }
269  // ==================
270 
271 #ifdef HAVE_MPI
272  MPI_Finalize();
273 #endif
274 
275  return ( EXIT_SUCCESS );
276 }
std::shared_ptr< mesh_Type > meshPtr_Type
bool operator()(const meshEntity_Type &entity) const
RegionMesh< LinearTriangle > mesh_Type
Real const & operator[](UInt const &i) const
Operator [].
CircleInterrogator(Vector3D const &center, Real radius, comparisonPolicy_Type const &policy=std::less< Real >())
VectorSmall(VectorSmall< 3 > const &vector)
Copy constructor.
double Real
Generic real data.
Definition: LifeV.hpp:175
VectorSmall< 3 > Vector3D
int main(int argc, char **argv)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191