1 #ifndef DUNE_FEM_ISTLMATRIXWRAPPER_HH 2 #define DUNE_FEM_ISTLMATRIXWRAPPER_HH 16 #include <dune/common/exceptions.hh> 19 #include <dune/istl/bvector.hh> 20 #include <dune/istl/bcrsmatrix.hh> 21 #include <dune/istl/preconditioners.hh> 44 struct ISTLMatrixParameter
45 :
public MatrixParameter
48 ISTLMatrixParameter(
const std::string keyPrefix =
"istl." )
49 : keyPrefix_( keyPrefix )
52 virtual double overflowFraction ()
const 54 return Parameter::getValue< double >( keyPrefix_ +
"matrix.overflowfraction", 1.0 );
57 virtual int numIterations ()
const 59 return Parameter::getValue< int >( keyPrefix_ +
"preconditioning.iterations", 5 );
62 virtual double relaxation ()
const 64 return Parameter::getValue< double >( keyPrefix_ +
"preconditioning.relaxation", 1.1 );
67 virtual int method ()
const 69 static const std::string preConTable[]
70 = {
"none",
"ssor",
"sor",
"ilu-0",
"ilu-n",
"gauss-seidel",
"jacobi",
"amg-ilu-0",
"amg-ilu-n",
"amg-jacobi" };
74 virtual std::string preconditionName()
const 76 static const std::string preConTable[]
77 = {
"None",
"SSOR",
"SOR",
"ILU-0",
"ILU-n",
"Gauss-Seidel",
"Jacobi",
"AMG-ILU-0",
"AMG-ILU-n",
"AMG-Jacobi" };
78 const int precond = method();
79 std::stringstream tmp;
80 tmp << preConTable[precond];
83 tmp <<
" n=" << numIterations();
84 tmp <<
" relax=" << relaxation();
89 std::string keyPrefix_;
96 template <
class LittleBlockType,
class RowDiscreteFunctionImp,
class ColDiscreteFunctionImp = RowDiscreteFunctionImp>
97 class ImprovedBCRSMatrix :
public BCRSMatrix<LittleBlockType>
100 typedef RowDiscreteFunctionImp RowDiscreteFunctionType;
101 typedef ColDiscreteFunctionImp ColDiscreteFunctionType;
103 typedef BCRSMatrix<LittleBlockType> BaseType;
105 typedef BaseType MatrixBaseType;
106 typedef typename BaseType :: RowIterator RowIteratorType ;
107 typedef typename BaseType :: ColIterator ColIteratorType ;
109 typedef ImprovedBCRSMatrix< LittleBlockType, RowDiscreteFunctionImp, ColDiscreteFunctionImp > ThisType;
111 typedef typename BaseType :: size_type size_type;
116 typedef typename BaseType::field_type field_type;
119 typedef typename BaseType::block_type block_type;
122 typedef typename BaseType:: allocator_type allocator_type;
125 typedef typename BaseType :: row_type row_type;
130 blocklevel = BaseType :: blocklevel
134 typedef typename BaseType :: ColIterator ColIterator;
137 typedef typename BaseType :: ConstColIterator ConstColIterator;
140 typedef typename BaseType :: RowIterator RowIterator;
143 typedef typename BaseType :: ConstRowIterator ConstRowIterator;
146 typedef typename ColDiscreteFunctionType :: DiscreteFunctionSpaceType RangeSpaceType;
149 typedef typename RowDiscreteFunctionType :: DofStorageType RowBlockVectorType;
152 typedef typename ColDiscreteFunctionType :: DofStorageType ColBlockVectorType;
155 typedef typename RangeSpaceType :: GridType :: Traits :: CollectiveCommunication CollectiveCommunictionType ;
157 typedef typename BaseType :: BuildMode BuildMode ;
161 ImprovedBCRSMatrix(size_type rows, size_type cols, size_type nnz,
double overflowFraction) :
162 BaseType (rows, cols, nnz, overflowFraction, BaseType::implicit)
166 ImprovedBCRSMatrix(size_type rows, size_type cols, size_type nz = 0 ) :
167 BaseType (rows, cols, BaseType :: row_wise)
171 ImprovedBCRSMatrix( ) :
176 ImprovedBCRSMatrix(
const ImprovedBCRSMatrix& org) :
180 template <
class RowKeyType,
class ColKeyType>
181 void createEntries(
const std::map<RowKeyType , std::set<ColKeyType> >& indices)
184 auto endcreate = this->createend();
185 for(
auto create = this->createbegin(); create != endcreate; ++create)
187 const auto it = indices.find( create.index() );
188 if (it == indices.end() )
190 const auto& localIndices = it->second;
191 const auto end = localIndices.end();
193 for (
auto it = localIndices.begin(); it != end; ++it)
194 create.insert( *it );
201 for (
auto& row : *
this)
202 for (
auto& entry : row)
207 template <
class HangingNodesType>
208 void setup(ThisType& oldMatrix,
const HangingNodesType& hangingNodes)
211 typedef std::set< std::pair<int, block_type> > LocalEntryType;
212 typedef std::map< int , LocalEntryType > EntriesType;
216 std::map< int , std::set<int> > indices;
218 auto rowend = oldMatrix.end();
219 for(
auto it = oldMatrix.begin(); it != rowend; ++it)
221 const auto row = it.index();
222 auto& localIndices = indices[ row ];
224 if( hangingNodes.isHangingNode( row ) )
227 const auto& cols = hangingNodes.associatedDofs( row );
228 const auto colSize = cols.size();
229 for(
auto i=0; i<colSize; ++i)
231 assert( ! hangingNodes.isHangingNode( cols[i].first ) );
234 auto& localColIndices = indices[ cols[i].first ];
235 auto& localEntry = entries[ cols[i].first ];
238 auto endj = (*it).end();
239 for (
auto j= (*it).begin(); j!=endj; ++j)
241 localColIndices.insert( j.index () );
242 localEntry.insert( std::make_pair( j.index(), (cols[i].second * (*j)) ));
247 localIndices.insert( row );
248 for(
auto i=0; i<colSize; ++i)
249 localIndices.insert( cols[i].first );
254 auto endj = (*it).end();
255 for (
auto j= (*it).begin(); j!=endj; ++j)
256 localIndices.insert( j.index () );
261 createEntries( indices );
264 auto rowit = oldMatrix.begin();
266 auto endcreate = this->end();
267 for(
auto create = this->begin(); create != endcreate; ++create, ++rowit )
269 assert( rowit != oldMatrix.end() );
271 const auto row = create.index();
272 if( hangingNodes.isHangingNode( row ) )
274 const auto& cols = hangingNodes.associatedDofs( row );
276 std::map< const int , block_type > colMap;
278 assert( block_type :: rows == 1 );
280 const auto colSize = cols.size();
281 for(
auto i=0; i<colSize; ++i)
282 colMap[ cols[i].first ] = -cols[i].second;
286 auto endj = (*create).end();
287 for (
auto j= (*create).begin(); j!=endj; ++j)
289 assert( colMap.find( j.index() ) != colMap.end() );
290 (*j) = colMap[ j.index() ];
294 else if ( entries.find( row ) == entries.end() )
296 auto colit = (*rowit).begin();
297 auto endj = (*create).end();
298 for (
auto j= (*create).begin(); j!=endj; ++j, ++colit )
300 assert( colit != (*rowit).end() );
306 std::map< int , block_type > oldCols;
309 auto colend = (*rowit).end();
310 for(
auto colit = (*rowit).begin(); colit != colend; ++colit)
311 oldCols[ colit.index() ] = 0;
314 auto entry = entries.find( row );
315 assert( entry != entries.end ());
318 auto endcol = (*entry).second.end();
319 for(
auto co = (*entry).second.begin(); co != endcol; ++co)
320 oldCols[ (*co).first ] = 0;
324 auto colend = (*rowit).end();
325 for(
auto colit = (*rowit).begin(); colit != colend; ++colit)
326 oldCols[ colit.index() ] += (*colit);
330 auto endcol = (*entry).second.end();
331 for(
auto co = (*entry).second.begin(); co != endcol; ++co)
332 oldCols[ (*co).first ] += (*co).second;
335 auto endj = (*create).end();
336 for (
auto j= (*create).begin(); j!=endj; ++j )
338 auto colEntry = oldCols.find( j.index() );
339 if( colEntry != oldCols.end() )
340 (*j) = (*colEntry).second;
349 void extractDiagonal( ColBlockVectorType& diag )
const 351 const auto endi = this->end();
352 for (
auto i = this->begin(); i!=endi; ++i)
355 const auto row = i.index();
356 auto entry = (*i).find( row );
357 const LittleBlockType& block = (*entry);
358 enum { blockSize = LittleBlockType :: rows };
359 for(
auto l=0; l<blockSize; ++l )
360 diag[ row ][ l ] = block[ l ][ l ];
366 field_type operator()(
const std::size_t row,
const std::size_t col)
const 368 const std::size_t blockRow(row/(LittleBlockType :: rows));
369 const std::size_t localRowIdx(row%(LittleBlockType :: rows));
370 const std::size_t blockCol(col/(LittleBlockType :: cols));
371 const std::size_t localColIdx(col%(LittleBlockType :: cols));
373 const auto& matrixRow(this->
operator[](blockRow));
374 auto entry = matrixRow.find( blockCol );
375 const LittleBlockType& block = (*entry);
376 return block[localRowIdx][localColIdx];
381 void set(
const std::size_t row,
const std::size_t col, field_type value)
383 const std::size_t blockRow(row/(LittleBlockType :: rows));
384 const std::size_t localRowIdx(row%(LittleBlockType :: rows));
385 const std::size_t blockCol(col/(LittleBlockType :: cols));
386 const std::size_t localColIdx(col%(LittleBlockType :: cols));
388 auto& matrixRow(this->
operator[](blockRow));
389 auto entry = matrixRow.find( blockCol );
390 LittleBlockType& block = (*entry);
391 block[localRowIdx][localColIdx] = value;
395 void print(std::ostream& s,
unsigned int offset=0)
const 398 const auto endi=this->end();
399 for (
auto i=this->begin(); i!=endi; ++i)
401 const auto endj = (*i).end();
402 for (
auto j=(*i).begin(); j!=endj; ++j)
403 if( (*j).infinity_norm() > 1.e-15)
404 s << i.index()+offset <<
" " << j.index()+offset <<
" " << *j << std::endl;
409 template <
class RowSpaceImp,
class ColSpaceImp>
410 class ISTLMatrixObject;
412 template <
class RowSpaceImp,
class ColSpaceImp = RowSpaceImp>
413 struct ISTLMatrixTraits
415 typedef RowSpaceImp RangeSpaceType;
416 typedef ColSpaceImp DomainSpaceType;
417 typedef ISTLMatrixTraits<DomainSpaceType,RangeSpaceType> ThisType;
419 typedef ISTLMatrixObject<DomainSpaceType,RangeSpaceType> MatrixObjectType;
423 template <
class DomainSpaceImp,
class RangeSpaceImp>
424 class ISTLMatrixObject
428 typedef DomainSpaceImp DomainSpaceType;
430 typedef RangeSpaceImp RangeSpaceType;
433 typedef ISTLMatrixObject<DomainSpaceType,RangeSpaceType> ThisType;
435 typedef typename DomainSpaceType::GridType GridType;
437 typedef typename RangeSpaceType :: EntityType RangeEntityType ;
438 typedef typename DomainSpaceType :: EntityType DomainEntityType ;
440 enum { littleCols = DomainSpaceType :: localBlockSize };
441 enum { littleRows = RangeSpaceType :: localBlockSize };
443 typedef FieldMatrix<typename DomainSpaceType :: RangeFieldType, littleRows, littleCols> LittleBlockType;
445 typedef ISTLBlockVectorDiscreteFunction< RangeSpaceType > RowDiscreteFunctionType;
446 typedef ISTLBlockVectorDiscreteFunction< DomainSpaceType > ColumnDiscreteFunctionType;
449 typedef typename RowDiscreteFunctionType :: DofStorageType RowBlockVectorType;
450 typedef typename ColumnDiscreteFunctionType :: DofStorageType ColumnBlockVectorType;
452 typedef typename RangeSpaceType :: BlockMapperType RowMapperType;
453 typedef typename DomainSpaceType :: BlockMapperType ColMapperType;
457 typedef ImprovedBCRSMatrix< LittleBlockType , ColumnDiscreteFunctionType , RowDiscreteFunctionType > MatrixType;
458 typedef typename ISTLParallelMatrixAdapter<MatrixType,RangeSpaceType>::Type MatrixAdapterType;
459 typedef typename MatrixAdapterType :: ParallelScalarProductType ParallelScalarProductType;
461 template <
class MatrixObjectImp>
464 struct LocalMatrixTraits
466 typedef DomainSpaceImp DomainSpaceType;
467 typedef RangeSpaceImp RangeSpaceType;
468 typedef typename DomainSpaceType :: RangeFieldType RangeFieldType;
469 typedef LocalMatrix<ThisType> LocalMatrixType;
470 typedef typename MatrixType:: block_type LittleBlockType;
474 template <
class MatrixObjectImp>
475 class LocalMatrix :
public LocalMatrixDefault<LocalMatrixTraits>
479 typedef LocalMatrixDefault<LocalMatrixTraits> BaseType;
482 typedef MatrixObjectImp MatrixObjectType;
484 typedef typename MatrixObjectImp :: MatrixType MatrixType;
486 typedef typename MatrixType::block_type LittleBlockType;
488 typedef typename MatrixObjectType::DomainSpaceType DomainSpaceType;
489 typedef typename MatrixObjectType::RangeSpaceType RangeSpaceType;
491 typedef typename MatrixObjectType::DomainEntityType DomainEntityType;
492 typedef typename MatrixObjectType::RangeEntityType RangeEntityType;
495 typedef typename DomainSpaceType::RangeFieldType DofType;
496 typedef typename MatrixType::row_type RowType;
499 typedef typename DomainSpaceType::BlockMapperType ColMapperType;
501 typedef typename RangeSpaceType::BlockMapperType RowMapperType;
503 static const int littleCols = MatrixObjectType::littleCols;
504 static const int littleRows = MatrixObjectType::littleRows;
506 LocalMatrix (
const MatrixObjectType& mObj,
const DomainSpaceType& domainSpace,
const RangeSpaceType& rangeSpace )
507 : BaseType( domainSpace, rangeSpace ),
508 rowMapper_( rangeSpace.blockMapper() ),
509 colMapper_( domainSpace.blockMapper() ),
510 numRows_( rowMapper_.maxNumDofs() ),
511 numCols_( colMapper_.maxNumDofs() ),
515 LocalMatrix (
const LocalMatrix& org )
517 rowMapper_(org.rowMapper_),
518 colMapper_(org.colMapper_),
519 numRows_( org.numRows_ ),
520 numCols_( org.numCols_ ),
521 matrices_(org.matrices_),
522 matrixObj_(org.matrixObj_)
527 void init (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity )
530 BaseType :: init ( domainEntity, rangeEntity );
532 numRows_ = rowMapper_.numDofs( rangeEntity );
533 numCols_ = colMapper_.numDofs( domainEntity );
534 matrices_.resize( numRows_, numCols_,
nullptr );
536 typedef typename MatrixType::size_type Index;
537 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
539 if( matrixObj_.implicitModeActive() )
540 return matrixObj_.matrix().entry( index.first, index.second );
542 return matrixObj_.matrix()[ index.first ][ index.second ];
545 auto functor = [
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
547 matrices_[ local.first ][ local.second ] = &blockAccess( index );
550 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
555 void check(
int localRow,
int localCol)
const 557 const std::size_t row = (int) localRow / littleRows;
558 const std::size_t col = (int) localCol / littleCols;
559 const int lRow = localRow%littleRows;
560 const int lCol = localCol%littleCols;
561 assert( row < matrices_.size() ) ;
562 assert( col < matrices_[row].size() );
563 assert( lRow < littleRows );
564 assert( lCol < littleCols );
567 DofType& getValue(
const int localRow,
const int localCol)
569 const int row = (int) localRow / littleRows;
570 const int col = (int) localCol / littleCols;
571 const int lRow = localRow%littleRows;
572 const int lCol = localCol%littleCols;
573 return (*matrices_[row][col])[lRow][lCol];
577 const DofType
get(
const int localRow,
const int localCol)
const 579 const int row = (int) localRow / littleRows;
580 const int col = (int) localCol / littleCols;
581 const int lRow = localRow%littleRows;
582 const int lCol = localCol%littleCols;
583 return (*matrices_[row][col])[lRow][lCol];
586 void scale (
const DofType& scalar)
588 for(
auto i=0; i<matrices_.size(); ++i)
589 for(
auto j=0; j<matrices_[i].size(); ++j)
590 (*matrices_[i][j]) *= scalar;
593 void add(
const int localRow,
const int localCol ,
const DofType value)
596 check(localRow,localCol);
598 getValue(localRow,localCol) += value;
601 void set(
const int localRow,
const int localCol ,
const DofType value)
604 check(localRow,localCol);
606 getValue(localRow,localCol) = value;
610 void unitRow(
const int localRow)
612 const int row = (int) localRow / littleRows;
613 const int lRow = localRow%littleRows;
616 doClearRow( row, lRow );
619 (*matrices_[row][row])[lRow][lRow] = 1;
625 for(
auto i=0; i<matrices_.size(); ++i)
626 for(
auto j=0; j<matrices_[i].size(); ++j)
627 (*matrices_[i][j]) = (DofType) 0;
631 void clearRow (
const int localRow )
633 const int row = (int) localRow / littleRows;
634 const int lRow = localRow%littleRows;
637 doClearRow( row, lRow );
646 void doClearRow (
const int row,
const int lRow )
649 const auto col = this->columns();
650 for(
auto localCol=0; localCol<col; ++localCol)
652 const int col = (int) localCol / littleCols;
653 const int lCol = localCol%littleCols;
654 (*matrices_[row][col])[lRow][lCol] = 0;
660 const RowMapperType& rowMapper_;
661 const ColMapperType& colMapper_;
668 Dune::DynamicMatrix< LittleBlockType* > matrices_;
671 const MatrixObjectType& matrixObj_;
675 typedef LocalMatrix<ThisType> ObjectType;
676 typedef ThisType LocalMatrixFactoryType;
679 typedef LocalMatrixWrapper< LocalMatrixStackType > LocalMatrixType;
680 typedef ColumnObject< ThisType > LocalColumnObjectType;
683 const DomainSpaceType & domainSpace_;
684 const RangeSpaceType & rangeSpace_;
687 RowMapperType& rowMapper_;
689 ColMapperType& colMapper_;
695 mutable MatrixType* matrix_;
697 mutable LocalMatrixStackType localMatrixStack_;
699 mutable MatrixAdapterType* matrixAdap_;
700 mutable ColumnBlockVectorType* Arg_;
701 mutable RowBlockVectorType* Dest_;
703 const double overflowFraction_;
706 ISTLMatrixObject(
const ISTLMatrixObject&);
712 ISTLMatrixObject (
const DomainSpaceType &domainSpace,
const RangeSpaceType &rangeSpace,
const std::string& paramfile )
713 DUNE_DEPRECATED_MSG(
"ISTLMatrixObject(...,string) is deprecated. Use ISTLMatrixObject(DomainSpace,RangeSpace,MatrixParameter) instead")
714 : domainSpace_(domainSpace)
715 , rangeSpace_(rangeSpace)
716 , rowMapper_( rangeSpace.blockMapper() )
717 , colMapper_( domainSpace.blockMapper() )
722 , localMatrixStack_( *this )
723 , matrixAdap_(nullptr)
726 , overflowFraction_( Parameter::getValue(
"istl.matrix.overflowfraction", 1.0 ) )
732 ISTLMatrixObject (
const DomainSpaceType &domainSpace,
const RangeSpaceType &rangeSpace,
const MatrixParameter& param = ISTLMatrixParameter() ) :
733 domainSpace_(domainSpace)
734 , rangeSpace_(rangeSpace)
735 , rowMapper_( rangeSpace.blockMapper() )
736 , colMapper_( domainSpace.blockMapper() )
740 , localMatrixStack_( *this )
741 , matrixAdap_(nullptr)
744 , overflowFraction_( param.overflowFraction() )
748 static const bool assembled = true ;
750 const ThisType& systemMatrix()
const 754 ThisType& systemMatrix()
766 MatrixType & matrix()
const 772 void printTexInfo(std::ostream& out)
const 774 out <<
"ISTL MatrixObj: ";
779 std::string preconditionName()
const 784 void createMatrixAdapter ()
const 787 matrixAdap_ =
new MatrixAdapterType( matrixAdapterObject() );
788 assert( matrixAdap_ );
792 const MatrixAdapterType& matrixAdapter()
const 794 createMatrixAdapter();
797 MatrixAdapterType& matrixAdapter()
799 createMatrixAdapter();
804 MatrixAdapterType matrixAdapterObject()
const 807 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
808 return MatrixAdapterType(matrix(), domainSpace(), rangeSpace(), PreConType() );
812 bool implicitModeActive()
const 818 if( matrix().buildMode() == MatrixType::implicit && matrix().buildStage() == MatrixType::building )
827 if( implicitModeActive() )
833 bool hasPreconditionMatrix()
const 847 template <
class Stencil>
848 void reserve(
const Stencil &stencil,
const bool implicit =
true )
851 if(sequence_ != domainSpace().sequence())
857 auto nnz = stencil.maxNonZerosEstimate();
860 Stencil tmpStencil( stencil );
861 tmpStencil.fill( *(domainSpace_.begin()), *(rangeSpace_.begin()) );
862 nnz = tmpStencil.maxNonZerosEstimate();
864 matrix_ =
new MatrixType( rowMapper_.size(), colMapper_.size(), nnz, overflowFraction_ );
868 matrix_ =
new MatrixType( rowMapper_.size(), colMapper_.size() );
869 matrix().createEntries( stencil.globalStencil() );
872 sequence_ = domainSpace().sequence();
877 template <
class HangingNodesType>
878 void changeHangingNodes(
const HangingNodesType& hangingNodes)
881 MatrixType* newMatrix =
new MatrixType(rowMapper_.size(), colMapper_.size());
884 newMatrix->setup( *matrix_ , hangingNodes );
895 void extractDiagonal( ColumnDiscreteFunctionType& diag )
const 898 matrix().extractDiagonal( diag.blockVector() );
902 bool rightPrecondition()
const 908 void multOEM(
const double* arg,
double* dest)
const 910 createBlockVectors();
912 RowBlockVectorType& Arg = *Arg_;
913 ColumnBlockVectorType &Dest = *Dest_;
915 std::copy_n( arg, Arg.size(), Arg.dbegin() );
918 matrixAdapter().apply( Arg, Dest );
920 std::copy( Dest.dbegin(), Dest.dend(), dest );
924 void apply(
const ColumnDiscreteFunctionType& arg, RowDiscreteFunctionType& dest)
const 926 matrixAdapter().apply( arg.blockVector(), dest.blockVector() );
930 template <
class RowDFType,
class ColDFType>
931 void apply(
const RowDFType& arg, ColDFType& dest)
const 933 multOEM( arg.dofVector(), dest.dofVector ());
937 template <
class ColumnLeakPo
interType,
class RowLeakPo
interType>
938 void multOEM(
const ColumnLeakPointerType& arg, RowLeakPointerType& dest)
const 940 DUNE_THROW(NotImplemented,
"Method has been removed");
944 double ddotOEM(
const double* v,
const double* w)
const 946 createBlockVectors();
948 RowBlockVectorType& V = *Arg_;
949 ColumnBlockVectorType& W = *Dest_;
951 std::copy_n( v, V.size(), V.dbegin() );
952 std::copy_n( w, W.size(), W.dbegin() );
956 ISTLBlockVectorDiscreteFunction< DomainSpaceType > vF(
"ddotOEM:vF", domainSpace(), V );
957 ISTLBlockVectorDiscreteFunction< RangeSpaceType > wF(
"ddotOEM:wF", rangeSpace(), W );
958 return vF.scalarProductDofs( wF );
970 void createPreconditionMatrix()
974 void print(std::ostream & s)
const 979 const DomainSpaceType& domainSpace()
const 983 const RangeSpaceType& rangeSpace()
const 988 const RowMapperType& rowMapper()
const 992 const ColMapperType& colMapper()
const 998 ObjectType* newObject()
const 1000 return new ObjectType(*
this, domainSpace(), rangeSpace());
1004 LocalMatrixType localMatrix(
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity )
const 1006 return LocalMatrixType( localMatrixStack_, domainEntity, rangeEntity );
1008 LocalColumnObjectType localColumn(
const DomainEntityType &domainEntity )
const 1010 return LocalColumnObjectType ( *
this, domainEntity );
1013 template<
class LocalMatrix >
1014 void addLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat )
1016 typedef typename MatrixType::size_type Index;
1017 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1019 if( implicitModeActive() )
1020 return matrix().entry( index.first, index.second );
1022 return matrix()[ index.first ][ index.second ];
1025 auto functor = [ &localMat,
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1027 LittleBlockType& block = blockAccess( index );
1028 for( std::size_t i = 0; i < littleRows; ++i )
1029 for( std::size_t j = 0; j < littleCols; ++j )
1030 block[ i ][ j ] += localMat.get( local.first * littleRows + i, local.second *littleCols + j );
1033 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1037 template<
class LocalMatrix >
1038 void setLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat )
1040 typedef typename MatrixType::size_type Index;
1041 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1043 if( implicitModeActive() )
1044 return matrix().entry( index.first, index.second );
1046 return matrix()[ index.first ][ index.second ];
1049 auto functor = [ &localMat,
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1051 LittleBlockType& block = blockAccess( index );
1052 for( std::size_t i = 0; i < littleRows; ++i )
1053 for( std::size_t j = 0; j < littleCols; ++j )
1054 block[ i ][ j ] = localMat.get( local.first * littleRows + i, local.second *littleCols + j );
1057 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1060 template<
class LocalMatrix,
class Scalar >
1061 void addScaledLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat,
const Scalar &s )
1063 typedef typename MatrixType::size_type Index;
1064 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1066 if( implicitModeActive() )
1067 return matrix().entry( index.first, index.second );
1069 return matrix()[ index.first ][ index.second ];
1072 auto functor = [ &localMat, &s,
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1074 LittleBlockType& block = blockAccess( index );
1075 for( std::size_t i = 0; i < littleRows; ++i )
1076 for( std::size_t j = 0; j < littleCols; ++j )
1077 block[ i ][ j ] += s * localMat.get( local.first * littleRows + i, local.second *littleCols + j );
1080 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1083 template<
class LocalMatrix >
1084 void getLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity, LocalMatrix &localMat )
const 1086 typedef typename MatrixType::size_type Index;
1087 auto functor = [ &localMat, this ] ( std::pair< int, int > local,
const std::pair< Index, Index > &global )
1089 for( std::size_t i = 0; i < littleRows; ++i )
1090 for( std::size_t j = 0; j < littleCols; ++j )
1091 localMat.set( local.first * littleRows + i, local.second *littleCols + j,
1092 matrix()[ global.first ][ global.second ][i][j] );
1095 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1099 void preConErrorMsg(
int preCon)
const 1104 void removeObj(
const bool alsoClearMatrix )
1111 matrixAdap_ =
nullptr;
1113 if( alsoClearMatrix )
1120 void createBlockVectors()
const 1122 if( Arg_ ==
nullptr || Dest_ ==
nullptr )
1126 Arg_ =
new RowBlockVectorType( rowMapper_.size() );
1127 Dest_ =
new ColumnBlockVectorType( colMapper_.size() );
1129 createMatrixAdapter ();
1135 template <
class SpaceImp>
1136 class ISTLMatrixObject<SpaceImp,SpaceImp>
1139 typedef SpaceImp DomainSpaceImp;
1140 typedef SpaceImp RangeSpaceImp;
1142 typedef DomainSpaceImp DomainSpaceType;
1144 typedef RangeSpaceImp RangeSpaceType;
1147 typedef ISTLMatrixObject<DomainSpaceType,RangeSpaceType> ThisType;
1149 typedef typename DomainSpaceType::GridType GridType;
1151 typedef typename RangeSpaceType :: EntityType RangeEntityType ;
1152 typedef typename DomainSpaceType :: EntityType DomainEntityType;
1154 enum { littleRows = DomainSpaceType :: localBlockSize };
1155 enum { littleCols = RangeSpaceType :: localBlockSize };
1157 typedef FieldMatrix<typename DomainSpaceType :: RangeFieldType, littleRows, littleCols> LittleBlockType;
1159 typedef ISTLBlockVectorDiscreteFunction< DomainSpaceType > RowDiscreteFunctionType;
1160 typedef ISTLBlockVectorDiscreteFunction< RangeSpaceType > ColumnDiscreteFunctionType;
1163 typedef typename RowDiscreteFunctionType :: DofContainerType RowBlockVectorType;
1164 typedef typename ColumnDiscreteFunctionType :: DofContainerType ColumnBlockVectorType;
1166 typedef typename DomainSpaceType :: BlockMapperType RowMapperType;
1167 typedef typename RangeSpaceType :: BlockMapperType ColMapperType;
1171 typedef ImprovedBCRSMatrix< LittleBlockType , RowDiscreteFunctionType , ColumnDiscreteFunctionType > MatrixType;
1172 typedef typename ISTLParallelMatrixAdapter<MatrixType,DomainSpaceType>::Type MatrixAdapterType;
1174 typedef ThisType PreconditionMatrixType;
1175 typedef typename MatrixAdapterType :: ParallelScalarProductType ParallelScalarProductType;
1177 template <
class MatrixObjectImp>
1180 struct LocalMatrixTraits
1182 typedef DomainSpaceImp DomainSpaceType ;
1183 typedef RangeSpaceImp RangeSpaceType;
1184 typedef typename DomainSpaceType :: RangeFieldType RangeFieldType;
1185 typedef LocalMatrix<ThisType> LocalMatrixType;
1186 typedef typename MatrixType:: block_type LittleBlockType;
1190 template <
class MatrixObjectImp>
1191 class LocalMatrix :
public LocalMatrixDefault<LocalMatrixTraits>
1195 typedef LocalMatrixDefault<LocalMatrixTraits> BaseType;
1198 typedef MatrixObjectImp MatrixObjectType;
1200 typedef typename MatrixObjectImp :: MatrixType MatrixType;
1202 typedef typename MatrixType::block_type LittleBlockType;
1204 typedef typename MatrixObjectType::DomainSpaceType DomainSpaceType;
1205 typedef typename MatrixObjectType::RangeSpaceType RangeSpaceType;
1207 typedef typename MatrixObjectType::DomainEntityType DomainEntityType;
1208 typedef typename MatrixObjectType::RangeEntityType RangeEntityType;
1211 typedef typename DomainSpaceType::RangeFieldType DofType;
1212 typedef typename MatrixType::row_type RowType;
1215 typedef typename DomainSpaceType::BlockMapperType ColMapperType;
1217 typedef typename RangeSpaceType::BlockMapperType RowMapperType;
1219 static const int littleCols = MatrixObjectType::littleCols;
1220 static const int littleRows = MatrixObjectType::littleRows;
1222 LocalMatrix (
const MatrixObjectType& mObj,
const DomainSpaceType& domainSpace,
const RangeSpaceType& rangeSpace )
1223 : BaseType( domainSpace, rangeSpace ),
1224 rowMapper_( rangeSpace.blockMapper() ),
1225 colMapper_( domainSpace.blockMapper() ),
1226 numRows_( rowMapper_.maxNumDofs() ),
1227 numCols_( colMapper_.maxNumDofs() ),
1231 LocalMatrix (
const LocalMatrix& org )
1233 rowMapper_(org.rowMapper_),
1234 colMapper_(org.colMapper_),
1235 numRows_( org.numRows_ ),
1236 numCols_( org.numCols_ ),
1237 matrices_(org.matrices_),
1238 matrixObj_(org.matrixObj_)
1243 void init (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity )
1246 BaseType :: init ( domainEntity, rangeEntity );
1248 numRows_ = rowMapper_.numDofs( rangeEntity );
1249 numCols_ = colMapper_.numDofs( domainEntity );
1250 matrices_.resize( numRows_, numCols_,
nullptr );
1252 typedef typename MatrixType::size_type Index;
1253 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1255 if( matrixObj_.implicitModeActive() )
1256 return matrixObj_.matrix().entry( index.first, index.second );
1258 return matrixObj_.matrix()[ index.first ][ index.second ];
1261 auto functor = [
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1263 matrices_[ local.first ][ local.second ] = &blockAccess( index );
1266 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1271 void check(
int localRow,
int localCol)
const 1273 const std::size_t row = (int) localRow / littleRows;
1274 const std::size_t col = (int) localCol / littleCols;
1275 const int lRow = localRow%littleRows;
1276 const int lCol = localCol%littleCols;
1277 assert( row < matrices_.size() ) ;
1278 assert( col < matrices_[row].size() );
1279 assert( lRow < littleRows );
1280 assert( lCol < littleCols );
1283 DofType& getValue(
const int localRow,
const int localCol)
1285 const int row = (int) localRow / littleRows;
1286 const int col = (int) localCol / littleCols;
1287 const int lRow = localRow%littleRows;
1288 const int lCol = localCol%littleCols;
1289 return (*matrices_[row][col])[lRow][lCol];
1293 const DofType
get(
const int localRow,
const int localCol)
const 1295 const int row = (int) localRow / littleRows;
1296 const int col = (int) localCol / littleCols;
1297 const int lRow = localRow%littleRows;
1298 const int lCol = localCol%littleCols;
1299 return (*matrices_[row][col])[lRow][lCol];
1302 void scale (
const DofType& scalar)
1304 for(
auto i=0; i<matrices_.size(); ++i)
1305 for(
auto j=0; j<matrices_[i].size(); ++j)
1306 (*matrices_[i][j]) *= scalar;
1309 void add(
const int localRow,
const int localCol ,
const DofType value)
1312 check(localRow,localCol);
1314 getValue(localRow,localCol) += value;
1317 void set(
const int localRow,
const int localCol ,
const DofType value)
1320 check(localRow,localCol);
1322 getValue(localRow,localCol) = value;
1326 void unitRow(
const int localRow)
1328 const int row = (int) localRow / littleRows;
1329 const int lRow = localRow%littleRows;
1332 doClearRow( row, lRow );
1335 (*matrices_[row][row])[lRow][lRow] = 1;
1341 for(
auto i=0; i<matrices_.size(); ++i)
1342 for(
auto j=0; j<matrices_[i].size(); ++j)
1343 (*matrices_[i][j]) = (DofType) 0;
1347 void clearRow (
const int localRow )
1349 const int row = (int) localRow / littleRows;
1350 const int lRow = localRow%littleRows;
1353 doClearRow( row, lRow );
1362 void doClearRow (
const int row,
const int lRow )
1365 const auto col = this->columns();
1366 for(
auto localCol=0; localCol<col; ++localCol)
1368 const int col = (int) localCol / littleCols;
1369 const int lCol = localCol%littleCols;
1370 (*matrices_[row][col])[lRow][lCol] = 0;
1376 const RowMapperType& rowMapper_;
1377 const ColMapperType& colMapper_;
1384 Dune::DynamicMatrix< LittleBlockType* > matrices_;
1387 const MatrixObjectType& matrixObj_;
1391 typedef LocalMatrix<ThisType> ObjectType;
1392 typedef ThisType LocalMatrixFactoryType;
1395 typedef LocalMatrixWrapper< LocalMatrixStackType > LocalMatrixType;
1396 typedef ColumnObject< ThisType > LocalColumnObjectType;
1399 const DomainSpaceType & domainSpace_;
1400 const RangeSpaceType & rangeSpace_;
1403 RowMapperType& rowMapper_;
1405 ColMapperType& colMapper_;
1411 mutable MatrixType* matrix_;
1413 ParallelScalarProductType scp_;
1416 double relaxFactor_;
1418 enum ISTLPreConder_Id { none = 0 ,
1430 ISTLPreConder_Id preconditioning_;
1432 mutable LocalMatrixStackType localMatrixStack_;
1434 mutable MatrixAdapterType* matrixAdap_;
1435 mutable RowBlockVectorType* Arg_;
1436 mutable ColumnBlockVectorType* Dest_;
1438 const double overflowFraction_;
1439 const MatrixParameter& param_;
1442 ISTLMatrixObject(
const ISTLMatrixObject&) =
delete;
1444 ISTLMatrixObject (
const DomainSpaceType &rowSpace,
const RangeSpaceType &colSpace,
const std :: string ¶mfile )
1445 DUNE_DEPRECATED_MSG(
"ISTLMatrixObject(...,string) is deprecated. Use ISTLMatrixObject(DomainSpace,RangeSpace,ISTLMatrixParameter) instead")
1446 : domainSpace_(rowSpace)
1447 , rangeSpace_(colSpace)
1448 , colMapper_( colSpace.blockMapper() )
1452 , scp_(rangeSpace())
1455 , preconditioning_(none)
1456 , localMatrixStack_( *this )
1457 , matrixAdap_(nullptr)
1460 , overflowFraction_( Parameter::getValue(
"istl.matrix.overflowfraction", 1.0 ) )
1464 DUNE_THROW(InvalidStateException,
"ISTLMatrixObject: old parameter method disabled");
1467 static const std::string preConTable[]
1468 = {
"none",
"ssor",
"sor",
"ilu-0",
"ilu-n",
"gauss-seidel",
"jacobi",
"amg-ilu-0",
"amg-ilu-n",
"amg-jacobi" };
1470 numIterations_ =
Parameter::getValue(
"istl.preconditioning.iterations", numIterations_ );
1474 if( preCon >= 0 && preCon <= 9)
1475 preconditioning_ = (ISTLPreConder_Id) preCon;
1477 preConErrorMsg(preCon);
1479 assert( rowMapper_.size() == colMapper_.size() );
1489 ISTLMatrixObject (
const DomainSpaceType &rowSpace,
const RangeSpaceType &colSpace,
const MatrixParameter& param = ISTLMatrixParameter() )
1490 : domainSpace_(rowSpace)
1491 , rangeSpace_(colSpace)
1495 , rowMapper_( rowSpace.blockMapper() )
1496 , colMapper_( colSpace.blockMapper() )
1500 , scp_(rangeSpace())
1501 , numIterations_( param.numIterations() )
1502 , relaxFactor_( param.relaxation() )
1503 , preconditioning_( (ISTLPreConder_Id)param.method() )
1504 , localMatrixStack_( *this )
1505 , matrixAdap_(nullptr)
1508 , overflowFraction_( param.overflowFraction() )
1511 assert( rowMapper_.size() == colMapper_.size() );
1515 static const bool assembled = true ;
1517 const ThisType& systemMatrix()
const 1521 ThisType& systemMatrix()
1533 MatrixType & matrix()
const 1539 void printTexInfo(std::ostream& out)
const 1541 out <<
"ISTL MatrixObj: ";
1542 out <<
" preconditioner = " << preconditionName() ;
1547 std::string preconditionName()
const 1549 return param_.preconditionName();
1552 template <
class PreconditionerType>
1553 MatrixAdapterType createMatrixAdapter(
const PreconditionerType* preconditioning, std::size_t numIterations)
const 1555 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
1556 PreConType preconAdapter(matrix(), numIterations, relaxFactor_, preconditioning );
1557 return MatrixAdapterType(matrix(), domainSpace(), rangeSpace(), preconAdapter );
1560 template <
class PreconditionerType>
1561 MatrixAdapterType createAMGMatrixAdapter(
const PreconditionerType* preconditioning, std::size_t numIterations)
const 1563 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
1564 PreConType preconAdapter(matrix(), numIterations, relaxFactor_, preconditioning, domainSpace().gridPart().comm() );
1565 return MatrixAdapterType(matrix(), domainSpace(), rangeSpace(), preconAdapter );
1569 const MatrixAdapterType& matrixAdapter()
const 1571 if( matrixAdap_ ==
nullptr )
1572 matrixAdap_ =
new MatrixAdapterType( matrixAdapterObject() );
1573 return *matrixAdap_;
1575 MatrixAdapterType& matrixAdapter()
1577 if( matrixAdap_ ==
nullptr )
1578 matrixAdap_ =
new MatrixAdapterType( matrixAdapterObject() );
1579 return *matrixAdap_;
1583 MatrixAdapterType matrixAdapterObject()
const 1585 #ifndef DISABLE_ISTL_PRECONDITIONING 1586 const auto procs = domainSpace().gridPart().comm().size();
1588 typedef typename MatrixType :: BaseType ISTLMatrixType;
1589 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
1591 if( preconditioning_ == none )
1593 return MatrixAdapterType(matrix(), domainSpace(),rangeSpace(), PreConType() );
1596 else if( preconditioning_ == ssor )
1599 DUNE_THROW(InvalidStateException,
"ISTL::SeqSSOR not working in parallel computations");
1601 typedef SeqSSOR<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1602 return createMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1605 else if(preconditioning_ == sor )
1608 DUNE_THROW(InvalidStateException,
"ISTL::SeqSOR not working in parallel computations");
1610 typedef SeqSOR<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1611 return createMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1614 else if(preconditioning_ == ilu_0)
1617 DUNE_THROW(InvalidStateException,
"ISTL::SeqILU0 not working in parallel computations");
1619 typedef FemSeqILU0<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1620 return createMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1623 else if(preconditioning_ == ilu_n)
1626 DUNE_THROW(InvalidStateException,
"ISTL::SeqILUn not working in parallel computations");
1628 typedef SeqILUn<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1629 return createMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1632 else if(preconditioning_ == gauss_seidel)
1635 DUNE_THROW(InvalidStateException,
"ISTL::SeqGS not working in parallel computations");
1637 typedef SeqGS<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1638 return createMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1641 else if(preconditioning_ == jacobi)
1643 if( numIterations_ == 1 )
1645 typedef FemDiagonalPreconditioner< ThisType, RowBlockVectorType, ColumnBlockVectorType > PreconditionerType;
1646 typedef typename MatrixAdapterType :: PreconditionAdapterType PreConType;
1647 PreConType preconAdapter( matrix(),
new PreconditionerType( *
this ) );
1648 return MatrixAdapterType( matrix(), domainSpace(), rangeSpace(), preconAdapter );
1650 else if ( procs == 1 )
1652 typedef SeqJac<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1653 return createMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1657 DUNE_THROW(InvalidStateException,
"ISTL::SeqJac(Jacobi) only working with istl.preconditioning.iterations: 1 in parallel computations");
1661 else if(preconditioning_ == amg_ilu_0)
1664 typedef SeqILU0<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1665 return createAMGMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1668 else if(preconditioning_ == amg_ilu_n)
1670 typedef SeqILUn<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType> PreconditionerType;
1671 return createAMGMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1674 else if(preconditioning_ == amg_jacobi)
1676 typedef SeqJac<ISTLMatrixType,RowBlockVectorType,ColumnBlockVectorType,1> PreconditionerType;
1677 return createAMGMatrixAdapter( (PreconditionerType*)
nullptr, numIterations_ );
1681 preConErrorMsg(preconditioning_);
1685 return MatrixAdapterType(matrix(), domainSpace(), rangeSpace(), PreConType() );
1689 bool implicitModeActive()
const 1694 if( matrix().buildMode() == MatrixType::implicit && matrix().buildStage() == MatrixType::building )
1703 if( implicitModeActive() )
1704 matrix().compress();
1709 bool hasPreconditionMatrix()
const 1711 return (preconditioning_ != none);
1715 const PreconditionMatrixType& preconditionMatrix()
const 1729 template <
class Stencil>
1730 void reserve(
const Stencil &stencil,
const bool implicit =
true )
1733 if(sequence_ != domainSpace().sequence())
1739 auto nnz = stencil.maxNonZerosEstimate();
1742 Stencil tmpStencil( stencil );
1743 tmpStencil.fill( *(domainSpace_.begin()), *(rangeSpace_.begin()) );
1744 nnz = tmpStencil.maxNonZerosEstimate();
1746 matrix_ =
new MatrixType( rowMapper_.size(), colMapper_.size(), nnz, overflowFraction_ );
1750 matrix_ =
new MatrixType( rowMapper_.size(), colMapper_.size() );
1751 matrix().createEntries( stencil.globalStencil() );
1754 sequence_ = domainSpace().sequence();
1759 template <
class HangingNodesType>
1760 void changeHangingNodes(
const HangingNodesType& hangingNodes)
1763 MatrixType* newMatrix =
new MatrixType(rowMapper_.size(), colMapper_.size());
1766 newMatrix->setup( *matrix_ , hangingNodes );
1772 matrix_ = newMatrix;
1777 void extractDiagonal( ColumnDiscreteFunctionType& diag )
const 1780 matrix().extractDiagonal( diag.blockVector() );
1784 bool rightPrecondition()
const 1792 void precondition(
const double* arg,
double* dest)
const 1794 createBlockVectors();
1799 RowBlockVectorType& Arg = *Arg_;
1800 ColumnBlockVectorType & Dest = *Dest_;
1802 std::copy_n( arg, Arg.size(), Arg.dbegin());
1807 assert( matrixAdap_ );
1809 matrixAdap_->preconditionAdapter().apply(Dest , Arg);
1811 std::copy( Dest.dbegin(), Dest.dend(), dest );
1815 void multOEM(
const double* arg,
double* dest)
const 1817 createBlockVectors();
1822 RowBlockVectorType& Arg = *Arg_;
1823 ColumnBlockVectorType & Dest = *Dest_;
1825 std::copy_n( arg, Arg.size(), Arg.dbegin() );
1828 assert( matrixAdap_ );
1829 matrixAdap_->apply( Arg, Dest );
1831 std::copy( Dest.dbegin(), Dest.dend(), dest );
1835 void apply(
const RowDiscreteFunctionType& arg, ColumnDiscreteFunctionType& dest)
const 1837 createMatrixAdapter();
1838 assert( matrixAdap_ );
1839 matrixAdap_->apply( arg.blockVector(), dest.blockVector() );
1843 template <
class RowDFType,
class ColDFType>
1844 void apply(
const RowDFType& arg, ColDFType& dest)
const 1846 multOEM( arg.leakPointer(), dest.leakPointer ());
1850 double ddotOEM(
const double* v,
const double* w)
const 1852 createBlockVectors();
1857 RowBlockVectorType& V = *Arg_;
1858 ColumnBlockVectorType& W = *Dest_;
1860 std::copy_n( v, V.size(), V.dbegin() );
1861 std::copy_n( w, W.size(), W.dbegin() );
1865 ISTLBlockVectorDiscreteFunction< DomainSpaceType > vF(
"ddotOEM:vF", domainSpace(), V );
1866 ISTLBlockVectorDiscreteFunction< RangeSpaceType > wF(
"ddotOEM:wF", rangeSpace(), W );
1867 return vF.scalarProductDofs( wF );
1878 void createPreconditionMatrix()
1882 void print(std::ostream & s)
const 1887 const DomainSpaceType& domainSpace()
const {
return domainSpace_; }
1888 const RangeSpaceType& rangeSpace()
const {
return rangeSpace_; }
1890 const RowMapperType& rowMapper()
const {
return rowMapper_; }
1891 const ColMapperType& colMapper()
const {
return colMapper_; }
1894 ObjectType* newObject()
const 1896 return new ObjectType(*
this, domainSpace(), rangeSpace());
1900 LocalMatrixType localMatrix(
const DomainEntityType& domainEntity,
const RangeEntityType &rangeEntity )
const 1902 return LocalMatrixType( localMatrixStack_, domainEntity, rangeEntity );
1904 LocalColumnObjectType localColumn(
const DomainEntityType &domainEntity )
const 1906 return LocalColumnObjectType ( *
this, domainEntity );
1909 template<
class LocalMatrix >
1910 void addLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat )
1912 typedef typename MatrixType::size_type Index;
1913 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1915 if( implicitModeActive() )
1916 return matrix().entry( index.first, index.second );
1918 return matrix()[ index.first ][ index.second ];
1921 auto functor = [ &localMat,
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1923 LittleBlockType& block = blockAccess( index );
1924 for( std::size_t i = 0; i < littleRows; ++i )
1925 for( std::size_t j = 0; j < littleCols; ++j )
1926 block[ i ][ j ] += localMat.get( local.first * littleRows + i, local.second *littleCols + j );
1929 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1933 template<
class LocalMatrix >
1934 void setLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat )
1936 typedef typename MatrixType::size_type Index;
1937 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1939 if( implicitModeActive() )
1940 return matrix().entry( index.first, index.second );
1942 return matrix()[ index.first ][ index.second ];
1945 auto functor = [ &localMat,
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1947 LittleBlockType& block = blockAccess( index );
1948 for( std::size_t i = 0; i < littleRows; ++i )
1949 for( std::size_t j = 0; j < littleCols; ++j )
1950 block[ i ][ j ] = localMat.get( local.first * littleRows + i, local.second *littleCols + j );
1953 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1956 template<
class LocalMatrix,
class Scalar >
1957 void addScaledLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat,
const Scalar &s )
1959 typedef typename MatrixType::size_type Index;
1960 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1962 if( implicitModeActive() )
1963 return matrix().entry( index.first, index.second );
1965 return matrix()[ index.first ][ index.second ];
1968 auto functor = [ &localMat, &s,
this, blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1970 LittleBlockType& block = blockAccess( index );
1971 for( std::size_t i = 0; i < littleRows; ++i )
1972 for( std::size_t j = 0; j < littleCols; ++j )
1973 block[ i ][ j ] += s * localMat.get( local.first * littleRows + i, local.second *littleCols + j );
1976 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1979 template<
class LocalMatrix >
1980 void getLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity, LocalMatrix &localMat )
const 1982 typedef typename MatrixType::size_type Index;
1983 auto functor = [ &localMat, this ] ( std::pair< int, int > local,
const std::pair< Index, Index > &global )
1985 for( std::size_t i = 0; i < littleRows; ++i )
1986 for( std::size_t j = 0; j < littleCols; ++j )
1987 localMat.set( local.first * littleRows + i, local.second *littleCols + j,
1988 matrix()[ global.first ][ global.second ][i][j] );
1991 rowMapper_.mapEach( rangeEntity,
makePairFunctor( colMapper_, domainEntity, functor ) );
1995 void preConErrorMsg(
int preCon)
const 1997 std::cerr <<
"ERROR: Wrong precoditioning number (p = " << preCon;
1998 std::cerr <<
") in ISTLMatrixObject! \n";
1999 std::cerr <<
"Valid values are: \n";
2000 std::cerr <<
"0 == no \n";
2001 std::cerr <<
"1 == SSOR \n";
2002 std::cerr <<
"2 == SOR \n";
2003 std::cerr <<
"3 == ILU-0 \n";
2004 std::cerr <<
"4 == ILU-n \n";
2005 std::cerr <<
"5 == Gauss-Seidel \n";
2006 std::cerr <<
"6 == Jacobi \n";
2011 void removeObj(
const bool alsoClearMatrix )
2018 matrixAdap_ =
nullptr;
2020 if( alsoClearMatrix )
2027 void createBlockVectors()
const 2029 if( Arg_ ==
nullptr || Dest_ ==
nullptr )
2033 Arg_ =
new RowBlockVectorType( rowMapper_.size() );
2034 Dest_ =
new ColumnBlockVectorType( colMapper_.size() );
2037 createMatrixAdapter ();
2040 void createMatrixAdapter ()
const 2042 if( matrixAdap_ ==
nullptr )
2043 matrixAdap_ =
new MatrixAdapterType(matrixAdapterObject());
2052 #endif // #if HAVE_DUNE_ISTL 2054 #endif // #ifndef DUNE_FEM_ISTLMATRIXWRAPPER_HH
Definition: coordinate.hh:4
static int getEnum(const std::string &key, const std::string(&values)[n])
Definition: io/parameter.hh:388
PairFunctor< Mapper, Entity, Functor > makePairFunctor(const Mapper &mapper, const Entity &entity, Functor functor)
Definition: operator/matrix/functor.hh:65
static T getValue(const std::string &key)
get a mandatory parameter from the container
Definition: io/parameter.hh:332