LifeV
MapEpetra.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 MapEpetra
30 
31  @author Gilles Fourestey <gilles.fourestey@epfl.ch>
32  @author Simone Deparis <simone.deparis@epfl.ch>
33  @contributor Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
34  @maintainer Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
35 
36  @date 26-10-2006
37 
38  This class manages the distribution of elements of matrices or vectors on a parallel machine
39  */
40 
41 #include <Epetra_Util.h>
42 
43 #include <lifev/core/LifeV.hpp>
44 #include <lifev/core/array/MapEpetra.hpp>
45 
46 namespace LifeV
47 {
48 
49 // ===================================================
50 // Constructors & Destructor
51 // ===================================================
52 
56 {
57  // Nothing to be done here
58 }
59 
60 MapEpetra::MapEpetra ( Int numGlobalElements,
61  Int numMyElements,
62  Int* myGlobalElements,
63  const commPtr_Type& commPtr ) :
64  M_commPtr ( commPtr )
65 {
66  ASSERT (M_commPtr.get()!=0, "Error! The communicator pointer is not valid.\n");
67 
68  createMap ( numGlobalElements,
69  numMyElements,
70  myGlobalElements,
71  *commPtr );
72 }
73 
74 MapEpetra::MapEpetra ( mapData_Type const& mapData, commPtr_Type const& commPtr ) :
77  M_commPtr ( commPtr )
78 {
79  ASSERT (M_commPtr.get()!=0, "Error! The communicator pointer is not valid.\n");
80 
81  M_uniqueMapEpetra.reset ( new Epetra_Map ( -1,
82  mapData.unique.size(),
83  mapData.unique.data(),
84  0,
85  *M_commPtr ) );
86  M_repeatedMapEpetra.reset ( new Epetra_Map ( -1,
87  mapData.repeated.size(),
88  mapData.repeated.data(),
89  0,
90  *M_commPtr ) );
91 }
92 
93 MapEpetra::MapEpetra ( const Int numGlobalElements,
94  const Int /*notUsed*/,
95  const commPtr_Type& commPtr ) :
98  M_commPtr ( commPtr )
99 {
100  ASSERT (M_commPtr.get()!=0, "Error! The communicator pointer is not valid.\n");
101 
102  std::vector<Int> myGlobalElements ( numGlobalElements );
103 
104  for ( Int i = 0; i < numGlobalElements; ++i )
105  {
106  myGlobalElements[i] = i;
107  }
108 
109  M_repeatedMapEpetra.reset ( new Epetra_Map ( -1, numGlobalElements, &myGlobalElements[0], 0, *commPtr ) );
110  M_uniqueMapEpetra.reset ( new Epetra_Map ( numGlobalElements, 0, *commPtr ) );
111 }
112 
113 MapEpetra::MapEpetra ( const Int size,
114  const commPtr_Type& commPtr ) :
117  M_commPtr ( commPtr )
118 {
119  ASSERT (M_commPtr.get()!=0, "Error! The communicator pointer is not valid.\n");
120 
121  Int numGlobalElements ( size );
122  Int numMyElements ( numGlobalElements );
123  std::vector<Int> myGlobalElements ( size );
124 
125  for ( Int i (0); i < numGlobalElements; ++i )
126  {
127  myGlobalElements[i] = i;
128  }
129  M_repeatedMapEpetra.reset ( new Epetra_Map ( numGlobalElements,
130  numMyElements,
131  &myGlobalElements[0],
132  0,
133  *commPtr ) );
134 
135  if ( commPtr->MyPID() != 0 )
136  {
137  numMyElements = 0;
138  }
139 
140  M_uniqueMapEpetra.reset ( new Epetra_Map ( numGlobalElements,
141  numMyElements,
142  &myGlobalElements[0],
143  0,
144  *commPtr ) );
145 }
146 
147 MapEpetra::MapEpetra ( const map_Type map ) :
148  M_repeatedMapEpetra ( new map_Type ( map ) ),
149  M_commPtr(map.Comm().Clone())
150 {
151  uniqueMap ();
152 }
153 
154 MapEpetra::MapEpetra ( const Epetra_BlockMap& blockMap, const Int offset, const Int maxId) :
156 {
157  std::vector<Int> myGlobalElements;
158  Int* sourceGlobalElements ( blockMap.MyGlobalElements() );
159  Int const startIdOrig ( offset );
160  Int const endIdOrig ( startIdOrig + maxId );
161  const Int maxMyElements = std::min ( maxId, blockMap.NumMyElements() );
162  myGlobalElements.reserve ( maxMyElements );
163 
164  //Sort MyGlobalElements to avoid a bug in Trilinos (9?) when multiplying two matrices (A * B^T)
165  std::sort ( myGlobalElements.begin(), myGlobalElements.end() );
166 
167  // We consider that the source Map may not be ordered
168  for ( Int i (0); i < blockMap.NumMyElements(); ++i )
169  if ( sourceGlobalElements[i] < endIdOrig && sourceGlobalElements[i] >= startIdOrig )
170  {
171  myGlobalElements.push_back ( sourceGlobalElements[i] - offset );
172  }
173 
174  createMap ( -1,
175  myGlobalElements.size(),
176  &myGlobalElements.front(),
177  *M_commPtr );
178 }
179 
180 // ===================================================
181 // Operators
182 // ===================================================
183 
184 MapEpetra& MapEpetra::operator= (const MapEpetra& epetraMap)
185 {
186  if ( this != &epetraMap )
187  {
190  M_exporter = epetraMap.M_exporter;
191  M_importer = epetraMap.M_importer;
192  M_commPtr = epetraMap.M_commPtr;
193  }
194 
195  return *this;
196 }
197 
198 MapEpetra& MapEpetra::operator+= ( const MapEpetra& epetraMap )
199 {
200  if ( ! epetraMap.getUniqueMap() )
201  {
202  return *this;
203  }
204 
205  if ( ! this->getUniqueMap() )
206  {
207  this->operator = ( epetraMap );
208  return *this;
209  }
210 
211  if (M_commPtr.get()==0)
212  {
213  // In case this map was created with default constructor
214  M_commPtr = epetraMap.M_commPtr;
215  }
216 
217  Int* pointer;
218  std::vector<Int> map;
219 
220  pointer = getRepeatedMap()->MyGlobalElements();
221  for ( Int ii = 0; ii < getRepeatedMap()->NumMyElements(); ++ii, ++pointer )
222  {
223  map.push_back ( *pointer );
224  }
225 
226  Int numGlobalElements = getUniqueMap()->NumGlobalElements();
227 
228  pointer = epetraMap.getRepeatedMap()->MyGlobalElements();
229  for (Int ii = 0; ii < epetraMap.getRepeatedMap()->NumMyElements(); ++ii, ++pointer)
230  {
231  map.push_back ( *pointer + numGlobalElements );
232  }
233 
234  M_repeatedMapEpetra.reset ( new Epetra_Map (-1, map.size(), map.data(), 0, *M_commPtr ) );
235 
236  map.resize (0);
237  pointer = getUniqueMap()->MyGlobalElements();
238 
239  for ( Int ii = 0; ii < getUniqueMap()->NumMyElements(); ++ii, ++pointer )
240  {
241  map.push_back ( *pointer );
242  }
243 
244  pointer = epetraMap.getUniqueMap()->MyGlobalElements();
245  for ( Int ii = 0; ii < epetraMap.getUniqueMap()->NumMyElements(); ++ii, ++pointer )
246  {
247  map.push_back ( *pointer + numGlobalElements );
248  }
249 
250  M_uniqueMapEpetra.reset ( new Epetra_Map ( -1, map.size(), map.data(), 0, *M_commPtr ) );
251 
252  M_exporter.reset (new std::shared_ptr<Epetra_Export>());
253  M_importer.reset (new std::shared_ptr<Epetra_Import>());
254 
255  return *this;
256 }
257 
258 MapEpetra& MapEpetra::operator += ( Int const size )
259 {
260  MapEpetra lagrMap ( size, commPtr() );
261 
262  ASSERT ( this->getUniqueMap(), "operator+=(const Int) works only for an existing MapEpetra" );
263 
264  this->operator+= ( lagrMap );
265  return *this;
266 }
267 
268 // ===================================================
269 // Methods
270 // ===================================================
271 
273 {
274  std::shared_ptr<MapEpetra> rootMap ( new MapEpetra ( Epetra_Util::Create_Root_Map ( *getUniqueMap(), root ) ) );
275  return rootMap;
276 }
277 
278 bool MapEpetra::mapsAreSimilar ( MapEpetra const& epetraMap ) const
279 {
280  if ( this == &epetraMap )
281  {
282  return true;
283  }
284 
285  return ( getUniqueMap()->SameAs ( *epetraMap.getUniqueMap() ) &&
286  getRepeatedMap()->SameAs ( *epetraMap.getRepeatedMap() ) );
287 }
288 
289 #ifdef HAVE_HDF5
290 
291 void MapEpetra::exportToHDF5 ( std::string const& fileName, std::string const& mapName, bool const truncate )
292 {
293  ASSERT (M_commPtr.get()!=0, "Error! The stored communicator pointer is not valid.\n");
294  ASSERT (M_uniqueMapEpetra.get()!=0 && M_repeatedMapEpetra.get()!=0, "Error! One (or both) the map pointers are not valid.\n");
295 
297 
298  if ( truncate )
299  {
300  // Create and open the file / Truncate and open the file
301  HDF5.Create ( ( fileName + ".h5" ).data() );
302  }
303  else
304  {
305  // Open an existing file without truncating it
306  HDF5.Open ( ( fileName + ".h5" ).data() );
307  }
308 
309  // Check if the file is created
310  if ( !HDF5.IsOpen () )
311  {
312  std::cerr << "Unable to create " + fileName + ".h5";
313  abort();
314  }
315 
316  // Save the maps into the file
317  HDF5.Write ( ( mapName + "Unique" ).c_str(), *M_uniqueMapEpetra );
318  HDF5.Write ( ( mapName + "Repeated" ).c_str(), *M_repeatedMapEpetra );
319 
320  // Close the file
321  HDF5.Close();
322 
323 } // exportToHDF5
324 
326 {
327  ASSERT (M_commPtr.get()!=0, "Error! The stored communicator pointer is not valid.\n");
328 
330 
331  // Open an existing file
332  HDF5.Open ( ( fileName + ".h5" ).data() );
333 
334  // Check if the file is created
335  if ( !HDF5.IsOpen () )
336  {
337  std::cerr << "Unable to open " + fileName + ".h5";
338  abort();
339  }
340 
341  // Read the unique map from the file
342  Epetra_Map* importedMap ( 0 );
343  HDF5.Read ( ( mapName + "Unique" ).c_str(), importedMap );
344 
345  // Copy the loaded map to the member object
347 
348  // Read the repeated map from the file
349  HDF5.Read ( ( mapName + "Repeated" ).c_str(), importedMap );
350 
351  // Copy the loaded matrix to the member object
353 
354  // Close the file
355  HDF5.Close();
356 
357 } // importFromHDF5
358 
359 #endif // HAVE_HDF5
360 
361 void MapEpetra::showMe ( std::ostream& output ) const
362 {
363  output << "unique map:" << std::endl;
364  output << *getUniqueMap();
365  output << "repeated map:" << std::endl;
366  output << *getRepeatedMap();
367 }
368 
369 // ===================================================
370 // Get Methods
371 // ===================================================
372 
374 {
375  switch ( mapType )
376  {
377  case Unique:
378  return getUniqueMap();
379  case Repeated:
380  return getRepeatedMap();
381  }
382  return getUniqueMap();
383 }
384 
385 const Epetra_Export& MapEpetra::exporter()
386 {
387  ASSERT (M_uniqueMapEpetra.get()!=0 && M_repeatedMapEpetra.get()!=0, "Error! One (or both) the map pointers are not valid.\n");
388 
390 
391  return **M_exporter;
392 }
393 
394 const Epetra_Import& MapEpetra::importer()
395 {
396  ASSERT (M_uniqueMapEpetra.get()!=0 && M_repeatedMapEpetra.get()!=0, "Error! One (or both) the map pointers are not valid.\n");
397 
399 
400  return **M_importer;
401 }
402 
403 // ===================================================
404 // Set Methods
405 // ===================================================
406 
407 void MapEpetra::setComm (commPtr_Type const& commPtr)
408 {
409  ASSERT (commPtr.get()!=0, "Error! The communicator pointer is not valid.\n");
410 
411  M_commPtr = commPtr;
412 }
413 
415 {
416  switch ( mapType )
417  {
418  case Unique:
419  M_uniqueMapEpetra = map;
420  case Repeated:
421  M_repeatedMapEpetra = map;
422  }
423 }
424 
425 // ===================================================
426 // Private Methods
427 // ===================================================
428 
429 MapEpetra::MapEpetra (const MapEpetra& epetraMap)
430 {
431  this->operator= ( epetraMap );
432 }
433 
434 void MapEpetra::createMap (Int numGlobalElements,
435  Int numMyElements,
436  Int* myGlobalElements,
437  const comm_Type& comm)
438 {
439  if ( numMyElements != 0 && myGlobalElements == 0 ) // linearMap
440  M_repeatedMapEpetra.reset ( new Epetra_Map ( numGlobalElements,
441  numMyElements,
442  0,
443  comm ) );
444  else // classic LifeV map
445  M_repeatedMapEpetra.reset ( new Epetra_Map ( numGlobalElements,
446  numMyElements,
447  myGlobalElements,
448  0,
449  comm ) );
450 
451  uniqueMap();
452 }
453 
455 {
456  M_uniqueMapEpetra.reset ( new Epetra_Map ( Epetra_Util::Create_OneToOne_Map ( *getRepeatedMap(), false ) ) );
457 
458  M_exporter.reset (new std::shared_ptr<Epetra_Export>());
459  M_importer.reset (new std::shared_ptr<Epetra_Import>());
460 }
461 
463 {
464  if ( !getRepeatedMap() || !getUniqueMap() )
465  {
466  return;
467  }
468 
469  if ( M_exporter->get() == 0 )
470  {
471  M_exporter->reset ( new Epetra_Export ( *getRepeatedMap(), *getUniqueMap() ) );
472  }
473 
474  if ( M_importer->get() == 0 )
475  {
476  M_importer->reset ( new Epetra_Import ( *getRepeatedMap(), *getUniqueMap() ) );
477  }
478 }
479 
480 void
481 MapEpetra::bubbleSort (Epetra_IntSerialDenseVector& elements)
482 {
483  Int hold;
484 
485  for ( Int pass (0); pass < elements.Length() - 1; pass++ )
486  for ( Int j (0); j < elements.Length() - 1; j++ )
487  if ( elements[j] > elements[j + 1] )
488  {
489  hold = elements[j];
490  elements[j] = elements[j + 1];
491  elements[j + 1] = hold;
492  }
493 }
494 
495 // ===================================================
496 // External operators
497 // ===================================================
498 
499 MapEpetra operator+ (const MapEpetra& map1, const MapEpetra& map2)
500 {
501  MapEpetra mapOut (map1);
502  mapOut += map2;
503 
504  return mapOut;
505 }
506 
507 MapEpetra operator+ (const MapEpetra& map, Int size)
508 {
509  MapEpetra mapOut (map);
510  mapOut += size;
511 
512  return mapOut;
513 }
514 
515 MapVector<MapEpetra> operator| (const MapEpetra& map1, const MapEpetra& map2)
516 {
517  return MapVector<MapEpetra> (map1, map2);
518 }
519 
520 } // end namespace LifeV
Epetra_Comm comm_Type
Definition: MapEpetra.hpp:93
bool mapsAreSimilar(MapEpetra const &epetraMap) const
This method return true if both the unique map and the repeated map are identical.
Definition: MapEpetra.cpp:278
Epetra_Map map_Type
Definition: MapEpetra.hpp:79
MapEpetra(const MapEpetra &epetraMap)
Copy constructor.
Definition: MapEpetra.cpp:429
MapEpetra(const map_Type map)
Constructor from raw Epetra_Map.
Definition: MapEpetra.cpp:147
mapPtr_Type M_repeatedMapEpetra
Definition: MapEpetra.hpp:344
MapEpetra & operator+=(const MapEpetra &epetraMap)
Addition operator.
Definition: MapEpetra.cpp:198
MapEpetra(mapData_Type const &mapData, commPtr_Type const &commPtr)
Constructor.
Definition: MapEpetra.cpp:74
MapEpetra()
Empty Constructor.
Definition: MapEpetra.cpp:53
MapVector< MapEpetra > operator|(const MapEpetra &map1, const MapEpetra &map2)
Juxtaposition operator.
Definition: MapEpetra.cpp:515
mapPtr_Type const & getUniqueMap() const
Getter for the unique map.
Definition: MapEpetra.hpp:325
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
MapEpetra & operator+=(Int const size)
Addition operator.
Definition: MapEpetra.cpp:258
commPtr_Type M_commPtr
Definition: MapEpetra.hpp:348
void bubbleSort(Epetra_IntSerialDenseVector &elements)
Sort the element given using a bubble sort algorithm.
Definition: MapEpetra.cpp:481
void updateInverseJacobian(const UInt &iQuadPt)
void createMap(Int numGlobalElements, Int numMyElements, Int *myGlobalElements, const comm_Type &comm)
Create a map.
Definition: MapEpetra.cpp:434
MapEpetra(Int numGlobalElements, Int numMyElements, Int *myGlobalElements, const commPtr_Type &commPtr)
Constructor.
Definition: MapEpetra.cpp:60
void setMap(mapPtr_Type map, MapEpetraType mapType)
set the internal Epetra_Maps
Definition: MapEpetra.cpp:414
MapEpetra(const Int numGlobalElements, const Int notUsed, const commPtr_Type &commPtr)
Constructor.
Definition: MapEpetra.cpp:93
MapEpetra(const Epetra_BlockMap &blockMap, const Int offset, const Int maxId)
Constructor.
Definition: MapEpetra.cpp:154
MapEpetra(const Int size, const commPtr_Type &commPtr)
Constructor.
Definition: MapEpetra.cpp:113
mapPtr_Type M_uniqueMapEpetra
Definition: MapEpetra.hpp:345
void createImportExport()
Reset and rebuild the importer and exporter for the map.
Definition: MapEpetra.cpp:462
Epetra_Import const & importer()
Getter for the Epetra_Import.
Definition: MapEpetra.cpp:394
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
MapEpetra operator+(const MapEpetra &map1, const MapEpetra &map2)
Addition operator.
Definition: MapEpetra.cpp:499
std::shared_ptr< map_Type > mapPtr_Type
Definition: MapEpetra.hpp:80
commPtr_Type & commPtr()
Definition: MapEpetra.hpp:274
std::shared_ptr< MapEpetra > createRootMap(Int const root) const
This method creates a pointer to a MapEpetra that has points only on processor root.
Definition: MapEpetra.cpp:272
void uniqueMap()
Reset the internal unique map and recompute it using the repeated map.
Definition: MapEpetra.cpp:454
This class is used to store maps that will be used for block defined problems.
Definition: MapVector.hpp:61
MapEpetraData mapData_Type
Definition: MapEpetra.hpp:82
void showMe(std::ostream &output=std::cout) const
Show informations about the map.
Definition: MapEpetra.cpp:361
MapEpetra & operator=(const MapEpetra &epetraMap)
Assignment operator.
Definition: MapEpetra.cpp:184
MapEpetra operator+(const MapEpetra &map, Int size)
Addition operator.
Definition: MapEpetra.cpp:507
void setComm(commPtr_Type const &commPtr)
Set the communicator.
Definition: MapEpetra.cpp:407
std::shared_ptr< comm_Type > commPtr_Type
Definition: MapEpetra.hpp:94
mapPtr_Type const & map(MapEpetraType mapType) const
Return a shared pointer on the internal Epetra_Map.
Definition: MapEpetra.cpp:373
mapPtr_Type const & getRepeatedMap() const
Getter for the repeated map.
Definition: MapEpetra.hpp:319