LifeV
MatrixEpetraStructuredUtility.hpp
Go to the documentation of this file.
1 //@HEADER
2 /*
3 ************************************************************************
4 
5  This file is part of the LifeV Applications.
6  Copyright (C) 2001-2010 EPFL, Politecnico di Milano, INRIA
7 
8  This library is free software; you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as
10  published by the Free Software Foundation; either version 2.1 of the
11  License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  USA
22 
23 ************************************************************************
24 */
25 //@HEADER
26 
27 /*!
28  @file MatrixEpetraStructuredUtility.hpp
29  @brief The file contains utility functions to manipulate MatrixEpetraStructuredView objects
30 
31  @author Gwenol Grandperrin <gwenol.grandperrin@epfl.ch>
32  @date 2010-11-08
33 
34  @todo createDiagBlock() and createInvDiagBlock() can be reduced to a single function to avoid copy duplication with the aid of a bit of template meta programming. In fact, a lot of routines in this file bring back to a common block and a specialized work on the single line.
35  */
36 
37 #ifndef _MATRIXEPETRASTRUCTUREDUTILITY_HPP_
38 #define _MATRIXEPETRASTRUCTUREDUTILITY_HPP_
39 
40 #include <boost/shared_ptr.hpp>
41 #include <lifev/core/array/MatrixBlockStructure.hpp>
42 #include <lifev/core/array/MatrixEpetra.hpp>
43 #include <lifev/core/array/MatrixEpetraStructured.hpp>
44 #include <lifev/core/array/MatrixEpetraStructuredView.hpp>
45 
46 namespace LifeV
47 {
48 
49 namespace MatrixEpetraStructuredUtility
50 {
51 
52 //! Copy the block specified in another block
53 /*!
54  @param srcBlock Source block
55  @param destBlock Destination block where the data will be stored
56 */
57 template< typename DataType>
58 void copyBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
59  const MatrixEpetraStructuredView<DataType>& destBlock )
60 {
61  // BLOCK COMPATIBILITY TEST
62  ASSERT ( srcBlock.numRows() <= destBlock.numRows(), "The destination block can not contain all the rows of the source block" );
63  ASSERT ( srcBlock.numColumns() <= destBlock.numColumns(), "The destination block can not contain all the columns of the source block" );
64 
65  // BLOCK PTR TEST
66  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
67  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
68 
69  // Processor informations
70  const Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
71  const Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
72  Int srcRowElement (0);
73 
74  //Offset between the first row/column of the source and destination blocks
75  const Int rowsOffset (destBlock.firstRowIndex() - srcBlock.firstRowIndex() );
76  const Int columnsOffset (destBlock.firstColumnIndex() - srcBlock.firstColumnIndex() );
77 
78  // Source informations handlers
79  Int numSrcEntries;
80  DataType* srcValues;
81  Int* srcIndices;
82  Int srcGlobalIndex (0);
83  Int srcRow (0);
84 
85  for (Int i (0); i < numSrcElements; ++i)
86  {
87  // Collecting the data from the source
88  srcRowElement = srcGlobalElements[i];
89 
90  // Test if the rows are in the source block
91  if ( ( static_cast<UInt> (srcRowElement) >= srcBlock.firstRowIndex() )
92  && ( static_cast<UInt> (srcRowElement) <= srcBlock.lastRowIndex() ) )
93  {
94  // Get the data of the row
95  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
96  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
97 
98  std::vector<Int> destIndices (numSrcEntries);
99  std::vector<DataType> destValues (numSrcEntries);
100  Int numDestEntries (0);
101  Int destRow (srcRowElement + rowsOffset);
102 
103  for (Int j (0); j < numSrcEntries; ++j)
104  {
105  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
106 
107  // Test if the coefficient is in the block
108  if ( ( static_cast<UInt> (srcGlobalIndex) >= srcBlock.firstColumnIndex() )
109  && ( static_cast<UInt> (srcGlobalIndex) <= srcBlock.lastColumnIndex() ) )
110  {
111  destIndices[numDestEntries] = srcGlobalIndex + columnsOffset;
112  destValues[numDestEntries] = srcValues[j];
113  numDestEntries++;
114  }
115  }
116  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
117  {
118 #ifdef NDEBUG
119  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
120 #else
121  Int errorCode = destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
122  ASSERT (errorCode >= 0, " Error in block copy: insertion failed");
123 #endif
124  }
125  else
126  {
127 #ifdef NDEBUG
128  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
129 #else
130  Int errorCode = destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
131  ASSERT (errorCode >= 0, " Error in block copy: sum failed");
132 #endif
133  }
134  }
135  }
136 }
137 
138 //! Copy the block specified in another block
139 /*!
140  @param srcBlock Source block
141  @param destBlock Destination block where the data will be stored
142 */
143 template< typename DataType>
144 void copyBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
145  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
146 {
147  copyBlock ( *srcBlock, *destBlock );
148 }
149 
150 //! Create a block full of zeros
151 /*!
152  @param destBlock Block where the data will be stored
153 */
154 template< typename DataType >
155 void createZeroBlock ( MatrixEpetraStructuredView<DataType>& /*destBlock*/ )
156 {
157  // This method will maybe be replaced
158  // by the method setBlockToZero
159  ASSERT ( false, "The method is not yet implemented");
160 }
161 
162 //! Create a block full of zeros
163 /*!
164  @param destBlock Block where the data will be stored
165 */
166 template< typename DataType >
167 void createZeroBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
168 {
169  createZeroBlock ( *destBlock );
170 }
171 
172 //! Create a block with an identical value on the diagonal
173 /*!
174  @param destBlock Block where the data will be stored
175  @param diagonalValue Value to be inserted in the diagonal
176 */
177 template< typename DataType >
178 void createScalarBlock ( const MatrixEpetraStructuredView<DataType>& destBlock, const DataType& diagonalValue )
179 {
180  // SQUARE TEST
181  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
182 
183  // BLOCK PTR TEST
184  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
185 
186  Int destIndex (0);
187 
188  Int indexBase (0);
189 
190  Int firstRowIndex (destBlock.firstRowIndex() + indexBase);
191  Int lastRowIndex (destBlock.lastRowIndex() + indexBase);
192  Int firstColumnIndex (destBlock.firstColumnIndex() + indexBase);
193 
194  // Processor informations
195  Int numDestElements = destBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
196  Int* destGlobalElements = destBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
197  Int destRowElement (0);
198 
199  for (Int i (0); i < numDestElements; ++i)
200  {
201  destRowElement = destGlobalElements[i];
202 
203  // Test if the rows are in the block
204  if ( (destRowElement >= firstRowIndex) && (destRowElement <= lastRowIndex) )
205  {
206  destIndex = firstColumnIndex + destRowElement - firstRowIndex;
207  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRowElement, 1, &diagonalValue, &destIndex);
208  }
209  }
210 }
211 
212 //! Create a block with an identical value on the diagonal
213 /*!
214  @param destBlock Block where the data will be stored
215  @param diagonalValue Value to be inserted in the diagonal
216 */
217 template< typename DataType >
218 void createScalarBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock, const DataType& diagonalValue )
219 {
220  createScalarBlock ( *destBlock, diagonalValue );
221 }
222 
223 //! Create a block with ones on the diagonal
224 /*!
225  @param destBlock Block where the data will be stored
226 */
227 template< typename DataType >
228 void createIdentityBlock ( const MatrixEpetraStructuredView<DataType>& destBlock )
229 {
230  createScalarBlock (destBlock, 1.0);
231 }
232 
233 //! Create a block with ones on the diagonal
234 /*!
235  @param destBlock Block where the data will be stored
236 */
237 template< typename DataType >
238 void createIdentityBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
239 {
240  createIdentityBlock ( *destBlock );
241 }
242 
243 //! Copy the diagonal of the block specified to another block
244 /*!
245  @param srcBlock Source block
246  @param destBlock Destination block where the data will be stored
247 */
248 template< typename DataType >
249 void createDiagBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
250  const MatrixEpetraStructuredView<DataType>& destBlock )
251 {
252  // SQUARE TEST
253  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
254  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
255 
256  // BLOCK COMPATIBILITY TEST
257  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
258  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
259 
260  // BLOCK PTR TEST
261  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
262  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
263 
264  Int indexBase (0);
265 
266  // Processor informations
267  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
268  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
269  UInt srcRowElement (0);
270 
271  // Source informations handlers
272  Int numSrcEntries;
273  DataType* srcValues;
274  Int* srcIndices;
275  Int srcGlobalIndex (0);
276  Int srcRow (0);
277 
278  for (Int i (0); i < numSrcElements; ++i)
279  {
280  // Collecting the data from the source
281  srcRowElement = srcGlobalElements[i];
282 
283  // Test if the rows are in the source block
284  if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
285  {
286  // Get the data of the row
287  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
288  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
289 
290  UInt diagIndex = srcRowElement - srcBlock.firstRowIndex();
291  Int destRow = destBlock.firstRowIndex() + diagIndex;
292  Int destIndex = destBlock.firstColumnIndex() + diagIndex;
293  DataType diagValue = 0.0;
294 
295  for (Int j (0); j < numSrcEntries; ++j)
296  {
297  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
298 
299  // Test if the coefficient is on the diagonal of the source block
300  if (srcGlobalIndex - srcBlock.firstColumnIndex() == diagIndex)
301  {
302  diagValue = srcValues[j];
303  j = numSrcEntries; //Exit the loop
304  }
305  }
306  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
307  {
308  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &diagValue, &destIndex);
309  }
310  else
311  {
312  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &diagValue, &destIndex);
313  }
314  }
315  }
316 }
317 
318 //! Copy the diagonal of the block specified to another block
319 /*!
320  @param srcBlock Source block
321  @param destBlock Destination block where the data will be stored
322 */
323 template< typename DataType >
324 void createDiagBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
325  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
326 {
327  createDiagBlock ( *srcBlock, *destBlock );
328 }
329 
330 //! Copy the inverse of the diagonal of the block specified to another block
331 /*!
332  @param srcBlock Source block
333  @param destBlock Destination block where the data will be stored
334 */
335 template< typename DataType >
336 void createInvDiagBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
337  const MatrixEpetraStructuredView<DataType>& destBlock )
338 {
339  // SQUARE TEST
340  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
341  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
342 
343  // BLOCK COMPATIBILITY TEST
344  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
345  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
346 
347  // BLOCK PTR TEST
348  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
349  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
350 
351  Int indexBase (0);
352 
353  // Processor informations
354  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
355  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
356  UInt srcRowElement (0);
357 
358  // Source informations handlers
359  Int numSrcEntries;
360  DataType* srcValues;
361  Int* srcIndices;
362  Int srcGlobalIndex (0);
363  Int srcRow (0);
364 
365  for (Int i (0); i < numSrcElements; ++i)
366  {
367  // Collecting the data from the source
368  srcRowElement = srcGlobalElements[i];
369 
370  // Test if the rows are in the source block
371  if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
372  {
373  // Get the data of the row
374  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
375  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
376 
377  UInt diagIndex = srcRowElement - srcBlock.firstRowIndex();
378  Int destRow = destBlock.firstRowIndex() + diagIndex;
379  Int destIndex = destBlock.firstColumnIndex() + diagIndex;
380  DataType diagValue = 0.0;
381 
382  for (Int j (0); j < numSrcEntries; ++j)
383  {
384  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
385 
386  // Test if the coefficient is on the diagonal of the source block
387  if (srcGlobalIndex - srcBlock.firstColumnIndex() == diagIndex)
388  {
389  // ZERO ON DIAGONAL TEST
390  ASSERT ( srcValues[j] != 0, "You cannot ask for inverse diagonal block when there are zeros on the diagonal" );
391 
392  diagValue = 1. / srcValues[j];
393  j = numSrcEntries; //Exit the loop
394  }
395  }
396  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
397  {
398  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &diagValue, &destIndex);
399  }
400  else
401  {
402  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &diagValue, &destIndex);
403  }
404  }
405  }
406 
407 }
408 
409 //! Copy the inverse of the diagonal of the block specified to another block
410 /*!
411  @param srcBlock Source block
412  @param destBlock Destination block where the data will be stored
413 */
414 template< typename DataType >
415 void createInvDiagBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
416  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
417 {
418  createInvDiagBlock ( *srcBlock, *destBlock );
419 }
420 
421 //! Copy the inverse of the square root of the diagonal of the block specified to another block
422 /*!
423  @param srcBlock Source block
424  @param destBlock Destination block where the data will be stored
425 */
426 template< typename DataType >
427 void createInvSquaredDiagBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
428  const MatrixEpetraStructuredView<DataType>& destBlock )
429 {
430  // SQUARE TEST
431  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
432  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
433 
434  // BLOCK COMPATIBILITY TEST
435  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
436  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
437 
438  // BLOCK PTR TEST
439  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
440  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
441 
442  Int indexBase (0);
443 
444  // Processor informations
445  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
446  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
447  UInt srcRowElement (0);
448 
449  // Source informations handlers
450  Int numSrcEntries;
451  Real* srcValues;
452  Int* srcIndices;
453  UInt srcGlobalIndex (0);
454  Int srcRow (0);
455 
456  for (Int i (0); i < numSrcElements; ++i)
457  {
458  // Collecting the data from the source
459  srcRowElement = srcGlobalElements[i];
460 
461  // Test if the rows are in the source block
462  if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
463  {
464  // Get the data of the row
465  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
466  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
467 
468  UInt diagIndex = srcRowElement - srcBlock.firstRowIndex();
469  Int destRow = destBlock.firstRowIndex() + diagIndex;
470  Int destIndex = destBlock.firstColumnIndex() + diagIndex;
471  Real diagValue = 0.0;
472 
473  for (Int j (0); j < numSrcEntries; ++j)
474  {
475  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
476 
477  // Test if the coefficient is on the diagonal of the source block
478  if (srcGlobalIndex - srcBlock.firstColumnIndex() == diagIndex)
479  {
480  // ZERO ON DIAGONAL TEST
481  ASSERT ( srcValues[j] != 0, "You cannot ask for inverse squared diagonal block when there are zeros on the diagonal" );
482 
483  diagValue = 1 / std::sqrt (srcValues[j]);
484  j = numSrcEntries; //Exit the loop
485  }
486  }
487  if (srcBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
488  {
489  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &diagValue, &destIndex);
490  }
491  else
492  {
493  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &diagValue, &destIndex);
494  }
495  }
496  }
497 }
498 
499 //! Copy the inverse of the square root of the diagonal of the block specified to another block
500 /*!
501  @param srcBlock Source block
502  @param destBlock Destination block where the data will be stored
503 */
504 template< typename DataType >
505 void createInvSquaredDiagBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
506  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
507 {
508  createInvSquaredDiagBlock ( *srcBlock, *destBlock );
509 }
510 
511 //! Copy the upper part of the block specified to another block
512 /*!
513  @param srcBlock Source block
514  @param destBlock Destination block where the data will be stored
515 */
516 template< typename DataType >
517 void createUpperTriangularBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
518  const MatrixEpetraStructuredView<DataType>& destBlock )
519 {
520  // SQUARE TEST
521  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
522  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
523 
524  // BLOCK COMPATIBILITY TEST
525  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
526  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
527 
528  // BLOCK PTR TEST
529  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
530  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
531 
532  // Processor informations
533  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
534  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
535  UInt srcRowElement (0);
536 
537  //Offset between the first row/column of the source and destination blocks
538  Int rowsOffset (destBlock.firstRowIndex() - srcBlock.firstRowIndex() );
539  Int columnsOffset (destBlock.firstColumnIndex() - srcBlock.firstColumnIndex() );
540 
541  // Source informations handlers
542  Int numSrcEntries;
543  DataType* srcValues;
544  Int* srcIndices;
545  UInt srcGlobalIndex (0);
546  Int srcRow (0);
547 
548  for (Int i (0); i < numSrcElements; ++i)
549  {
550  // Collecting the data from the source
551  srcRowElement = srcGlobalElements[i];
552 
553  // Test if the rows are in the source block
554  if ( (srcRowElement >= srcBlock.firstRowIndex() ) && (srcRowElement <= srcBlock.lastRowIndex() ) )
555  {
556  // Get the data of the row
557  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
558  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
559 
560  std::vector<Int> destIndices (numSrcEntries);
561  std::vector<DataType> destValues (numSrcEntries);
562  Int numDestEntries (0);
563  Int destRow (srcRowElement + rowsOffset);
564  for (Int j (0); j < numSrcEntries; ++j)
565  {
566  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
567 
568  // Test if the coefficient is:
569  // a) in the block, and
570  // b) on the upper triangular part of the block.
571  if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() ) &&
572  (srcGlobalIndex <= srcBlock.lastColumnIndex() ) &&
573  (srcGlobalIndex - srcBlock.firstColumnIndex() >= srcRowElement - srcBlock.firstRowIndex() ) )
574  {
575  destIndices[numDestEntries] = srcGlobalIndex + columnsOffset;
576  destValues[numDestEntries] = srcValues[j];
577  numDestEntries++;
578  }
579  }
580  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
581  {
582  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
583  }
584  else
585  {
586  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
587  }
588  }
589  }
590 }
591 
592 //! Copy the upper part of the block specified to another block
593 /*!
594  @param srcBlock Source block
595  @param destBlock Destination block where the data will be stored
596 */
597 template< typename DataType >
598 void createUpperTriangularBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
599  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
600 {
601  createUpperTriangularBlock ( *srcBlock, *destBlock );
602 }
603 
604 //! Copy the lower part of the block specified to another block
605 /*!
606  @param srcBlock Source block
607  @param destBlock Destination block where the data will be stored
608 */
609 template< typename DataType >
610 void createLowerTriangularBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
611  const MatrixEpetraStructuredView<DataType>& destBlock )
612 {
613  // SQUARE TEST
614  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
615  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
616 
617  // BLOCK COMPATIBILITY TEST
618  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
619  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
620 
621  // BLOCK PTR TEST
622  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
623  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
624 
625  // Processor informations
626  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
627  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
628  UInt srcRowElement (0);
629 
630  //Offset between the first row/column of the source and destination blocks
631  Int rowsOffset (destBlock.firstRowIndex() - srcBlock.firstRowIndex() );
632  Int columnsOffset (destBlock.firstColumnIndex() - srcBlock.firstColumnIndex() );
633 
634  // Source informations handlers
635  Int numSrcEntries;
636  DataType* srcValues;
637  Int* srcIndices;
638  UInt srcGlobalIndex (0);
639  Int srcRow (0);
640 
641  for (Int i (0); i < numSrcElements; ++i)
642  {
643  // Collecting the data from the source
644  srcRowElement = srcGlobalElements[i];
645 
646  // Test if the rows are in the source block
647  if ( (srcRowElement >= srcBlock.firstRowIndex() ) && (srcRowElement <= srcBlock.lastRowIndex() ) )
648  {
649  // Get the data of the row
650  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
651  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
652 
653  std::vector<Int> destIndices (numSrcEntries);
654  std::vector<DataType> destValues (numSrcEntries);
655  Int numDestEntries (0);
656  Int destRow (srcRowElement + rowsOffset);
657  for (Int j (0); j < numSrcEntries; ++j)
658  {
659  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
660 
661  // Test if the coefficient is:
662  // a) in the block, and
663  // b) on the lower triangular part of the block.
664  if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() ) &&
665  (srcGlobalIndex <= srcBlock.lastColumnIndex() ) &&
666  (srcGlobalIndex - srcBlock.firstColumnIndex() <= srcRowElement - srcBlock.firstRowIndex() ) )
667  {
668  destIndices[numDestEntries] = srcGlobalIndex + columnsOffset;
669  destValues[numDestEntries] = srcValues[j];
670  numDestEntries++;
671  }
672  }
673  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
674  {
675  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
676  }
677  else
678  {
679  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
680  }
681  }
682  }
683 }
684 
685 //! Copy the lower part of the block specified to another block
686 /*!
687  @param srcBlock Source block
688  @param destBlock Destination block where the data will be stored
689 */
690 template< typename DataType >
691 void createLowerTriangularBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
692  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
693 {
694  createLowerTriangularBlock ( *srcBlock, *destBlock );
695 }
696 
697 
698 //! Copy the lumped version of the block specified to another block
699 /*!
700  @param srcBlock Source block
701  @param destBlock Destination block where the data will be stored
702 */
703 template< typename DataType >
704 void createLumpedBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
705  const MatrixEpetraStructuredView<DataType>& destBlock )
706 {
707  // SQUARE TEST
708  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
709  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
710 
711  // BLOCK COMPATIBILITY TEST
712  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
713  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
714 
715  // BLOCK PTR TEST
716  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
717  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
718 
719  Int indexBase (0);
720 
721  // Processor informations
722  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
723  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
724  UInt srcRowElement (0);
725 
726  // Source informations handlers
727  Int numSrcEntries;
728  DataType* srcValues;
729  Int* srcIndices;
730  UInt srcGlobalIndex (0);
731  Int srcRow (0);
732 
733  for (Int i (0); i < numSrcElements; ++i)
734  {
735  // Collecting the data from the source
736  srcRowElement = srcGlobalElements[i];
737 
738  // Test if the rows are in the source block
739  if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
740  {
741  // Get the data of the row
742  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
743  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
744 
745  Int diagIndex = srcRowElement - srcBlock.firstRowIndex();
746  Int destRow = destBlock.firstRowIndex() + diagIndex;
747  Int destIndex = destBlock.firstColumnIndex() + diagIndex;
748  DataType srcBlockRowSum = 0.0;
749  for (Int j (0); j < numSrcEntries; ++j)
750  {
751  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
752 
753  // Test if the coefficient is in the block
754  if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() + indexBase) &&
755  (srcGlobalIndex <= srcBlock.lastColumnIndex() + indexBase) )
756  {
757  srcBlockRowSum += abs (srcValues[j]);
758  }
759  }
760  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
761  {
762  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
763  }
764  else
765  {
766  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
767  }
768  }
769  }
770 }
771 
772 //! Copy the lumped version of the block specified to another block
773 /*!
774  @param srcBlock Source block
775  @param destBlock Destination block where the data will be stored
776 */
777 template< typename DataType >
778 void createLumpedBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
779  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
780 {
781  createLumpedBlock ( *srcBlock, *destBlock );
782 }
783 
784 //! Copy the inverse of the lumped version of the block specified to another block
785 /*!
786  @param srcBlock Source block
787  @param destBlock Destination block where the data will be stored
788 */
789 template< typename DataType >
790 void createInvLumpedBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
791  const MatrixEpetraStructuredView<DataType>& destBlock )
792 {
793  // SQUARE TEST
794  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
795  ASSERT ( destBlock.numRows() == destBlock.numColumns() , "The destination block must be square" );
796 
797  // BLOCK COMPATIBILITY TEST
798  ASSERT ( srcBlock.numRows() == destBlock.numRows(), "The two blocks must have the same number of rows" );
799  ASSERT ( srcBlock.numColumns() == destBlock.numColumns(), "The two blocks must have the same number of columns" );
800 
801  // BLOCK PTR TEST
802  ASSERT ( srcBlock.matrixPtr() != 0 , "The source block does not have a valid pointer" );
803  ASSERT ( destBlock.matrixPtr() != 0 , "The destination block does not have a valid pointer" );
804 
805  Int indexBase (0);
806 
807  // Processor informations
808  Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
809  Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
810  UInt srcRowElement (0);
811 
812  // Source informations handlers
813  Int numSrcEntries;
814  DataType* srcValues;
815  Int* srcIndices;
816  UInt srcGlobalIndex (0);
817  Int srcRow (0);
818 
819  for (Int i (0); i < numSrcElements; ++i)
820  {
821  // Collecting the data from the source
822  srcRowElement = srcGlobalElements[i];
823 
824  // Test if the rows are in the source block
825  if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
826  {
827  // Get the data of the row
828  srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID ( static_cast<EpetraInt_Type> (srcRowElement) );
829  srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
830 
831  Int diagIndex = srcRowElement - srcBlock.firstRowIndex();
832  Int destRow = destBlock.firstRowIndex() + diagIndex;
833  Int destIndex = destBlock.firstColumnIndex() + diagIndex;
834  DataType srcBlockRowSum = 0.0;
835  for (Int j (0); j < numSrcEntries; ++j)
836  {
837  srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
838 
839  // Test if the coefficient is in the block
840  if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() + indexBase) &&
841  (srcGlobalIndex <= srcBlock.lastColumnIndex() + indexBase) )
842  {
843  srcBlockRowSum += abs (srcValues[j]);
844  }
845  }
846 
847  // ZERO ON DIAGONAL TEST
848  ASSERT ( srcBlockRowSum != 0, "You cannot ask for inverse lumped block when there are rows of zeros" );
849 
850  srcBlockRowSum = 1. / srcBlockRowSum;
851  if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
852  {
853  destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
854  }
855  else
856  {
857  destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
858  }
859  }
860  }
861 }
862 
863 //! Copy the inverse of the lumped version of the block specified to another block
864 /*!
865  @param srcBlock Source block
866  @param destBlock Destination block where the data will be stored
867 */
868 template< typename DataType >
869 void createInvLumpedBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
870  std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
871 {
872  createInvLumpedBlock ( *srcBlock, *destBlock );
873 }
874 
875 //! Create a new matrix from the block specified
876 /*!
877  @param srcBlock Source block
878  @param dstMatrix Pointer to be initialized with a new matrix
879  @param rowMap Row map. The column map will be defined in MatrixEpetraStructured<DataType>::GlobalAssemble(...,...)
880  @param closeMatrix If closeMatrix is equal to true, globalAssemble will be called.
881  @warning This method is only intended to be used with square blocks!
882 */
883 template< typename DataType>
884 void createMatrixFromBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
885  std::shared_ptr<MatrixEpetraStructured<DataType> >& destMatrix,
886  const MapEpetra& rowMap,
887  bool closeMatrix = true )
888 {
889  // SQUARE TEST
890  ASSERT ( srcBlock.numRows() == srcBlock.numColumns() , "The source block must be square" );
891  ASSERT ( srcBlock.numRows() == rowMap.mapSize(), "The two blocks must have the same number of rows" );
892 
893  // Create destination matrix
894  destMatrix.reset ( new MatrixEpetraStructured<DataType> ( rowMap, srcBlock.matrixPtr()->meanNumEntries() ) );
895 
896  // Copy the entries
897  copyBlock ( srcBlock, * ( destMatrix->block ( 0, 0 ) ) );
898 
899  // Close the matrix if requested
900  if ( closeMatrix )
901  {
902  destMatrix->globalAssemble();
903  }
904 }
905 
906 //! Create a new matrix from the block specified
907 /*!
908  @param srcBlock Source block
909  @param dstMatrix Pointer to be initialized with a new matrix
910  @param rowMap Row map. The column map will be defined in MatrixEpetraStructured<DataType>::GlobalAssemble(...,...)
911  @param closeMatrix If closeMatrix is equal to true, globalAssemble will be called.
912  @warning This method is only intended to be used with square blocks!
913 */
914 template< typename DataType>
915 void createMatrixFromBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
916  std::shared_ptr<MatrixEpetraStructured<DataType> >& destMatrix,
917  const MapEpetra& rowMap,
918  bool closeMatrix = true )
919 {
920  createMatrixFromBlock ( *srcBlock, destMatrix, rowMap, closeMatrix );
921 }
922 
923 //! Create a new matrix from the block specified (for rectangle matrix)
924 /*!
925  @param srcBlock Source block
926  @param dstMatrix Pointer to be initialized with a new matrix
927  @param domainMap domain map. The column map will be defined in MatrixEpetraStructured<DataType>::GlobalAssemble(...,...)
928  @param rangeMap range map. The column map will be defined in MatrixEpetraStructured<DataType>::GlobalAssemble(...,...)
929  @param closeMatrix If closeMatrix is equal to true, globalAssemble will be called.
930  @warning This method is only intended to be used with square blocks!
931 */
932 template< typename DataType>
933 void createMatrixFromBlock ( const MatrixEpetraStructuredView<DataType>& srcBlock,
934  std::shared_ptr<MatrixEpetraStructured<DataType> >& destMatrix,
935  std::shared_ptr<MapEpetra> domainMap,
936  std::shared_ptr<MapEpetra> rangeMap,
937  bool closeMatrix = true )
938 {
939 
940 
941  // Create destination matrix
942  if ( domainMap->mapSize() > rangeMap->mapSize() )
943  {
944  destMatrix.reset ( new MatrixEpetraStructured<DataType> ( *domainMap, srcBlock.matrixPtr()->meanNumEntries() ) );
945  }
946  else
947  {
948  destMatrix.reset ( new MatrixEpetraStructured<DataType> ( *rangeMap, srcBlock.matrixPtr()->meanNumEntries() ) );
949  }
950 
951  // Copy the entries
952  copyBlock ( srcBlock, * ( destMatrix->block ( 0, 0 ) ) );
953 
954  // Close the matrix if requested
955  if ( closeMatrix )
956  {
957  destMatrix->globalAssemble ( domainMap, rangeMap );
958  }
959 }
960 
961 //! Create a new matrix from the block specified
962 /*!
963  @param srcBlock Source block
964  @param dstMatrix Pointer to be initialized with a new matrix
965  @param domainMap domain map. The column map will be defined in MatrixEpetraStructured<DataType>::GlobalAssemble(...,...)
966  @param rangeMap range map. The column map will be defined in MatrixEpetraStructured<DataType>::GlobalAssemble(...,...)
967  @param closeMatrix If closeMatrix is equal to true, globalAssemble will be called.
968  @warning This method is only intended to be used with square blocks!
969 */
970 template< typename DataType>
971 void createMatrixFromBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
972  std::shared_ptr<MatrixEpetraStructured<DataType> >& destMatrix,
973  std::shared_ptr<MapEpetra> domainMap,
974  std::shared_ptr<MapEpetra> rangeMap,
975  bool closeMatrix = true )
976 {
977  createMatrixFromBlock ( *srcBlock, destMatrix, domainMap, rangeMap, closeMatrix );
978 }
979 
980 //! Create a block view using an unstructured matrix and block structure informations
981 /*!
982  @param matrixPtr Pointer on an unstructured matrix
983  @param blockStructure Structure to be used to extract block view
984  @param rowIndex Row position of the block in the matrix
985  @param columnIndex Column position of the block in the matrix
986 */
987 template <typename DataType>
988 std::shared_ptr< MatrixEpetraStructuredView<DataType> >
989 createBlockView ( std::shared_ptr<MatrixEpetra<DataType> > matrixPtr,
990  const MatrixBlockStructure& blockStructure,
991  const UInt& rowIndex,
992  const UInt& columnIndex )
993 {
994  ASSERT ( matrixPtr->matrixPtr()->NumGlobalCols() == blockStructure.numRows(), " Incompatible block structure (global size does not match) " );
995  ASSERT ( matrixPtr->matrixPtr()->NumGlobalRows() == blockStructure.numColumns(), " Incompatible block structure (global size does not match) " );
996 
997  std::shared_ptr< MatrixEpetraStructuredView<DataType> > matrixBlockView ( new MatrixEpetraStructuredView<DataType> );
998 
999  matrixBlockView->setup ( blockStructure.rowBlockFirstIndex ( rowIndex ),
1000  blockStructure.columnBlockFirstIndex ( columnIndex ),
1001  blockStructure.blockNumRows ( rowIndex ),
1002  blockStructure.blockNumColumns ( columnIndex ),
1003  /*matrixPtr->matrixPtr().get()*/
1004  &(*matrixPtr) );
1005 
1006  return matrixBlockView;
1007 }
1008 
1009 //! Fill a block view using an unstructured matrix and block structure informations
1010 /*!
1011  @param matrixPtr Pointer on an unstructured matrix
1012  @param blockStructure Structure to be used to extract block view
1013  @param rowIndex Row position of the block in the matrix
1014  @param columnIndex Column position of the block in the matrix
1015  @param blockView block view to be filled with informations
1016 */
1017 template <typename DataType>
1018 void
1019 fillBlockView ( std::shared_ptr<MatrixEpetra<DataType> > matrixPtr,
1020  const MatrixBlockStructure& blockStructure,
1021  const UInt& rowIndex,
1022  const UInt& columnIndex,
1023  MatrixEpetraStructuredView<DataType>& blockView )
1024 {
1025  ASSERT ( matrixPtr->matrixPtr()->NumGlobalCols() == blockStructure.numRows(), " Incompatible block structure (global size does not match) " );
1026  ASSERT ( matrixPtr->matrixPtr()->NumGlobalRows() == blockStructure.numColumns(), " Incompatible block structure (global size does not match) " );
1027 
1028  blockView.setup ( blockStructure.rowBlockFirstIndex ( rowIndex ),
1029  blockStructure.columnBlockFirstIndex ( columnIndex ),
1030  blockStructure.blockNumRows ( rowIndex ),
1031  blockStructure.blockNumColumns ( columnIndex ),
1032  matrixPtr.get() );
1033 }
1034 
1035 //! Fill a block view using an unstructured matrix and block structure informations
1036 /*!
1037  @param matrixPtr Pointer on an unstructured matrix
1038  @param blockStructure Structure to be used to extract block view
1039  @param rowIndex Row position of the block in the matrix
1040  @param columnIndex Column position of the block in the matrix
1041  @param blockView block view to be filled with informations
1042 */
1043 template <typename DataType>
1044 void
1045 fillBlockView ( std::shared_ptr<MatrixEpetra<DataType> > matrixPtr,
1046  const MatrixBlockStructure& blockStructure,
1047  const UInt& rowIndex,
1048  const UInt& columnIndex,
1049  std::shared_ptr< MatrixEpetraStructuredView<DataType> >& blockView )
1050 {
1051  if ( blockView.get() == 0 )
1052  {
1053  blockView.reset ( new MatrixEpetraStructuredView<DataType> );
1054  }
1055  fillBlockView ( matrixPtr, blockStructure, rowIndex, columnIndex, *blockView );
1056 }
1057 
1058 } // namespace MatrixEpetraStructuredUtility
1059 
1060 } // namespace LifeV
1061 
1062 #endif /*_MATRIXEPETRASTRUCTUREDUTILITY_HPP_ */
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
int32_type Int
Generic integer data.
Definition: LifeV.hpp:188
#define ASSERT(X, A)
Definition: LifeAssert.hpp:90
double Real
Generic real data.
Definition: LifeV.hpp:175
int EpetraInt_Type
Epetra int type (can be int or long long, accordingly to release notes)
Definition: LifeV.hpp:200
uint32_type UInt
generic unsigned integer (used mainly for addressing)
Definition: LifeV.hpp:191