LifeV
DOFInterface3Dto2D.hpp
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 Class for connecting the dof of a mesh (3D) and an interface (2D)
30  that lives on the boundary of the mesh.
31 
32  @author Vincent Martin
33  @date 00-02-2003
34 
35  This file contains the class which may be used to update and hold
36  the connections between the dof of a mesh (3D) and an interface (2D)
37  that lives on the boundary of the mesh. The interface is referenced
38  by a flag.
39 
40  @contributor M.A. Fernandez
41  Samuel Quinodoz <samuel.quinodoz@epfl.ch>
42  @mantainer Samuel Quinodoz <samuel.quinodoz@epfl.ch>
43  */
44 
45 
46 #ifndef _DOFINTERFACE3DTO2D_HH
47 #define _DOFINTERFACE3DTO2D_HH
48 
49 #include <fstream>
50 
51 #include <lifev/core/LifeV.hpp>
52 
53 #include <lifev/core/fem/DOFInterface.hpp>
54 #include <lifev/core/fem/DOFLocalPattern.hpp>
55 #include <lifev/core/fem/DOF.hpp>
56 #include <lifev/core/mesh/MarkerDefinitions.hpp>
57 
58 namespace LifeV
59 {
60 /*!
61  \class DOFInterface3Dto2D
62 
63  Base class which holds the connections of the dof between a 3D mesh and its 2D interface
64 
65  The connections may be built by calling the update method.
66 */
67 class DOFInterface3Dto2D:
68  public DOFInterface
69 {
70 public:
71 
72  //! @name Constructor & Destructor
73  //@{
74 
75  //! default constructor
76  DOFInterface3Dto2D() :
77  M_refFE1 ( 0 ),
78  M_dof1 ( 0 )
79  {}
80 
81  //! Constructor for interfacing DOF of the same type (DOFLocalPattern)
82  /*!
83  \param refFe the part of the reference FE that contains the dof patterns (nbDofPerEdge...)
84  \param dof1 the DOF object of the mesh in which we want to make the computations
85  */
86  DOFInterface3Dto2D ( const DOFLocalPattern& refFE, const DOF& dof1 );
87 
88  //@}
89 
90 
91  //! @name Methods
92  //@{
93 
94  void setup (const DOFLocalPattern& refFE1, const DOF& dof1);
95 
96  //! This method builds the DOF connections at the interface
97  /*!
98  \param mesh1 the mesh in which we want to make the computations
99  \param flag1 the marker of the interface in the mesh1
100  */
101  template <typename MeshType>
102  void update ( const MeshType& mesh1, const markerID_Type& flag1 );
103 
104  //! Creates an Inria medit type mesh for the interface (pseudo 3D)
105  /*! Write the 2D Inria mesh of the interface
106  referenced by the number M_interfaceFlag.
107 
108  It uses a inria "me.hpp" format. (for medit)
109 
110  You should have filled the lists of vertices and faces before.
111  (Call update once previously).
112  */
113  template <typename MeshType>
114  void generate2DMesh ( std::string fname, const MeshType& mesh1 ) const;
115 
116  //! removes all unuseful list (all except M_faceList). use it properly!
117  void clearLists();
118 
119  //! output
120  std::ostream& showMe ( bool verbose = false, std::ostream& out = std::cout ) const ;
121 
122  //@}
123 
124 
125  //! @name Operators
126  //@{
127 
128  //! Returns the identity of the i-th elements in the (finalised) face list
129  //! (counting from 0 ' a la C')
130  ID operator[] ( const UInt& i ) const;
131 
132  //! Assignment operator (we have a vector of DOFInterface3Dto2D)
133  DOFInterface3Dto2D& operator= ( const DOFInterface3Dto2D& dofi );
134 
135  //@}
136 
137 
138  //! @name Get Methods
139  //@{
140 
141  //! Returns the reference of the interface
142  const markerID_Type& interfaceFlag() const
143  {
144  return M_interfaceFlag;
145  }
146 
147  //! true if the lists have been updated.
148  const bool& finalized() const
149  {
150  return M_finalized;
151  }
152 
153  //@}
154 
155 private:
156 
157  //! @name Private Methods
158  //@{
159 
160  //! Transforms the 3d index of a vertex into its 2d (interface) index.
161  //! This is a simple algorithm... Find out something better some day...?
162 
163  ID vertex3Dto2D ( const ID& idpoint3D ) const;
164 
165  //! This method builds the connections between faces at the interface (M_faceList container)
166  /*!
167  \param mesh1 the mesh in which we want to make the computations
168  \param flag1 the marker of the interface in the mesh1
169  */
170  template <typename MeshType>
171  void updateFaceConnections ( const MeshType& mesh1, const markerID_Type& flag1 );
172 
173  //! This method builds the list of vertices at the interface (M_vertexList container)
174  /*!
175  \param mesh1 the mesh in which we want to make the computations
176  */
177  template <typename MeshType>
178  void updateVertices ( const MeshType& mesh1 );
179 
180  //! This method builds the connections between DOF at the interface (_locDof container)
181  /*!
182  \param mesh1 the mesh in which we want to make the computations
183  \param dof1 the DOF object of the mesh in which we want to make the computations
184  */
185  template <typename MeshType>
186  void updateDofConnections ( const MeshType& mesh1 );
187 
188  //@}
189 
190 
191  //! reference of the interface
192  markerID_Type M_interfaceFlag;
193 
194  //! DOFLocalPattern object used in the mesh in which we want to make the computations
195  const DOFLocalPattern* M_refFE1;
196 
197  //! DOF object of the mesh in which we want to make the computations
198  const DOF* M_dof1;
199 
200  /*! STL list which holds the connections between faces at the interface
201  -> first : global (3D) face number
202  -> second : interface (2D) face number
203 
204  The name has changed : it was _elc before. (V.M.)
205  */
206  std::vector< std::pair<ID, ID> > M_faceList;
207 
208  /*! Auxiliary STL list which holds the connections between vertices at the interface
209  (vertices appear more than once. (Mathematically, it is a family))
210  Empty after calling update
211  */
212  std::list<ID> M_vertexPerFaceList;
213 
214  /*! STL list which holds the connections between vertices at the interface
215  -> first : global (3D) vertex number
216  -> second : interface (2D) vertex number
217  */
218  std::list< std::pair<ID, ID> > M_vertexList;
219 
220  //! true if the lists have been updated.
221  bool M_finalized;
222 
223 };
224 
225 
226 // ===================================================
227 // Helper
228 // ===================================================
229 
230 
231 /**
232  \brief useful function to sort a list and remove multiple numbers.
233  Helper function for DoF interface
234 */
235 void RemoveMultiple ( const std::list<ID>& list0, std::list< std::pair<ID, ID> >& listf );
236 
237 
238 // ===================================================
239 // Methods
240 // ===================================================
241 
242 template <typename MeshType>
243 void DOFInterface3Dto2D::
244 update ( const MeshType& mesh1, const markerID_Type& flag1 )
245 {
246 
247  // Updating face connections at the interface
248  updateFaceConnections ( mesh1, flag1 );
249 
250  // Updating vertex connections at the interface
251  updateVertices ( mesh1 );
252 
253  // _updateEdges( mesh1 );
254 
255  // Update of the DOF connections without inperpolation
256  updateDofConnections ( mesh1 );
257 
258  M_interfaceFlag = flag1;
259 
260  M_finalized = true; //! the lists are updated
261 }
262 
263 template <typename MeshType>
264 void DOFInterface3Dto2D::
265 generate2DMesh ( std::string fname, const MeshType& mesh1 ) const
266 {
267 
268  ASSERT_PRE ( M_finalized, "The lists of vertices and faces must be finalized before generating the interface mesh." );
269 
270  std::ofstream ofile ( fname.c_str() );
271  ASSERT ( ofile, "Error: Output file cannot be open" );
272 
273  ID idpoint3D;
274  ID idpoint2D;
275  ID idface3D;
276 
277  typedef typename MeshType::FaceShape FaceShape;
278  UInt numVertexPerFace = FaceShape::S_numVertices;
279 
280  ofile << "MeshVersionFormatted 1\n";
281  ofile << "Dimension 3\n";
282  ofile << std::endl;
283 
284  ofile << "Vertices\n";
285  ofile << M_vertexList.size() << "\n";
286 
287  //! Write the coordinates of the vertices
288  for ( std::list< std::pair<ID, ID> >::const_iterator i2D = M_vertexList.begin(); i2D != M_vertexList.end(); ++i2D )
289  {
290  idpoint3D = i2D->first;
291  ofile << mesh1.pointList ( idpoint3D ).x() << " "
292  << mesh1.pointList ( idpoint3D ).y() << " "
293  << mesh1.pointList ( idpoint3D ).z() << " "
294  << mesh1.pointList ( idpoint3D ).markerID() << std::endl;
295  }
296  ofile << std::endl;
297 
298  switch ( FaceShape::S_shape )
299  {
300  case FaceShape::QUAD:
301  ofile << "Quadrilaterals\n";
302  break;
303  case FaceShape::TRIANGLE:
304  ofile << "Triangles\n";
305  break;
306  default:
307  ERROR_MSG ( "This shape is not implemented in myinterface!" );
308  }
309 
310  ofile << M_faceList.size() << "\n";
311 
312  //! Write the face table
313  for ( std::vector< std::pair<ID, ID> >::const_iterator i2D = M_faceList.begin(); i2D != M_faceList.end(); ++i2D )
314  {
315  idface3D = i2D->first;
316 
317  for ( ID vertex = 0 ; vertex < numVertexPerFace ; ++ vertex )
318  {
319  idpoint3D = mesh1.boundaryFace ( idface3D ).point ( vertex ).id();
320  idpoint2D = vertex3Dto2D ( idpoint3D ); //Simple algorithm (of Search in the list...)
321  ofile << idpoint2D << " ";
322  }
323  ofile << mesh1.boundaryFace ( idface3D ).markerID() << std::endl;
324  }
325 }
326 
327 // ===================================================
328 // Private Methods
329 // ===================================================
330 
331 template <typename MeshType>
332 void DOFInterface3Dto2D::
333 updateFaceConnections ( const MeshType& mesh1, const markerID_Type& flag1 )
334 {
335 
336  UInt numBoundaryFace1 = mesh1.numBFaces(); // Number of boundary faces in mesh1
337 
338  markerID_Type marker1;
339 
340  ID fcounter = 0; //! Face on the interface counter
341 
342  //! Loop on boundary faces on mesh1
343  for ( ID iBoundaryFace1 = 0; iBoundaryFace1 < numBoundaryFace1; ++iBoundaryFace1 )
344  {
345 
346  //! The face marker
347  marker1 = mesh1.boundaryFace ( iBoundaryFace1 ).markerID();
348 
349  //! Is the face on the interface?
350  if ( marker1 == flag1 )
351  {
352 
353  std::pair<ID, ID> fp ( iBoundaryFace1, fcounter );
354  M_faceList.push_back ( fp );
355  fcounter ++; //! local face number
356 
357  }
358  }
359  ASSERT ( M_faceList.size() == --fcounter,
360  "Local face counter and list size do not match (in face loop)." );
361 }
362 
363 
364 template <typename MeshType>
365 void DOFInterface3Dto2D::
366 updateVertices ( const MeshType& mesh1 )
367 {
368 
369  typedef typename MeshType::FaceShape GeoBShape; // Shape of the faces
370 
371  UInt numVertexPerFace = GeoBShape::S_numVertices;
372 
373  // Loop on faces at the interface (matching faces)
374  for ( std::vector< std::pair<ID, ID> >::iterator i = M_faceList.begin(); i != M_faceList.end(); ++i )
375  {
376  for ( ID jVertex = 0 ; jVertex < numVertexPerFace ; ++ jVertex )
377  {
378  M_vertexPerFaceList.push_back ( mesh1.boundaryFace ( i->first ).point ( jVertex ).id() );
379  }
380  }
381 
382  RemoveMultiple ( M_vertexPerFaceList , M_vertexList );
383 
384  //save memory
385  M_vertexPerFaceList.clear();
386 }
387 
388 
389 template <typename MeshType>
390 void DOFInterface3Dto2D::
391 updateDofConnections ( const MeshType& mesh1 )
392 {
393  typedef typename MeshType::VolumeShape GeoShape;
394  typedef typename MeshType::FaceShape GeoBShape;
395 
396  UInt nbVertexPerFace = GeoBShape::S_numVertices; // Number of face's vertices
397  UInt nbEdgePerFace = GeoBShape::S_numEdges; // Number of face's edges
398 
399  UInt nbDofPerVertex1 = M_refFE1->nbDofPerVertex(); // number of DOF per vertices on mesh1
400  UInt nbDofPerEdge1 = M_refFE1->nbDofPerEdge(); // number of DOF per edges on mesh1
401  UInt nbDofPerFace1 = M_refFE1->nbDofPerFace(); // number of DOF per faces on mesh1
402 
403  UInt nbVertexPerElement = GeoShape::S_numVertices; // Number of element's vertices
404  UInt nbEdgePerElement = GeoShape::S_numEdges; // Number of element's edges
405 
406  UInt nDofElemV1 = nbVertexPerElement * nbDofPerVertex1; // number of vertex's DOF on a Element on mesh1
407  UInt nDofElemE1 = nbEdgePerElement * nbDofPerEdge1; // number of edge's DOF on a Element on mesh1
408 
409  ID iElAd1, iVeEl1, iFaEl1, iEdEl1, gDof1;
410 
411  ID locDofCounter1 = 0;
412 
413  std::map<ID, ID> locDofMap;
414 
415  // Loop on faces at the interface (matching faces)
416  for ( std::vector< std::pair<ID, ID> >::iterator i = M_faceList.begin(); i != M_faceList.end(); ++i )
417  {
418 
419  iElAd1 = mesh1.boundaryFace ( i->first ).firstAdjacentElementIdentity(); // id of the element adjacent to the face (mesh1)
420 
421  iFaEl1 = mesh1.boundaryFace ( i->first ).firstAdjacentElementPosition(); // local id of the face in its adjacent element (mesh1)
422 
423  // Vertex based DOF on mesh1
424  if ( nbDofPerVertex1 )
425  {
426 
427  // loop on face vertices (mesh1)
428  for ( ID iVeFa1 = 0; iVeFa1 < nbVertexPerFace; ++iVeFa1 )
429  {
430 
431  iVeEl1 = GeoShape::faceToPoint ( iFaEl1, iVeFa1 ); // local vertex number (in element)
432 
433  // Loop number of DOF per vertex (mesh1)
434  for ( ID l = 0; l < nbDofPerVertex1; ++l )
435  {
436 
437  gDof1 = M_dof1->localToGlobalMap ( iElAd1, iVeEl1 * nbDofPerVertex1 + l ); // Global Dof on mesh1
438 
439  std::pair<ID, ID> locDof ( gDof1, locDofCounter1); //! May be : invert the 2 ??
440  locDofMap.insert ( locDof ); // Updating the list of dof connections
441 
442  locDofCounter1 ++; //! local DOF (total dof on the interface)
443  }
444  }
445  }
446 
447  // Edge based DOF on mesh1
448  if ( nbDofPerEdge1 )
449  {
450 
451  // loop on face edges (mesh1)
452  for ( ID iEdFa1 = 0; iEdFa1 < nbEdgePerFace; ++iEdFa1 )
453  {
454 
455  iEdEl1 = GeoShape::faceToEdge ( iFaEl1, iEdFa1 ).first; // local edge number (in element)
456 
457  // Loop number of DOF per edge (mesh1)
458  for ( ID l = 0; l < nbDofPerEdge1; ++l )
459  {
460 
461  gDof1 = M_dof1->localToGlobalMap ( iElAd1, nDofElemV1 + iEdEl1 * nbDofPerEdge1 + l ); // Global Dof on mesh1
462 
463  std::pair<ID, ID> locDof ( gDof1, locDofCounter1 );
464  locDofMap.insert ( locDof ); // Updating the list of dof connections
465 
466  locDofCounter1 ++; //! local DOF (total dof on the interface)
467  }
468  }
469  }
470 
471  // Face based Dof on mesh1
472  for ( ID l = 0; l < nbDofPerFace1; ++l )
473  {
474 
475  gDof1 = M_dof1->localToGlobalMap ( iElAd1, nDofElemE1 + nDofElemV1 + iFaEl1 * nbDofPerFace1 + l ); // Global Dof in mesh1
476 
477  std::pair<ID, ID> locDof ( gDof1, locDofCounter1 );
478  locDofMap.insert ( locDof ); // Updating the list of dof connections
479 
480  locDofCounter1 ++; //! local DOF (total dof on the interface)
481  }
482  }
483 
484  // RemoveMultiple(locDofMap);
485  UInt ii = 0;
486  for ( std::map<ID, ID>::const_iterator it = locDofMap.begin(); it != locDofMap.end(); ++it, ++ii )
487  {
488  // std::cout << it->first << " " << it->second << ". ";
489  std::pair<ID, ID> _locDof (it->first, ii);
490  M_localDofMap.insert (_locDof);
491  }
492 }
493 
494 
495 }
496 #endif
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
const UInt & nbDofPerVertex() const
Return the number of degrees of freedom located on the vertices (0D structures)
ID markerID_Type
markerID_Type is the type used to store the geometric entity marker IDs
Definition: Marker.hpp:81
#define ERROR_MSG(A)
Definition: LifeAssert.hpp:69
#define ASSERT_PRE(X, A)
Definition: LifeAssert.hpp:96
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
uint32_type ID
IDs.
Definition: LifeV.hpp:194
DOFLocalPattern - A class to store the "couplings" between the basis functions.
const UInt & nbDofPerEdge() const
Return the number of degrees of freedom located on the edges (1D structures)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
const UInt & nbDofPerFace() const
Return the number of degrees of freedom located on the faces (2D structures).