LifeV
DOFGatherer.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, 2011, 2012, 2013 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 that produces a list of dof GID from a list of element LIDs
30 
31  @date 2013-12-08
32  @author Radu Popescu <radu.popescu@epfl.ch>
33  */
34 
35 #ifndef DOFGATHERER_HPP_
36 #define DOFGATHERER_HPP_
37 
38 #include <algorithm>
39 #include <iostream>
40 #include <vector>
41 #include <set>
42 
43 #include <boost/shared_ptr.hpp>
44 
45 #include <lifev/core/LifeV.hpp>
46 
47 #include <lifev/core/array/MapEpetra.hpp>
48 #include <lifev/core/fem/FESpace.hpp>
49 #include <lifev/core/mesh/GraphUtil.hpp>
50 
51 namespace LifeV
52 {
53 
54 using namespace GraphUtil;
55 
56 //! Class that produces a list of dof GID from a list of element LIDs
57 /*!
58  @author Radu Popescu <radu.popescu@epfl.ch>
59 
60  Objects of this class are constructed using an table of element LIDs
61  (as an idTablePtr_Type object) and a finite element space (standard FESpace).
62  The element LIDs are stored in a vector or vectors (see idTablePtr_Type in
63  lifev/core/mesh/GraphUtil.hpp), where each vector contains the IDs of
64  the elements in a second stage partition (for ShyLU_MT).
65 
66  The DOFGatherer performs two operations, relevant to the second stage
67  partitioning method used by multi-threaded solvers such as ShyLU_MT:
68 
69  1. It gathers for each set of element IDs, from the FESpace, all the dof
70  GIDs that are associated with the elements.
71  2. It will classify the dofs into unique sets, one for each element ID set,
72  and a shared set, representing the dofs on the interface between the
73  second stage parts. These shared dofs are removed from the unique sets
74  and are place into a separate set, in the same table.
75 
76  The classified dof sets can be accessed through the dofGIDTable method.
77  */
78 template <typename MeshType>
80 {
81 public:
82  //! Public typedefs
83  typedef FESpace<MeshType, MapEpetra> feSpace_Type;
85 
86  //! Constructors and destructor
87  //@{
88  //! Constructor
89  /*!
90  * \param elementIds - table of element LIDs from the second stage mesh partition
91  * \param feSpace - finite element space
92  */
93  DOFGatherer (const idTablePtr_Type& elementIds,
94  const feSpacePtr_Type& feSpace);
95 
96  //! Destructor
97  virtual ~DOFGatherer();
98  //@}
99 
100  //! Get methods
101  //@{
102  //! Return a pointer to the classified dof table
104  {
105  return M_dofGIDTable;
106  }
107  //@}
108 
109  //! Public methods
110  //@{
111  //! Display the contents of the dof table
112  void showMe (std::ostream& s = std::cout);
113  //@}
114 private:
115  //! Private methods
116  //@{
117  //! This method performs all the computations
118  void run();
119 
120  //! Helper method to obtain dof GIDs associated with element LIDs
121  /*!
122  * \param elementLIDs - input list of element LIDs for which the dof lookup is
123  * desired
124  * \param dofGIDs - output set of dof GIDs
125  */
126  void getDofGIDs (const idList_Type& elementLIDs,
127  idSet_Type& dofGIDs);
128 
129  //! Private methods that computes unique and shared dofs in M_dofGIDTable
130  void dofClassification();
131 
132  //! Helper method that removes a subset of IDs from an idSet_Type
133  void removeValues (const idSet_Type& valuesToRemove,
134  idSet_Type& targetSet);
135 
136  //! Method that computes whether two (ordered) sets of IDs intersect
137  const bool setsCouldIntersect (const idSet_Type& first,
138  const idSet_Type& second) const
139  {
140  Int x0 = * (first.begin() );
141  Int x1 = * (first.rbegin() );
142  Int y0 = * (second.begin() );
143  Int y1 = * (second.rbegin() );
144  return (x0 < y1) && (y0 < x1);
145  }
146 
147  //! Method that checks if two ordered sets of IDs have a single shared value
148  const bool singleIntersect (const idSet_Type& first,
149  const idSet_Type& second,
150  Int& returnValue) const
151  {
152  Int x0 = * (first.begin() );
153  Int x1 = * (first.rbegin() );
154  Int y0 = * (second.begin() );
155  Int y1 = * (second.rbegin() );
156 
157  if (y0 == x1)
158  {
159  returnValue = y0;
160  return true;
161  }
162  else if (x0 == y1)
163  {
164  returnValue = x0;
165  return true;
166  }
167  else
168  {
169  returnValue = -1;
170  return false;
171  }
172  }
173  //@}
174 
175  // Private data
179 };
180 
181 // Method implementation
182 
183 template <typename MeshType>
184 DOFGatherer<MeshType>::DOFGatherer (const idTablePtr_Type& elementIds,
185  const feSpacePtr_Type& feSpace)
186  : M_elementIds (elementIds),
187  M_feSpace (feSpace),
188  M_dofGIDTable()
189 {
190  run();
191 }
192 
193 template <typename MeshType>
195 {
196 }
197 
198 template <typename MeshType>
199 void DOFGatherer<MeshType>::run()
200 {
201  // We need to cycle on each element LID list and obtain the dof GIDs
202  // that are associated with the given element sets
203  const Int numParts = M_elementIds->size();
204  M_dofGIDTable.reset (new idSetGroup_Type (numParts) );
205 
206  for (Int i = 0; i < numParts; ++i)
207  {
208  M_dofGIDTable->at (i).reset (new idSet_Type);
209  getDofGIDs (* (M_elementIds->at (i) ), * (M_dofGIDTable->at (i) ) );
210  }
211 
212  // From the newly produces dof GID lists, we need to remove shared dof GIDs,
213  // which represent the interface between the second stage parts and place
214  // them into a separate GID list
215 
216  // Add a new dof set to the output table, representing the id of dofs shared
217  // among the other sets
218  M_dofGIDTable->push_back (idSetPtr_Type() );
219  M_dofGIDTable->at (numParts).reset (new idSet_Type);
220 
221  // Call the classification method
223 }
224 
225 template <typename MeshType>
226 void DOFGatherer<MeshType>::getDofGIDs (const idList_Type& elementLIDs,
227  idSet_Type& dofGIDs)
228 {
229  const UInt nbDof = M_feSpace->refFE().nbDof();
230  const UInt fieldDim = M_feSpace->fieldDim();
231 
232  for (Int iElement = 0; iElement < elementLIDs.size(); ++iElement)
233  {
234  Int elemLID = elementLIDs[iElement];
235  for (UInt iBlock = 0; iBlock < fieldDim; ++iBlock)
236  {
237  // Set the row global indices in the local matrix
238  for (UInt iDof = 0; iDof < nbDof; ++iDof)
239  {
240  dofGIDs.insert (M_feSpace->dof().localToGlobalMap (elemLID, iDof)
241  + iBlock * M_feSpace->dof().numTotalDof() );
242  }
243  }
244  }
245 }
246 
247 template <typename MeshType>
248 void DOFGatherer<MeshType>::showMe (std::ostream& s)
249 {
250  for (Int i = 0; i < M_dofGIDTable->size(); ++i)
251  {
252  s << "DOF set " << i << " (size " << M_dofGIDTable->at (i)->size() << "): ";
253  idSet_Type& currentDofs = * (M_dofGIDTable->at (i) );
254  for (idSet_Type::const_iterator it = currentDofs.begin();
255  it != currentDofs.end(); ++it)
256  {
257  s << *it << " ";
258  }
259  s << std::endl;
260  }
261 }
262 
263 template<typename MeshType>
265 {
266  // TODO: try to do this with one pass over GIDs, to see if it's faster
267  Int numSets = M_dofGIDTable->size() - 1;
268  idSet_Type& commonSet = * (M_dofGIDTable->at (numSets) );
269 
270  for (Int i = 0; i < numSets - 1; ++i)
271  {
272  idSet_Type& currentSet = * (M_dofGIDTable->at (i) );
273  for (Int j = i + 1; j < numSets; ++j)
274  {
275  idSet_Type& comparisonSet = * (M_dofGIDTable->at (j) );
276 
277  if (setsCouldIntersect (currentSet, comparisonSet) )
278  {
279  Int temp = 0;
280  if (singleIntersect (currentSet, comparisonSet, temp) )
281  {
282  currentSet.erase (temp);
283  comparisonSet.erase (temp);
284  commonSet.insert (temp);
285  }
286  else
287  {
288  idSet_Type intersectionSet;
289  std::set_intersection (currentSet.begin(), currentSet.end(),
290  comparisonSet.begin(), comparisonSet.end(),
291  std::inserter (intersectionSet, intersectionSet.begin() ) );
292  removeValues (intersectionSet, currentSet);
293  removeValues (intersectionSet, comparisonSet);
294 
295  commonSet.insert (intersectionSet.begin(), intersectionSet.end() );
296  }
297  }
298  }
299  }
300 }
301 
302 template<typename MeshType>
303 void DOFGatherer<MeshType>::removeValues (const idSet_Type& valuesToRemove,
304  idSet_Type& targetSet)
305 {
306  for (idSet_Type::const_iterator it = valuesToRemove.begin();
307  it != valuesToRemove.end(); ++it)
308  {
309  targetSet.erase (*it);
310  }
311 }
312 
313 } /* namespace LifeV */
314 
315 #endif /* DOFGATHERER_HPP_ */
std::set< Int > idSet_Type
Definition: GraphUtil.hpp:64
void dofClassification()
Private methods that computes unique and shared dofs in M_dofGIDTable.
const bool setsCouldIntersect(const idSet_Type &first, const idSet_Type &second) const
Method that computes whether two (ordered) sets of IDs intersect.
const std::shared_ptr< FESpace< MeshType, MapEpetra > > M_feSpace
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
void updateInverseJacobian(const UInt &iQuadPt)
void getDofGIDs(const idList_Type &elementLIDs, idSet_Type &dofGIDs)
Helper method to obtain dof GIDs associated with element LIDs.
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
std::vector< LifeV::Int > idList_Type
Definition: GraphUtil.hpp:60
DOFGatherer(const idTablePtr_Type &elementIds, const feSpacePtr_Type &feSpace)
Constructors and destructor.
const idSetGroupPtr_Type & dofGIDTable() const
Get methods.
Class that produces a list of dof GID from a list of element LIDs.
Definition: DOFGatherer.hpp:79
virtual ~DOFGatherer()
Destructor.
FESpace< MeshType, MapEpetra > feSpace_Type
Public typedefs.
Definition: DOFGatherer.hpp:83
const bool singleIntersect(const idSet_Type &first, const idSet_Type &second, Int &returnValue) const
Method that checks if two ordered sets of IDs have a single shared value.
std::shared_ptr< idSetGroup_Type > idSetGroupPtr_Type
Definition: GraphUtil.hpp:67
void showMe(std::ostream &s=std::cout)
Public methods.
std::shared_ptr< idTable_Type > idTablePtr_Type
Definition: GraphUtil.hpp:63
idSetGroupPtr_Type M_dofGIDTable
std::shared_ptr< feSpace_Type > feSpacePtr_Type
Definition: DOFGatherer.hpp:84
void run()
Private methods.
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191
const idTablePtr_Type M_elementIds
void removeValues(const idSet_Type &valuesToRemove, idSet_Type &targetSet)
Helper method that removes a subset of IDs from an idSet_Type.