LifeV
BlockEpetra_Map.cpp
Go to the documentation of this file.
1 /*
2  * BlockEpetra_Map.cpp
3  *
4  * Created on: Aug 14, 2011
5  * Author: uvilla
6  */
7 
8 #include <lifev/core/linear_algebra/BlockEpetra_Map.hpp>
9 
10 namespace LifeV
11 {
13  M_nBlocks(0),
16  M_blockMap(0),
18  M_block2mono(0),
19  M_mono2block(0)
20  { }
21 
30 {
31  for(UInt iblock(0); iblock < M_nBlocks; ++iblock)
32  {
33  M_blockMap[iblock].reset(new map_Type(*(map.M_blockMap[iblock])));
34  M_blockShiftedMap[iblock].reset(new map_Type(*(map.M_blockShiftedMap[iblock])));
35  M_mono2block[iblock].reset(new import_Type(*(map.M_mono2block[iblock])));
36  M_block2mono[iblock].reset(new import_Type(*(map.M_block2mono[iblock])));
37  }
38 }
39 
41  M_nBlocks(0),
44  M_blockMap(0),
46  M_block2mono(0),
47  M_mono2block(0)
48 {
49  setUp(mapPtrContainer);
50 }
51 
52 void BlockEpetra_Map::setUp(const mapPtr_Type & map1, const mapPtr_Type & map2)
53 {
54  mapPtrContainer_Type tmpContainer(2);
55  tmpContainer[0] = map1;
56  tmpContainer[1] = map2;
57  setUp(tmpContainer);
58 }
59 
60 void BlockEpetra_Map::setUp(const mapPtr_Type & map1, const mapPtr_Type & map2, const mapPtr_Type & map3)
61 {
62  mapPtrContainer_Type tmpContainer(3);
63  tmpContainer[0] = map1;
64  tmpContainer[1] = map2;
65  tmpContainer[2] = map3;
66  setUp(tmpContainer);
67 }
68 
69 void BlockEpetra_Map::setUp(const mapPtrContainer_Type & mapPtrContainer)
70 {
71  M_nBlocks = mapPtrContainer.size();
72  M_blockMap.resize(M_nBlocks);
73  M_myLocalOffsets.resize(M_nBlocks);
74  M_blockShiftedMap.resize(M_nBlocks);
75  M_mono2block.resize(M_nBlocks);
76  M_block2mono.resize(M_nBlocks);
77 
78  for(UInt iblock(0); iblock<M_nBlocks; ++iblock)
79  {
80  M_blockMap[iblock].reset(new map_Type(*(mapPtrContainer[iblock])));
81  M_blockShiftedMap[iblock].reset(new map_Type(*(mapPtrContainer[iblock])));
82  }
83 
84  build();
85 }
86 
87 void BlockEpetra_Map::setUp(const Epetra_BlockMap & map1, const Epetra_BlockMap & map2)
88 {
89  mapPtrContainer_Type tmpContainer(2);
90  tmpContainer[0].reset(blockMap2Map(&map1));
91  tmpContainer[1].reset(blockMap2Map(&map2));
92  setUp(tmpContainer);
93 }
94 
95 void BlockEpetra_Map::setUp(const Epetra_BlockMap & map1, const Epetra_BlockMap & map2, const Epetra_BlockMap & map3)
96 {
97  mapPtrContainer_Type tmpContainer(3);
98  tmpContainer[0].reset(blockMap2Map(&map1));
99  tmpContainer[1].reset(blockMap2Map(&map2));
100  tmpContainer[2].reset(blockMap2Map(&map3));
101  setUp(tmpContainer);
102 }
103 
104 
106 {
107  return M_nBlocks;
108 }
109 
111 {
112  return M_monolithicMap;
113 }
114 const BlockEpetra_Map::constMapPtr_Type BlockEpetra_Map::monolithicMap() const
115 {
116  return M_monolithicMap;
117 }
119 {
120  return M_blockMap[iblock];
121 }
122 
123 const BlockEpetra_Map::constMapPtr_Type BlockEpetra_Map::blockMap(UInt iblock) const
124 {
125  return M_blockMap[iblock];
126 }
127 
129 {
130  return M_blockShiftedMap[iblock];
131 }
132 const BlockEpetra_Map::constMapPtr_Type BlockEpetra_Map::blockShiftedMap(UInt iblock) const
133 {
134  return M_blockShiftedMap[iblock];
135 }
136 
138 {
139  return *M_block2mono[iblock];
140 }
141 
143 {
144  return *M_mono2block[iblock];
145 }
146 
148 {
149  std::cout<<"Number of Blocks = " << M_nBlocks << "\n";
150  for(UInt i(0); i < M_nBlocks; ++i)
151  std::cout<<"MyLocalOffsets[" << i<< "] = " << M_myLocalOffsets[i] << "\n";
152 }
153 
154 //-------------------------------------------------------//
156 {
157 
158  const comm_Type & comm(M_blockMap[0]->Comm());
159 
160  // STEP 1
161  // numMyElBlock(i) contains the number of element in map-i associated with my PID.
162  // numGlobalElBlock(i) contains the global number of element in map-i
163  // numMyElMono contains the number in the monolithic map associated with my PID.
164  // numGlobalElMono contains the global number of element in the monolithic map
165  std::vector<int> numMyElBlock(M_nBlocks), numGlobalElBlock(M_nBlocks);
166  int numMyElMono(0), numGlobalElMono(0);
167 
168  for(UInt iblock=0; iblock < M_nBlocks; ++iblock)
169  {
170  numMyElBlock[iblock] = M_blockMap[iblock]->NumMyElements();
171  numGlobalElBlock[iblock] = M_blockMap[iblock]->NumGlobalElements();
172  }
173 
174  // I sum all over the blocks and I write the result in num*ElMono
175  numMyElMono = std::accumulate(numMyElBlock.begin(), numMyElBlock.end(), numMyElMono);
176  numGlobalElMono = std::accumulate(numGlobalElBlock.begin(), numGlobalElBlock.end(), numGlobalElMono);
177 
178  // STEP 2
179  // Define the shift for each block
180  std::vector<int> shift(M_nBlocks+1);
181  std::vector<int>::iterator itShift(shift.begin());
182  //the first shift is 0
183  *itShift = 0; itShift++;
184  // the other shifts are the sums of the global size of the previous blocks
185  std::partial_sum(numGlobalElBlock.begin(), numGlobalElBlock.end(), itShift);
186 
187  // STEP 2 bis
188  // Define the LocalShift for block in each processor
189  std::vector<UInt>::iterator itMyShift(M_myLocalOffsets.begin());
190  *itMyShift = 0; ++itMyShift;
191  std::partial_sum(numMyElBlock.begin(), numMyElBlock.end()-1, itMyShift);
192 
193 
194  // STEP 3 build the shifted and the monolithic maps
195  // myGlobalElBlock(i)(j) will contain the Global Id in the shifted map-i corresponding to the local id j
196  // myGlobalElMono(j) will contain the Global Id in the monilithic map corresponding to the local id j
197  std::vector<std::vector<int> > myGlobalElBlock(M_nBlocks);
198  std::vector<int> myGlobalElMono(numMyElMono);
199 
200  // Iterator for the vector myGlobalElMono
201  std::vector<int>::iterator myGlobalElMonoIt;
202  myGlobalElMonoIt = myGlobalElMono.begin();
203 
204  //I do a loop on the blocks
205  for(std::vector<std::vector<int> >::iterator myGlobalElBlockIt = myGlobalElBlock.begin();
206  myGlobalElBlockIt != myGlobalElBlock.end();
207  ++myGlobalElBlockIt)
208  {
209  // Get the block number from the iterator.
210  UInt iblock = (UInt) (myGlobalElBlockIt - myGlobalElBlock.begin());
211  // I will copy the Global Elements of the map-iblock into the vector *myGlobalElBlockIt
212  myGlobalElBlockIt->resize(numMyElBlock[iblock]);
213  M_blockShiftedMap[iblock]->MyGlobalElements( &(*myGlobalElBlockIt)[0] );
214 
215  // Now I shift the Global Elements
216  for(std::vector<int>::iterator it=myGlobalElBlockIt->begin(); it!=myGlobalElBlockIt->end(); ++it)
217  *it += shift[iblock];
218 
219  // the vector myGlobalElMonoIt is the concatenation of the *myGlobalElBlockIt vectors
220  myGlobalElMonoIt = std::copy(myGlobalElBlockIt->begin(), myGlobalElBlockIt->end(), myGlobalElMonoIt);
221 
222  // Now I say that blockMaps[iblock] is the map with the Shifted Global Elements
223  M_blockShiftedMap[iblock].reset(new map_Type(numGlobalElBlock[iblock], myGlobalElBlockIt->size(),
224  &(*myGlobalElBlockIt)[0], shift[iblock], comm));
225 
226  }
227 
228  // I create the monolithic map
229  M_monolithicMap.reset(new map_Type(numGlobalElMono, myGlobalElMono.size(), &myGlobalElMono[0], 0, comm));
230 
231  // I create the importer from the block maps to the monolithic map and viceversa
232  for(UInt iblock=0; iblock<M_nBlocks; ++iblock)
233  {
234  M_block2mono[iblock].reset(new import_Type(*M_monolithicMap, *M_blockShiftedMap[iblock]));
235  M_mono2block[iblock].reset(new import_Type(*M_blockShiftedMap[iblock], *M_monolithicMap));
236  }
237 }
238 
239 
241 {
242  Epetra_Map * map = new Epetra_Map
243  (blockMap->NumGlobalElements(),
244  blockMap->NumMyElements(),
245  blockMap->MyGlobalElements(),
246  blockMap->IndexBase(),
247  blockMap->Comm()
248  );
249  return map;
250 }
251 
252 } /*end name space*/
const import_Type & mono2blockImporter(UInt iblock) const
return an Trilinos import_Type object from the monolithic map to block iblock map.
This class handles block access to parallel monolithic Vectors with an underling block structure...
mapPtr_Type & blockMap(UInt iblock)
returns the original map of block iblock
void setUp(const Epetra_BlockMap &map1, const Epetra_BlockMap &map2, const Epetra_BlockMap &map3)
other set up routines to overcome a design problem in Trilinos (3 blocks)
mapPtr_Type & blockShiftedMap(UInt iblock)
returns the map relative to block iblock in the numbering of the monolithic map
const constMapPtr_Type blockMap(UInt iblock) const
const version
void setUp(const mapPtrContainer_Type &mapPtrContainer)
general setup for arbitrary number of blocks. The maps of the block to stride are collected in a mapP...
BlockEpetra_Map(const mapPtrContainer_Type &mapPtrContainer)
Construct a BlockEpetra_Map from an ordered list of Epetra_BlockMap objects.
importPtrContainer_Type M_mono2block
split the monolithic vector in the block vectors
const constMapPtr_Type monolithicMap() const
const version
void updateInverseJacobian(const UInt &iQuadPt)
mapPtrContainer_Type M_blockMap
const constMapPtr_Type blockShiftedMap(UInt iblock) const
const version
BlockEpetra_Map(const BlockEpetra_Map &map)
Copy constructor.
std::vector< mapPtr_Type > mapPtrContainer_Type
BlockEpetra_Map()
Default Constructor.
importPtrContainer_Type M_block2mono
merge block vectors in the monolithic vector
mapPtrContainer_Type M_blockShiftedMap
const import_Type & block2monoImporter(UInt iblock) const
return an Trilinos import_Type object from block iblock map to the monolithic map ...
void setUp(const Epetra_BlockMap &map1, const Epetra_BlockMap &map2)
other set up routines to overcome a design problem in Trilinos (2 blocks)
mapPtr_Type & monolithicMap()
returns the monolithicMap
void showMe()
Print debug info.
UInt nBlocks() const
get the number of blocks
Epetra_Map * blockMap2Map(const Epetra_BlockMap *blockMap)
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191