37 #ifndef _MATRIXEPETRASTRUCTUREDUTILITY_HPP_ 38 #define _MATRIXEPETRASTRUCTUREDUTILITY_HPP_ 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> 49 namespace MatrixEpetraStructuredUtility
57 template<
typename DataType>
58 void copyBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
59 const MatrixEpetraStructuredView<DataType>& destBlock )
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" );
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" );
70 const Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
71 const Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
72 Int srcRowElement (0);
75 const Int rowsOffset (destBlock.firstRowIndex() - srcBlock.firstRowIndex() );
76 const Int columnsOffset (destBlock.firstColumnIndex() - srcBlock.firstColumnIndex() );
82 Int srcGlobalIndex (0);
85 for (
Int i (0); i < numSrcElements; ++i)
88 srcRowElement = srcGlobalElements[i];
91 if ( (
static_cast<
UInt> (srcRowElement) >= srcBlock.firstRowIndex() )
92 && (
static_cast<
UInt> (srcRowElement) <= srcBlock.lastRowIndex() ) )
95 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
96 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
98 std::vector<Int> destIndices (numSrcEntries);
99 std::vector<DataType> destValues (numSrcEntries);
100 Int numDestEntries (0);
101 Int destRow (srcRowElement + rowsOffset);
103 for (
Int j (0); j < numSrcEntries; ++j)
105 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
108 if ( (
static_cast<
UInt> (srcGlobalIndex) >= srcBlock.firstColumnIndex() )
109 && (
static_cast<
UInt> (srcGlobalIndex) <= srcBlock.lastColumnIndex() ) )
111 destIndices[numDestEntries] = srcGlobalIndex + columnsOffset;
112 destValues[numDestEntries] = srcValues[j];
116 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
119 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
121 Int errorCode = destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
122 ASSERT (errorCode >= 0,
" Error in block copy: insertion failed");
128 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
130 Int errorCode = destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
131 ASSERT (errorCode >= 0,
" Error in block copy: sum failed");
143 template<
typename DataType>
144 void copyBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
145 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
147 copyBlock ( *srcBlock, *destBlock );
154 template<
typename DataType >
155 void createZeroBlock ( MatrixEpetraStructuredView<DataType>& )
159 ASSERT (
false,
"The method is not yet implemented");
166 template<
typename DataType >
167 void createZeroBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
169 createZeroBlock ( *destBlock );
177 template<
typename DataType >
178 void createScalarBlock (
const MatrixEpetraStructuredView<DataType>& destBlock,
const DataType& diagonalValue )
181 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
184 ASSERT ( destBlock.matrixPtr() != 0 ,
"The destination block does not have a valid pointer" );
190 Int firstRowIndex (destBlock.firstRowIndex() + indexBase);
191 Int lastRowIndex (destBlock.lastRowIndex() + indexBase);
192 Int firstColumnIndex (destBlock.firstColumnIndex() + indexBase);
195 Int numDestElements = destBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
196 Int* destGlobalElements = destBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
197 Int destRowElement (0);
199 for (
Int i (0); i < numDestElements; ++i)
201 destRowElement = destGlobalElements[i];
204 if ( (destRowElement >= firstRowIndex) && (destRowElement <= lastRowIndex) )
206 destIndex = firstColumnIndex + destRowElement - firstRowIndex;
207 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRowElement, 1, &diagonalValue, &destIndex);
217 template<
typename DataType >
218 void createScalarBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock,
const DataType& diagonalValue )
220 createScalarBlock ( *destBlock, diagonalValue );
227 template<
typename DataType >
228 void createIdentityBlock (
const MatrixEpetraStructuredView<DataType>& destBlock )
230 createScalarBlock (destBlock, 1.0);
237 template<
typename DataType >
238 void createIdentityBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
240 createIdentityBlock ( *destBlock );
248 template<
typename DataType >
249 void createDiagBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
250 const MatrixEpetraStructuredView<DataType>& destBlock )
253 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
254 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
267 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
268 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
269 UInt srcRowElement (0);
275 Int srcGlobalIndex (0);
278 for (
Int i (0); i < numSrcElements; ++i)
281 srcRowElement = srcGlobalElements[i];
284 if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
287 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
288 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
290 UInt diagIndex = srcRowElement - srcBlock.firstRowIndex();
291 Int destRow = destBlock.firstRowIndex() + diagIndex;
292 Int destIndex = destBlock.firstColumnIndex() + diagIndex;
293 DataType diagValue = 0.0;
295 for (
Int j (0); j < numSrcEntries; ++j)
297 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
300 if (srcGlobalIndex - srcBlock.firstColumnIndex() == diagIndex)
302 diagValue = srcValues[j];
306 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
308 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &diagValue, &destIndex);
312 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &diagValue, &destIndex);
323 template<
typename DataType >
324 void createDiagBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
325 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
327 createDiagBlock ( *srcBlock, *destBlock );
335 template<
typename DataType >
336 void createInvDiagBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
337 const MatrixEpetraStructuredView<DataType>& destBlock )
340 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
341 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
354 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
355 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
356 UInt srcRowElement (0);
362 Int srcGlobalIndex (0);
365 for (
Int i (0); i < numSrcElements; ++i)
368 srcRowElement = srcGlobalElements[i];
371 if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
374 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
375 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
377 UInt diagIndex = srcRowElement - srcBlock.firstRowIndex();
378 Int destRow = destBlock.firstRowIndex() + diagIndex;
379 Int destIndex = destBlock.firstColumnIndex() + diagIndex;
380 DataType diagValue = 0.0;
382 for (
Int j (0); j < numSrcEntries; ++j)
384 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
387 if (srcGlobalIndex - srcBlock.firstColumnIndex() == diagIndex)
390 ASSERT ( srcValues[j] != 0,
"You cannot ask for inverse diagonal block when there are zeros on the diagonal" );
392 diagValue = 1. / srcValues[j];
396 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
398 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &diagValue, &destIndex);
402 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &diagValue, &destIndex);
414 template<
typename DataType >
415 void createInvDiagBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
416 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
418 createInvDiagBlock ( *srcBlock, *destBlock );
426 template<
typename DataType >
427 void createInvSquaredDiagBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
428 const MatrixEpetraStructuredView<DataType>& destBlock )
431 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
432 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
445 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
446 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
447 UInt srcRowElement (0);
453 UInt srcGlobalIndex (0);
456 for (
Int i (0); i < numSrcElements; ++i)
459 srcRowElement = srcGlobalElements[i];
462 if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
465 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
466 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
468 UInt diagIndex = srcRowElement - srcBlock.firstRowIndex();
469 Int destRow = destBlock.firstRowIndex() + diagIndex;
470 Int destIndex = destBlock.firstColumnIndex() + diagIndex;
471 Real diagValue = 0.0;
473 for (
Int j (0); j < numSrcEntries; ++j)
475 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
478 if (srcGlobalIndex - srcBlock.firstColumnIndex() == diagIndex)
481 ASSERT ( srcValues[j] != 0,
"You cannot ask for inverse squared diagonal block when there are zeros on the diagonal" );
483 diagValue = 1 / std::sqrt (srcValues[j]);
487 if (srcBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
489 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &diagValue, &destIndex);
493 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &diagValue, &destIndex);
504 template<
typename DataType >
505 void createInvSquaredDiagBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
506 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
508 createInvSquaredDiagBlock ( *srcBlock, *destBlock );
516 template<
typename DataType >
517 void createUpperTriangularBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
518 const MatrixEpetraStructuredView<DataType>& destBlock )
521 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
522 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
533 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
534 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
535 UInt srcRowElement (0);
538 Int rowsOffset (destBlock.firstRowIndex() - srcBlock.firstRowIndex() );
539 Int columnsOffset (destBlock.firstColumnIndex() - srcBlock.firstColumnIndex() );
545 UInt srcGlobalIndex (0);
548 for (
Int i (0); i < numSrcElements; ++i)
551 srcRowElement = srcGlobalElements[i];
554 if ( (srcRowElement >= srcBlock.firstRowIndex() ) && (srcRowElement <= srcBlock.lastRowIndex() ) )
557 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
558 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
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)
566 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
571 if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() ) &&
572 (srcGlobalIndex <= srcBlock.lastColumnIndex() ) &&
573 (srcGlobalIndex - srcBlock.firstColumnIndex() >= srcRowElement - srcBlock.firstRowIndex() ) )
575 destIndices[numDestEntries] = srcGlobalIndex + columnsOffset;
576 destValues[numDestEntries] = srcValues[j];
580 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
582 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
586 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
597 template<
typename DataType >
598 void createUpperTriangularBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
599 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
601 createUpperTriangularBlock ( *srcBlock, *destBlock );
609 template<
typename DataType >
610 void createLowerTriangularBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
611 const MatrixEpetraStructuredView<DataType>& destBlock )
614 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
615 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
626 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
627 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
628 UInt srcRowElement (0);
631 Int rowsOffset (destBlock.firstRowIndex() - srcBlock.firstRowIndex() );
632 Int columnsOffset (destBlock.firstColumnIndex() - srcBlock.firstColumnIndex() );
638 UInt srcGlobalIndex (0);
641 for (
Int i (0); i < numSrcElements; ++i)
644 srcRowElement = srcGlobalElements[i];
647 if ( (srcRowElement >= srcBlock.firstRowIndex() ) && (srcRowElement <= srcBlock.lastRowIndex() ) )
650 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
651 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
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)
659 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
664 if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() ) &&
665 (srcGlobalIndex <= srcBlock.lastColumnIndex() ) &&
666 (srcGlobalIndex - srcBlock.firstColumnIndex() <= srcRowElement - srcBlock.firstRowIndex() ) )
668 destIndices[numDestEntries] = srcGlobalIndex + columnsOffset;
669 destValues[numDestEntries] = srcValues[j];
673 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
675 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
679 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, numDestEntries, &destValues[0], &destIndices[0]);
690 template<
typename DataType >
691 void createLowerTriangularBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
692 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
694 createLowerTriangularBlock ( *srcBlock, *destBlock );
703 template<
typename DataType >
704 void createLumpedBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
705 const MatrixEpetraStructuredView<DataType>& destBlock )
708 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
709 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
722 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
723 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
724 UInt srcRowElement (0);
730 UInt srcGlobalIndex (0);
733 for (
Int i (0); i < numSrcElements; ++i)
736 srcRowElement = srcGlobalElements[i];
739 if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
742 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
743 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
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)
751 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
754 if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() + indexBase) &&
755 (srcGlobalIndex <= srcBlock.lastColumnIndex() + indexBase) )
757 srcBlockRowSum += abs (srcValues[j]);
760 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
762 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
766 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
777 template<
typename DataType >
778 void createLumpedBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
779 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
781 createLumpedBlock ( *srcBlock, *destBlock );
789 template<
typename DataType >
790 void createInvLumpedBlock (
const MatrixEpetraStructuredView<DataType>& srcBlock,
791 const MatrixEpetraStructuredView<DataType>& destBlock )
794 ASSERT ( srcBlock.numRows() == srcBlock.numColumns() ,
"The source block must be square" );
795 ASSERT ( destBlock.numRows() == destBlock.numColumns() ,
"The destination block must be square" );
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" );
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" );
808 Int numSrcElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().NumMyElements();
809 Int* srcGlobalElements = srcBlock.matrixPtr()->matrixPtr()->RowMap().MyGlobalElements();
810 UInt srcRowElement (0);
816 UInt srcGlobalIndex (0);
819 for (
Int i (0); i < numSrcElements; ++i)
822 srcRowElement = srcGlobalElements[i];
825 if ( (srcRowElement >= srcBlock.firstRowIndex() + indexBase) && (srcRowElement <= srcBlock.lastRowIndex() + indexBase) )
828 srcRow = srcBlock.matrixPtr()->matrixPtr()->LRID (
static_cast<
EpetraInt_Type> (srcRowElement) );
829 srcBlock.matrixPtr()->matrixPtr()->ExtractMyRowView (srcRow, numSrcEntries, srcValues, srcIndices);
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)
837 srcGlobalIndex = srcBlock.matrixPtr()->matrixPtr()->GCID (srcIndices[j]);
840 if ( (srcGlobalIndex >= srcBlock.firstColumnIndex() + indexBase) &&
841 (srcGlobalIndex <= srcBlock.lastColumnIndex() + indexBase) )
843 srcBlockRowSum += abs (srcValues[j]);
848 ASSERT ( srcBlockRowSum != 0,
"You cannot ask for inverse lumped block when there are rows of zeros" );
850 srcBlockRowSum = 1. / srcBlockRowSum;
851 if (destBlock.matrixPtr()->matrixPtr()->Map().MyGID (destRow) )
853 destBlock.matrixPtr()->matrixPtr()->InsertGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
857 destBlock.matrixPtr()->matrixPtr()->SumIntoGlobalValues (destRow, 1, &srcBlockRowSum, &destIndex);
868 template<
typename DataType >
869 void createInvLumpedBlock ( std::shared_ptr< MatrixEpetraStructuredView<DataType> > srcBlock,
870 std::shared_ptr< MatrixEpetraStructuredView<DataType> > destBlock )
872 createInvLumpedBlock ( *srcBlock, *destBlock );
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 )
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" );
894 destMatrix.reset (
new MatrixEpetraStructured<DataType> ( rowMap, srcBlock.matrixPtr()->meanNumEntries() ) );
897 copyBlock ( srcBlock, * ( destMatrix->block ( 0, 0 ) ) );
902 destMatrix->globalAssemble();
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 )
920 createMatrixFromBlock ( *srcBlock, destMatrix, rowMap, closeMatrix );
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 )
942 if ( domainMap->mapSize() > rangeMap->mapSize() )
944 destMatrix.reset (
new MatrixEpetraStructured<DataType> ( *domainMap, srcBlock.matrixPtr()->meanNumEntries() ) );
948 destMatrix.reset (
new MatrixEpetraStructured<DataType> ( *rangeMap, srcBlock.matrixPtr()->meanNumEntries() ) );
952 copyBlock ( srcBlock, * ( destMatrix->block ( 0, 0 ) ) );
957 destMatrix->globalAssemble ( domainMap, rangeMap );
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 )
977 createMatrixFromBlock ( *srcBlock, destMatrix, domainMap, rangeMap, closeMatrix );
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 )
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) " );
997 std::shared_ptr< MatrixEpetraStructuredView<DataType> > matrixBlockView (
new MatrixEpetraStructuredView<DataType> );
999 matrixBlockView->setup ( blockStructure.rowBlockFirstIndex ( rowIndex ),
1000 blockStructure.columnBlockFirstIndex ( columnIndex ),
1001 blockStructure.blockNumRows ( rowIndex ),
1002 blockStructure.blockNumColumns ( columnIndex ),
1006 return matrixBlockView;
1017 template <
typename DataType>
1019 fillBlockView ( std::shared_ptr<MatrixEpetra<DataType> > matrixPtr,
1020 const MatrixBlockStructure& blockStructure,
1021 const UInt& rowIndex,
1022 const UInt& columnIndex,
1023 MatrixEpetraStructuredView<DataType>& blockView )
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) " );
1028 blockView.setup ( blockStructure.rowBlockFirstIndex ( rowIndex ),
1029 blockStructure.columnBlockFirstIndex ( columnIndex ),
1030 blockStructure.blockNumRows ( rowIndex ),
1031 blockStructure.blockNumColumns ( columnIndex ),
1043 template <
typename DataType>
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 )
1051 if ( blockView.get() == 0 )
1053 blockView.reset (
new MatrixEpetraStructuredView<DataType> );
1055 fillBlockView ( matrixPtr, blockStructure, rowIndex, columnIndex, *blockView );
void assignFunction(bcBase_Type &base)
Assign the function to the base of the BCHandler.
int32_type Int
Generic integer data.
double Real
Generic real data.
int EpetraInt_Type
Epetra int type (can be int or long long, accordingly to release notes)
uint32_type UInt
generic unsigned integer (used mainly for addressing)