EpetraExt  Development
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EpetraExt_BlockUtility.cpp
Go to the documentation of this file.
1 //@HEADER
2 // ***********************************************************************
3 //
4 // EpetraExt: Epetra Extended - Linear Algebra Services Package
5 // Copyright (2011) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ***********************************************************************
40 //@HEADER
41 
42 #include "EpetraExt_BlockUtility.h"
43 #include "Epetra_Map.h"
44 #include "Epetra_Comm.h"
45 
46 namespace EpetraExt {
47 
48 using std::vector;
49 
50 template<typename int_type>
51 Epetra_Map * BlockUtility::TGenerateBlockMap(
52  const Epetra_BlockMap & BaseMap,
53  const int_type * RowIndices,
54  int NumBlockRows,
55  const Epetra_Comm & GlobalComm,
56  int_type Offset)
57 {
58  int_type BaseIndex = (int_type) BaseMap.IndexBase64();
59  if (Offset == 0)
60  Offset = BlockUtility::TCalculateOffset<int_type>(BaseMap);
61 
62  //Get Base Global IDs
63  int Size = BaseMap.NumMyElements();
64  int TotalSize = NumBlockRows * Size;
65  vector<int_type> GIDs(Size);
66  BaseMap.MyGlobalElements( &GIDs[0] );
67 
68  vector<int_type> GlobalGIDs( TotalSize );
69  for( int i = 0; i < NumBlockRows; ++i )
70  {
71  for( int j = 0; j < Size; ++j )
72  GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset;
73  }
74 
75  int_type GlobalSize;
76  int_type TotalSize_int_type = TotalSize;
77  GlobalComm.SumAll( &TotalSize_int_type, &GlobalSize, 1 );
78 
79  Epetra_Map *GlobalMap =
80  new Epetra_Map( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex,
81  GlobalComm );
82 
83  return GlobalMap;
84 }
85 
86 //==============================================================================
87 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
89  const Epetra_BlockMap & BaseMap,
90  const int * RowIndices,
91  int NumBlockRows,
92  const Epetra_Comm & GlobalComm,
93  int Offset)
94 {
95  if(BaseMap.GlobalIndicesInt())
96  return TGenerateBlockMap<int>(BaseMap, RowIndices, NumBlockRows, GlobalComm, Offset);
97  else
98  throw "EpetraExt::BlockUtility::GenerateBlockMap: Global Indices not int.";
99 }
100 #endif
101 //==============================================================================
102 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
104  const Epetra_BlockMap & BaseMap,
105  const long long * RowIndices,
106  int NumBlockRows,
107  const Epetra_Comm & GlobalComm,
108  long long Offset)
109 {
110  if(BaseMap.GlobalIndicesLongLong())
111  return TGenerateBlockMap<long long>(BaseMap, RowIndices, NumBlockRows, GlobalComm, Offset);
112  else
113  throw "EpetraExt::BlockUtility::GenerateBlockMap: Global Indices not long long.";
114 }
115 #endif
116 //==============================================================================
117 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
119  const Epetra_BlockMap & BaseMap,
120  const std::vector<int>& RowIndices,
121  const Epetra_Comm & GlobalComm,
122  int Offset )
123 {
124  return GenerateBlockMap(BaseMap, &RowIndices[0], RowIndices.size(),
125  GlobalComm, Offset);
126 }
127 #endif
128 
129 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
131  const Epetra_BlockMap & BaseMap,
132  const std::vector<long long>& RowIndices,
133  const Epetra_Comm & GlobalComm,
134  long long Offset )
135 {
136  return GenerateBlockMap(BaseMap, &RowIndices[0], RowIndices.size(),
137  GlobalComm, Offset);
138 }
139 #endif
140 
141 //==============================================================================
143  const Epetra_BlockMap & BaseMap,
144  const Epetra_BlockMap& BlockMap,
145  const Epetra_Comm & GlobalComm,
146  int Offset)
147 {
148 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
149  if(BaseMap.GlobalIndicesInt() && BlockMap.GlobalIndicesInt())
150  return GenerateBlockMap(BaseMap,
151  BlockMap.MyGlobalElements(),
152  BlockMap.NumMyElements(),
153  GlobalComm,
154  Offset);
155  else
156 #endif
157 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
158  if(BaseMap.GlobalIndicesLongLong() && BlockMap.GlobalIndicesLongLong())
159  return GenerateBlockMap(BaseMap,
160  BlockMap.MyGlobalElements64(),
161  BlockMap.NumMyElements(),
162  GlobalComm,
163  Offset);
164  else
165 #endif
166  throw "EpetraExt::BlockUtility::GenerateBlockMap: Error Global Indices unknown.";
167 }
168 
169 //==============================================================================
170 template<typename int_type>
171 Epetra_CrsGraph * BlockUtility::TGenerateBlockGraph(
172  const Epetra_CrsGraph & BaseGraph,
173  const vector< vector<int_type> > & RowStencil,
174  const vector<int_type> & RowIndices,
175  const Epetra_Comm & GlobalComm )
176 {
177 
178  const Epetra_BlockMap & BaseMap = BaseGraph.RowMap();
179  int_type BaseIndex = (int_type) BaseMap.IndexBase64();
180  int_type Offset = BlockUtility::TCalculateOffset<int_type>(BaseMap);
181 
182  //Get Base Global IDs
183  int NumBlockRows = RowIndices.size();
184  int Size = BaseMap.NumMyElements();
185  int TotalSize = NumBlockRows * Size;
186  vector<int_type> GIDs(Size);
187  BaseMap.MyGlobalElements( &GIDs[0] );
188 
189  vector<int_type> GlobalGIDs( TotalSize );
190  for( int i = 0; i < NumBlockRows; ++i )
191  {
192  for( int j = 0; j < Size; ++j )
193  GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset;
194  }
195 
196  int_type GlobalSize;
197  int_type TotalSize_int_type = TotalSize;
198  GlobalComm.SumAll( &TotalSize_int_type, &GlobalSize, 1 );
199 
200  Epetra_Map GlobalMap( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex, GlobalComm );
201 
202  int MaxIndices = BaseGraph.MaxNumIndices();
203  vector<int_type> Indices(MaxIndices);
204  int NumIndices;
205 
206  Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy,
207  dynamic_cast<Epetra_BlockMap&>(GlobalMap),
208  0 );
209 
210  for( int i = 0; i < NumBlockRows; ++i )
211  {
212  int StencilSize = RowStencil[i].size();
213  for( int j = 0; j < Size; ++j )
214  {
215  int_type BaseRow = (int_type) BaseMap.GID64(j);
216  int_type GlobalRow = (int_type) GlobalMap.GID64(j+i*Size);
217 
218  BaseGraph.ExtractGlobalRowCopy( BaseRow, MaxIndices, NumIndices, &Indices[0] );
219  for( int k = 0; k < StencilSize; ++k )
220  {
221  int_type ColOffset = (RowIndices[i]+RowStencil[i][k]) * Offset;
222  if( k > 0 ) ColOffset -= (RowIndices[i]+RowStencil[i][k-1]) * Offset;
223 
224  for( int l = 0; l < NumIndices; ++l )
225  Indices[l] += ColOffset;
226 
227  GlobalGraph->InsertGlobalIndices( GlobalRow, NumIndices, &Indices[0] );
228  }
229  }
230  }
231 
232  GlobalGraph->FillComplete();
233 
234  return GlobalGraph;
235 }
236 
237 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
239  const Epetra_CrsGraph & BaseGraph,
240  const vector< vector<int> > & RowStencil,
241  const vector<int> & RowIndices,
242  const Epetra_Comm & GlobalComm )
243 {
244  if(BaseGraph.RowMap().GlobalIndicesInt())
245  return TGenerateBlockGraph<int>(BaseGraph, RowStencil, RowIndices, GlobalComm);
246  else
247  throw "EpetraExt::BlockUtility::GenerateBlockGraph: Error Global Indices not int.";
248 }
249 #endif
250 
251 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
253  const Epetra_CrsGraph & BaseGraph,
254  const vector< vector<long long> > & RowStencil,
255  const vector<long long> & RowIndices,
256  const Epetra_Comm & GlobalComm )
257 {
258  if(BaseGraph.RowMap().GlobalIndicesLongLong())
259  return TGenerateBlockGraph<long long>(BaseGraph, RowStencil, RowIndices, GlobalComm);
260  else
261  throw "EpetraExt::BlockUtility::GenerateBlockGraph: Error Global Indices not long long.";
262 }
263 #endif
264 
265 //==============================================================================
266 template<typename int_type>
267 Epetra_CrsGraph * BlockUtility::TGenerateBlockGraph(
268  const Epetra_RowMatrix & BaseMatrix,
269  const vector< vector<int_type> > & RowStencil,
270  const vector<int_type> & RowIndices,
271  const Epetra_Comm & GlobalComm )
272 {
273 
274  const Epetra_BlockMap & BaseMap = BaseMatrix.RowMatrixRowMap();
275  const Epetra_BlockMap & BaseColMap = BaseMatrix.RowMatrixColMap();
276  int_type BaseIndex = (int_type) BaseMap.IndexBase64();
277  int_type Offset = BlockUtility::TCalculateOffset<int_type>(BaseMap);
278 
279  //Get Base Global IDs
280  int NumBlockRows = RowIndices.size();
281  int Size = BaseMap.NumMyElements();
282  int TotalSize = NumBlockRows * Size;
283  vector<int_type> GIDs(Size);
284  BaseMap.MyGlobalElements( &GIDs[0] );
285 
286  vector<int_type> GlobalGIDs( TotalSize );
287  for( int i = 0; i < NumBlockRows; ++i )
288  {
289  for( int j = 0; j < Size; ++j )
290  GlobalGIDs[i*Size+j] = GIDs[j] + RowIndices[i] * Offset;
291  }
292 
293  int_type GlobalSize;
294  int_type TotalSize_int_type = TotalSize;
295  GlobalComm.SumAll( &TotalSize_int_type, &GlobalSize, 1 );
296 
297  Epetra_Map GlobalMap( GlobalSize, TotalSize, &GlobalGIDs[0], BaseIndex, GlobalComm );
298 
299  int MaxIndices = BaseMatrix.MaxNumEntries();
300  vector<int> Indices_local(MaxIndices);
301  vector<int_type> Indices_global(MaxIndices);
302  vector<double> Values(MaxIndices);
303  int NumIndices;
304 
305  Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy,
306  dynamic_cast<Epetra_BlockMap&>(GlobalMap),
307  0 );
308 
309  for( int i = 0; i < NumBlockRows; ++i )
310  {
311  int StencilSize = RowStencil[i].size();
312  for( int j = 0; j < Size; ++j )
313  {
314  int_type GlobalRow = (int_type) GlobalMap.GID64(j+i*Size);
315 
316  BaseMatrix.ExtractMyRowCopy( j, MaxIndices, NumIndices, &Values[0], &Indices_local[0] );
317  for( int l = 0; l < NumIndices; ++l ) Indices_global[l] = (int_type) BaseColMap.GID64(Indices_local[l]);
318 
319  for( int k = 0; k < StencilSize; ++k )
320  {
321  int_type ColOffset = (RowIndices[i]+RowStencil[i][k]) * Offset;
322  if( k > 0 ) ColOffset -= (RowIndices[i]+RowStencil[i][k-1]) * Offset;
323 
324  for( int l = 0; l < NumIndices; ++l )
325  Indices_global[l] += ColOffset;
326 
327  GlobalGraph->InsertGlobalIndices( GlobalRow, NumIndices, &Indices_global[0] );
328  }
329  }
330  }
331 
332  GlobalGraph->FillComplete();
333 
334  return GlobalGraph;
335 }
336 
337 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
339  const Epetra_RowMatrix & BaseMatrix,
340  const vector< vector<int> > & RowStencil,
341  const vector<int> & RowIndices,
342  const Epetra_Comm & GlobalComm )
343 {
344  if(BaseMatrix.RowMatrixRowMap().GlobalIndicesInt())
345  return TGenerateBlockGraph<int>(BaseMatrix, RowStencil, RowIndices, GlobalComm);
346  else
347  throw "EpetraExt::BlockUtility::GenerateBlockGraph: Error Global Indices not int.";
348 }
349 #endif
350 
351 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
353  const Epetra_RowMatrix & BaseMatrix,
354  const vector< vector<long long> > & RowStencil,
355  const vector<long long> & RowIndices,
356  const Epetra_Comm & GlobalComm )
357 {
358  if(BaseMatrix.RowMatrixRowMap().GlobalIndicesLongLong())
359  return TGenerateBlockGraph<long long>(BaseMatrix, RowStencil, RowIndices, GlobalComm);
360  else
361  throw "EpetraExt::BlockUtility::GenerateBlockGraph: Error Global Indices not long long.";
362 }
363 #endif
364 
365 //==============================================================================
366 template<typename int_type>
367 Epetra_CrsGraph * BlockUtility::TGenerateBlockGraph(
368  const Epetra_CrsGraph & BaseGraph,
369  const Epetra_CrsGraph & LocalBlockGraph,
370  const Epetra_Comm & GlobalComm )
371 {
372  const Epetra_BlockMap & BaseRowMap = BaseGraph.RowMap();
373  const Epetra_BlockMap & BaseColMap = BaseGraph.ColMap();
374  int_type ROffset = BlockUtility::TCalculateOffset<int_type>(BaseRowMap);
375  (void) ROffset; // Silence "unused variable" compiler warning.
376  int_type COffset = BlockUtility::TCalculateOffset<int_type>(BaseColMap);
377 
378  //Get Base Global IDs
379  const Epetra_BlockMap & BlockRowMap = LocalBlockGraph.RowMap();
380  const Epetra_BlockMap & BlockColMap = LocalBlockGraph.ColMap();
381 
382  int NumBlockRows = BlockRowMap.NumMyElements();
383  vector<int_type> RowIndices(NumBlockRows);
384  BlockRowMap.MyGlobalElements(&RowIndices[0]);
385 
386  int Size = BaseRowMap.NumMyElements();
387 
388  Epetra_Map *GlobalRowMap =
389  GenerateBlockMap(BaseRowMap, BlockRowMap, GlobalComm);
390 
391 
392  int MaxIndices = BaseGraph.MaxNumIndices();
393  vector<int_type> Indices(MaxIndices);
394 
395  Epetra_CrsGraph * GlobalGraph = new Epetra_CrsGraph( Copy,
396  dynamic_cast<Epetra_BlockMap&>(*GlobalRowMap),
397  0 );
398 
399  int NumBlockIndices, NumBaseIndices;
400  int *BlockIndices, *BaseIndices;
401  for( int i = 0; i < NumBlockRows; ++i )
402  {
403  LocalBlockGraph.ExtractMyRowView(i, NumBlockIndices, BlockIndices);
404 
405  for( int j = 0; j < Size; ++j )
406  {
407  int_type GlobalRow = (int_type) GlobalRowMap->GID64(j+i*Size);
408 
409  BaseGraph.ExtractMyRowView( j, NumBaseIndices, BaseIndices );
410  for( int k = 0; k < NumBlockIndices; ++k )
411  {
412  int_type ColOffset = (int_type) BlockColMap.GID64(BlockIndices[k]) * COffset;
413 
414  for( int l = 0; l < NumBaseIndices; ++l )
415  Indices[l] = (int_type) BaseGraph.GCID64(BaseIndices[l]) + ColOffset;
416 
417  GlobalGraph->InsertGlobalIndices( GlobalRow, NumBaseIndices, &Indices[0] );
418  }
419  }
420  }
421 
422  const Epetra_BlockMap & BaseDomainMap = BaseGraph.DomainMap();
423  const Epetra_BlockMap & BaseRangeMap = BaseGraph.RangeMap();
424  const Epetra_BlockMap & BlockDomainMap = LocalBlockGraph.DomainMap();
425  const Epetra_BlockMap & BlockRangeMap = LocalBlockGraph.RangeMap();
426 
427  Epetra_Map *GlobalDomainMap =
428  GenerateBlockMap(BaseDomainMap, BlockDomainMap, GlobalComm);
429  Epetra_Map *GlobalRangeMap =
430  GenerateBlockMap(BaseRangeMap, BlockRangeMap, GlobalComm);
431 
432  GlobalGraph->FillComplete(*GlobalDomainMap, *GlobalRangeMap);
433 
434  delete GlobalDomainMap;
435  delete GlobalRangeMap;
436  delete GlobalRowMap;
437 
438  return GlobalGraph;
439 }
440 
442  const Epetra_CrsGraph & BaseGraph,
443  const Epetra_CrsGraph & LocalBlockGraph,
444  const Epetra_Comm & GlobalComm )
445 {
446 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
447  if(BaseGraph.RowMap().GlobalIndicesInt() && LocalBlockGraph.RowMap().GlobalIndicesInt())
448  return TGenerateBlockGraph<int>(BaseGraph, LocalBlockGraph, GlobalComm);
449  else
450 #endif
451 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
452  if(BaseGraph.RowMap().GlobalIndicesLongLong() && LocalBlockGraph.RowMap().GlobalIndicesLongLong())
453  return TGenerateBlockGraph<long long>(BaseGraph, LocalBlockGraph, GlobalComm);
454  else
455 #endif
456  throw "EpetraExt::BlockUtility::GenerateBlockGraph: Error Global Indices unknown.";
457 }
458 
459 //==============================================================================
460 template<typename int_type>
461 void BlockUtility::TGenerateRowStencil(const Epetra_CrsGraph& LocalBlockGraph,
462  std::vector<int_type> RowIndices,
463  std::vector< std::vector<int_type> >& RowStencil)
464 {
465  // Get row indices
466  int NumMyRows = LocalBlockGraph.NumMyRows();
467  RowIndices.resize(NumMyRows);
468  const Epetra_BlockMap& RowMap = LocalBlockGraph.RowMap();
469  RowMap.MyGlobalElements(&RowIndices[0]);
470 
471  // Get stencil
472  RowStencil.resize(NumMyRows);
473  if (LocalBlockGraph.IndicesAreGlobal()) {
474  for (int i=0; i<NumMyRows; i++) {
475  int_type Row = RowIndices[i];
476  int NumCols = LocalBlockGraph.NumGlobalIndices(Row);
477  RowStencil[i].resize(NumCols);
478  LocalBlockGraph.ExtractGlobalRowCopy(Row, NumCols, NumCols,
479  &RowStencil[i][0]);
480  for (int k=0; k<NumCols; k++)
481  RowStencil[i][k] -= Row;
482  }
483  }
484  else {
485  for (int i=0; i<NumMyRows; i++) {
486  int NumCols = LocalBlockGraph.NumMyIndices(i);
487  std::vector<int> RowStencil_local(NumCols);
488  RowStencil[i].resize(NumCols);
489  LocalBlockGraph.ExtractMyRowCopy(i, NumCols, NumCols,
490  &RowStencil_local[0]);
491  for (int k=0; k<NumCols; k++)
492  RowStencil[i][k] = (int_type) ((int) (LocalBlockGraph.GCID64(RowStencil_local[k]) - RowIndices[i]));
493  }
494  }
495 }
496 
497 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
499  std::vector<int> RowIndices,
500  std::vector< std::vector<int> >& RowStencil)
501 {
502  if(LocalBlockGraph.RowMap().GlobalIndicesInt())
503  BlockUtility::TGenerateRowStencil<int>(LocalBlockGraph, RowIndices, RowStencil);
504  else
505  throw "EpetraExt::BlockUtility::GenerateRowStencil: Global Indices not int.";
506 }
507 #endif
508 
509 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES
511  std::vector<long long> RowIndices,
512  std::vector< std::vector<long long> >& RowStencil)
513 {
514  if(LocalBlockGraph.RowMap().GlobalIndicesLongLong())
515  BlockUtility::TGenerateRowStencil<long long>(LocalBlockGraph, RowIndices, RowStencil);
516  else
517  throw "EpetraExt::BlockUtility::GenerateRowStencil: Global Indices not long long.";
518 }
519 #endif
520 
521 
522 //==============================================================================
523 template<typename int_type>
524 int_type BlockUtility::TCalculateOffset(const Epetra_BlockMap & BaseMap)
525 {
526  int_type MaxGID = (int_type) BaseMap.MaxAllGID64();
527 
528 // int Offset = 1;
529 // while( Offset <= MaxGID ) Offset *= 10;
530 
531 // return Offset;
532 
533  return MaxGID+1;
534 }
535 
536 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES
538 {
539  if(BaseMap.GlobalIndicesInt())
540  return TCalculateOffset<int>(BaseMap);
541  else
542  throw "EpetraExt::BlockUtility::GenerateBlockMap: Global Indices not int.";
543 }
544 #endif
545 
547 {
548  return TCalculateOffset<long long>(BaseMap);
549 }
550 
551 } //namespace EpetraExt
const Epetra_BlockMap & RangeMap() const
virtual const Epetra_Map & RowMatrixRowMap() const =0
int NumGlobalIndices(long long Row) const
bool GlobalIndicesLongLong() const
int MyGlobalElements(int *MyGlobalElementList) const
static void GenerateRowStencil(const Epetra_CrsGraph &LocalBlockGraph, std::vector< int > RowIndices, std::vector< std::vector< int > > &RowStencil)
Generate stencil arrays from a local block graph.
int NumMyRows() const
const Epetra_BlockMap & ColMap() const
bool GlobalIndicesInt() const
const Epetra_BlockMap & DomainMap() const
static long long CalculateOffset64(const Epetra_BlockMap &BaseMap)
virtual int SumAll(double *PartialSums, double *GlobalSums, int Count) const =0
int NumMyElements() const
virtual int MaxNumEntries() const =0
static int CalculateOffset(const Epetra_BlockMap &BaseMap)
Routine for calculating Offset for creating unique global IDs for Block representation.
int ExtractMyRowCopy(int LocalRow, int LenOfIndices, int &NumIndices, int *Indices) const
bool IndicesAreGlobal() const
const Epetra_BlockMap & RowMap() const
int ExtractGlobalRowCopy(int GlobalRow, int LenOfIndices, int &NumIndices, int *Indices) const
int InsertGlobalIndices(int GlobalRow, int NumIndices, int *Indices)
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
int NumMyIndices(int Row) const
int MaxNumIndices() const
virtual int ExtractMyRowCopy(int MyRow, int Length, int &NumEntries, double *Values, int *Indices) const =0
static Epetra_Map * GenerateBlockMap(const Epetra_BlockMap &BaseMap, const int *RowIndices, int num_indices, const Epetra_Comm &GlobalComm, int Offset=0)
virtual const Epetra_Map & RowMatrixColMap() const =0
static Epetra_CrsGraph * GenerateBlockGraph(const Epetra_CrsGraph &BaseGraph, const std::vector< std::vector< int > > &RowStencil, const std::vector< int > &RowIndices, const Epetra_Comm &GlobalComm)
BlockCrsMatrix constuctor.