1#ifndef DUNE_FEM_ISTLMATRIXWRAPPER_HH
2#define DUNE_FEM_ISTLMATRIXWRAPPER_HH
25#include <dune/fem/function/blockvectorfunction.hh>
26#include <dune/fem/operator/common/localmatrix.hh>
27#include <dune/fem/operator/common/localmatrixwrapper.hh>
28#include <dune/fem/operator/common/operator.hh>
29#include <dune/fem/operator/common/stencil.hh>
30#include <dune/fem/function/common/scalarproducts.hh>
31#include <dune/fem/io/parameter.hh>
32#include <dune/fem/operator/matrix/columnobject.hh>
33#include <dune/fem/storage/objectstack.hh>
35#include <dune/fem/operator/matrix/istlmatrixadapter.hh>
36#include <dune/fem/operator/matrix/istlpreconditioner.hh>
37#include <dune/fem/operator/matrix/functor.hh>
47 template<
class MatrixObject >
48 class ISTLLocalMatrix;
50 template <
class DomainSpaceImp,
class RangeSpaceImp,
53 class ISTLMatrixObject;
58 template <
class LittleBlockType,
class RowDiscreteFunctionImp,
class ColDiscreteFunctionImp = RowDiscreteFunctionImp>
59 class ImprovedBCRSMatrix :
public BCRSMatrix<LittleBlockType>
61 friend struct MatrixDimension<ImprovedBCRSMatrix>;
63 typedef RowDiscreteFunctionImp RowDiscreteFunctionType;
64 typedef ColDiscreteFunctionImp ColDiscreteFunctionType;
66 typedef BCRSMatrix<LittleBlockType> BaseType;
68 typedef BaseType MatrixBaseType;
69 typedef typename BaseType :: RowIterator RowIteratorType ;
70 typedef typename BaseType :: ColIterator ColIteratorType ;
72 typedef ImprovedBCRSMatrix< LittleBlockType, RowDiscreteFunctionImp, ColDiscreteFunctionImp > ThisType;
74 typedef typename BaseType :: size_type size_type;
79 typedef typename BaseType::field_type field_type;
82 typedef typename BaseType::block_type block_type;
85 typedef typename BaseType:: allocator_type allocator_type;
88 typedef typename BaseType :: row_type row_type;
91 typedef typename BaseType :: ColIterator ColIterator;
94 typedef typename BaseType :: ConstColIterator ConstColIterator;
97 typedef typename BaseType :: RowIterator RowIterator;
100 typedef typename BaseType :: ConstRowIterator ConstRowIterator;
103 typedef typename ColDiscreteFunctionType :: DiscreteFunctionSpaceType RangeSpaceType;
106 typedef typename RowDiscreteFunctionType :: DofStorageType RowBlockVectorType;
109 typedef typename ColDiscreteFunctionType :: DofStorageType ColBlockVectorType;
112 typedef typename RangeSpaceType :: GridType :: Traits :: Communication CommunicationType ;
114 typedef typename BaseType :: BuildMode BuildMode ;
118 ImprovedBCRSMatrix(size_type rows, size_type cols, size_type nnz,
double overflowFraction) :
119 BaseType (rows, cols, nnz, overflowFraction, BaseType::implicit)
123 ImprovedBCRSMatrix(size_type rows, size_type cols, size_type nz = 0 ) :
124 BaseType (rows, cols, BaseType :: row_wise)
128 ImprovedBCRSMatrix( ) :
133 ImprovedBCRSMatrix(
const ImprovedBCRSMatrix& org) :
137 ConstRowIterator slicedBegin(
const size_type row )
const
139 return ConstRowIterator( this->r, row );
142 ConstRowIterator slicedEnd(
const size_type row )
const
144 return ConstRowIterator( this->r, row );
147 std::pair< size_type, size_type > sliceBeginEnd(
const size_type thread,
const size_type numThreads )
const
149 const size_type sliceSize = this->N() / numThreads ;
150 const size_type sliceBegin = thread * sliceSize ;
151 const size_type sliceEnd = ( thread == numThreads-1 ) ? this->N() : (sliceBegin + sliceSize) ;
152 return std::make_pair( sliceBegin, sliceEnd );
156 template <
class X,
class Y,
bool isMV>
157 void mvThreadedImpl( [[maybe_unused]]
const field_type& alpha,
158 const X& x, Y& y, std::integral_constant<bool, isMV> )
const
160 auto doMV = [
this, &alpha, &x, &y] ()
164 if constexpr ( isMV )
166 [[maybe_unused]] field_type a = alpha;
169 const auto slice = sliceBeginEnd( MPIManager::thread(), MPIManager::numThreads() );
170 const ConstRowIterator endi = slicedEnd( slice.second );
171 for (ConstRowIterator i = slicedBegin(slice.first); i!=endi; ++i)
173 if constexpr ( isMV )
176 ConstColIterator endj = (*i).end();
177 for (ConstColIterator j=(*i).begin(); j!=endj; ++j)
179 auto&& xj = Dune::Impl::asVector(x[j.index()]);
180 auto&& yi = Dune::Impl::asVector(y[i.index()]);
181 if constexpr ( isMV )
182 Dune::Impl::asMatrix(*j).umv(xj, yi);
184 Dune::Impl::asMatrix(*j).usmv(alpha, xj, yi);
191 MPIManager :: run ( doMV );
193 catch (
const SingleThreadModeError& e )
196 if constexpr ( isMV )
200 DUNE_THROW(SingleThreadModeError,
"ImprovedBCRSMatrix::usmvThreaded: Cannot recover from threading error. Disable threading!");
207 template <
class X,
class Y>
208 void usmvThreaded(
const field_type& alpha,
const X& x, Y& y )
const
210 mvThreadedImpl(alpha, x, y, std::false_type() );
213 template <
class X,
class Y>
214 void mvThreaded(
const X& x, Y& y )
const
216 mvThreadedImpl(1.0, x, y, std::true_type() );
219 template <
class SparsityPattern >
220 void createEntries(
const SparsityPattern& sparsityPattern)
222 const auto spEnd = sparsityPattern.end();
225 auto endcreate = this->createend();
226 for(
auto create = this->createbegin(); create != endcreate; ++create)
228 const auto row = sparsityPattern.find( create.index() );
230 if( row == spEnd )
continue;
233 for (
const auto& col : row->second )
234 create.insert( col );
241 for (
auto& row : *
this)
242 for (
auto& entry : row)
247 void unitRow(
const size_t row )
249 block_type idBlock( 0 );
250 for (
int i = 0; i < idBlock.rows; ++i)
253 auto& matRow = (*this)[ row ];
254 auto colIt = matRow.begin();
255 const auto& colEndIt = matRow.end();
256 for (; colIt != colEndIt; ++colIt)
258 if( colIt.index() == row )
266 template <
class HangingNodesType>
267 void setup(ThisType& oldMatrix,
const HangingNodesType& hangingNodes)
270 typedef std::set< std::pair<int, block_type> > LocalEntryType;
271 typedef std::map< int , LocalEntryType > EntriesType;
275 std::map< int , std::set<int> > indices;
277 auto rowend = oldMatrix.end();
278 for(
auto it = oldMatrix.begin(); it != rowend; ++it)
280 const auto row = it.index();
281 auto& localIndices = indices[ row ];
283 if( hangingNodes.isHangingNode( row ) )
286 const auto& cols = hangingNodes.associatedDofs( row );
287 const auto colSize = cols.size();
288 for(
auto i=0; i<colSize; ++i)
290 assert( ! hangingNodes.isHangingNode( cols[i].first ) );
293 auto& localColIndices = indices[ cols[i].first ];
294 auto& localEntry = entries[ cols[i].first ];
297 auto endj = (*it).end();
298 for (
auto j= (*it).begin(); j!=endj; ++j)
300 localColIndices.insert( j.index () );
301 localEntry.insert( std::make_pair( j.index(), (cols[i].second * (*j)) ));
306 localIndices.insert( row );
307 for(
auto i=0; i<colSize; ++i)
308 localIndices.insert( cols[i].first );
313 auto endj = (*it).end();
314 for (
auto j= (*it).begin(); j!=endj; ++j)
315 localIndices.insert( j.index () );
320 createEntries( indices );
323 auto rowit = oldMatrix.begin();
325 auto endcreate = this->end();
326 for(
auto create = this->begin(); create != endcreate; ++create, ++rowit )
328 assert( rowit != oldMatrix.end() );
330 const auto row = create.index();
331 if( hangingNodes.isHangingNode( row ) )
333 const auto& cols = hangingNodes.associatedDofs( row );
335 std::map< const int , block_type > colMap;
337 assert( block_type :: rows == 1 );
339 const auto colSize = cols.size();
340 for(
auto i=0; i<colSize; ++i)
341 colMap[ cols[i].first ] = -cols[i].second;
345 auto endj = (*create).end();
346 for (
auto j= (*create).begin(); j!=endj; ++j)
348 assert( colMap.find( j.index() ) != colMap.end() );
349 (*j) = colMap[ j.index() ];
353 else if ( entries.find( row ) == entries.end() )
355 auto colit = (*rowit).begin();
356 auto endj = (*create).end();
357 for (
auto j= (*create).begin(); j!=endj; ++j, ++colit )
359 assert( colit != (*rowit).end() );
365 std::map< int , block_type > oldCols;
368 auto colend = (*rowit).end();
369 for(
auto colit = (*rowit).begin(); colit != colend; ++colit)
370 oldCols[ colit.index() ] = 0;
373 auto entry = entries.find( row );
374 assert( entry != entries.end ());
377 auto endcol = (*entry).second.end();
378 for(
auto co = (*entry).second.begin(); co != endcol; ++co)
379 oldCols[ (*co).first ] = 0;
383 auto colend = (*rowit).end();
384 for(
auto colit = (*rowit).begin(); colit != colend; ++colit)
385 oldCols[ colit.index() ] += (*colit);
389 auto endcol = (*entry).second.end();
390 for(
auto co = (*entry).second.begin(); co != endcol; ++co)
391 oldCols[ (*co).first ] += (*co).second;
394 auto endj = (*create).end();
395 for (
auto j= (*create).begin(); j!=endj; ++j )
397 auto colEntry = oldCols.find( j.index() );
398 if( colEntry != oldCols.end() )
399 (*j) = (*colEntry).second;
408 void extractDiagonal( ColBlockVectorType& diag )
const
410 const auto endi = this->end();
411 for (
auto i = this->begin(); i!=endi; ++i)
414 const auto row = i.index();
415 auto entry = (*i).find( row );
416 const LittleBlockType& block = (*entry);
417 enum { blockSize = LittleBlockType :: rows };
418 for(
auto l=0; l<blockSize; ++l )
419 diag[ row ][ l ] = block[ l ][ l ];
425 field_type operator()(
const std::size_t row,
const std::size_t col)
const
427 const std::size_t blockRow(row/(LittleBlockType :: rows));
428 const std::size_t localRowIdx(row%(LittleBlockType :: rows));
429 const std::size_t blockCol(col/(LittleBlockType :: cols));
430 const std::size_t localColIdx(col%(LittleBlockType :: cols));
432 const auto& matrixRow(this->
operator[](blockRow));
433 auto entry = matrixRow.find( blockCol );
434 const LittleBlockType& block = (*entry);
435 return block[localRowIdx][localColIdx];
440 void set(
const std::size_t row,
const std::size_t col, field_type value)
442 const std::size_t blockRow(row/(LittleBlockType :: rows));
443 const std::size_t localRowIdx(row%(LittleBlockType :: rows));
444 const std::size_t blockCol(col/(LittleBlockType :: cols));
445 const std::size_t localColIdx(col%(LittleBlockType :: cols));
447 auto& matrixRow(this->
operator[](blockRow));
448 auto entry = matrixRow.find( blockCol );
449 LittleBlockType& block = (*entry);
450 block[localRowIdx][localColIdx] = value;
454 void print(std::ostream& s=std::cout,
unsigned int offset=0)
const
457 const auto endi=this->end();
458 for (
auto i=this->begin(); i!=endi; ++i)
460 const auto endj = (*i).end();
461 for (
auto j=(*i).begin(); j!=endj; ++j)
462 if( (*j).infinity_norm() > 1.e-15)
463 s << i.index()+offset <<
" " << j.index()+offset <<
" " << *j << std::endl;
473 template<
class MatrixObject >
474 struct ISTLLocalMatrixTraits
476 typedef typename MatrixObject::DomainSpaceType DomainSpaceType;
477 typedef typename MatrixObject::RangeSpaceType RangeSpaceType;
478 typedef typename DomainSpaceType::RangeFieldType RangeFieldType;
480 typedef ISTLLocalMatrix< MatrixObject > LocalMatrixType;
481 typedef typename MatrixObject::MatrixType::block_type LittleBlockType;
488 template<
class MatrixObject >
489 class ISTLLocalMatrix
490 :
public LocalMatrixDefault< ISTLLocalMatrixTraits< MatrixObject > >
494 typedef LocalMatrixDefault< ISTLLocalMatrixTraits< MatrixObject > > BaseType;
497 typedef MatrixObject MatrixObjectType;
499 typedef typename MatrixObjectType::MatrixType MatrixType;
501 typedef typename MatrixType::block_type LittleBlockType;
503 typedef typename MatrixType :: size_type size_type;
505 typedef typename MatrixObjectType::DomainSpaceType DomainSpaceType;
506 typedef typename MatrixObjectType::RangeSpaceType RangeSpaceType;
508 typedef typename MatrixObjectType::DomainEntityType DomainEntityType;
509 typedef typename MatrixObjectType::RangeEntityType RangeEntityType;
512 typedef typename DomainSpaceType::RangeFieldType DofType;
513 typedef typename MatrixType::row_type RowType;
516 typedef typename DomainSpaceType::BlockMapperType ColMapperType;
518 typedef typename RangeSpaceType::BlockMapperType RowMapperType;
520 static const int littleCols = MatrixObjectType::littleCols;
521 static const int littleRows = MatrixObjectType::littleRows;
523 typedef typename MatrixType::size_type Index;
528 [[deprecated(
"Use TemporaryLocalMatrix,LocalContribution and {get,add,set}LocalMatrix")]]
529 ISTLLocalMatrix (
const MatrixObjectType& mObj,
const DomainSpaceType& domainSpace,
const RangeSpaceType& rangeSpace )
530 : BaseType( domainSpace, rangeSpace ),
531 rowMapper_( rangeSpace.blockMapper() ),
532 colMapper_( domainSpace.blockMapper() ),
533 numRows_( rowMapper_.maxNumDofs() ),
534 numCols_( colMapper_.maxNumDofs() ),
541 [[deprecated(
"Use TemporaryLocalMatrix,LocalContribution and {get,add,set}LocalMatrix")]]
542 ISTLLocalMatrix (
const ISTLLocalMatrix& org )
544 rowMapper_(org.rowMapper_),
545 colMapper_(org.colMapper_),
546 numRows_( org.numRows_ ),
547 numCols_( org.numCols_ ),
548 matrices_(org.matrices_),
549 matrixObj_(org.matrixObj_)
553 void init (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity )
556 BaseType :: init ( domainEntity, rangeEntity );
558 numRows_ = rowMapper_.numDofs( rangeEntity );
559 numCols_ = colMapper_.numDofs( domainEntity );
562 matrices_.resize( numRows_ );
563 for(
auto& row : matrices_ )
565 row.resize( numCols_,
nullptr );
568 if( matrixObj_.implicitModeActive() )
570 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
572 return matrixObj_.matrix().entry( index.first, index.second );
574 initBlocks( blockAccess, domainEntity, rangeEntity );
578 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
580 return matrixObj_.matrix()[ index.first ][ index.second ];
582 initBlocks( blockAccess, domainEntity, rangeEntity );
586 template <
class BlockAccess>
587 void initBlocks( BlockAccess& blockAccess,
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity )
589 auto functor = [
this, &blockAccess ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
591 matrices_[ local.first ][ local.second ] = &blockAccess( index );
594 rowMapper_.mapEach( rangeEntity, makePairFunctor( colMapper_, domainEntity, functor ) );
599 void check(
int localRow,
int localCol)
const
602 const std::size_t row = (int) localRow / littleRows;
603 const std::size_t col = (int) localCol / littleCols;
604 const int lRow = localRow%littleRows;
605 const int lCol = localCol%littleCols;
606 assert( row < matrices_.size() ) ;
607 assert( col < matrices_[row].
size() );
608 assert( lRow < littleRows );
609 assert( lCol < littleCols );
613 DofType& getValue(
const int localRow,
const int localCol)
615 const int row = (int) localRow / littleRows;
616 const int col = (int) localCol / littleCols;
617 const int lRow = localRow%littleRows;
618 const int lCol = localCol%littleCols;
619 return (*matrices_[row][col])[lRow][lCol];
623 const DofType
get(
const int localRow,
const int localCol)
const
625 const int row = (int) localRow / littleRows;
626 const int col = (int) localCol / littleCols;
627 const int lRow = localRow%littleRows;
628 const int lCol = localCol%littleCols;
629 return (*matrices_[row][col])[lRow][lCol];
632 void scale (
const DofType& scalar)
634 const size_type nrows = matrices_.size();
635 for(size_type i=0; i<nrows; ++i)
637 const size_type ncols = matrices_[i].size();
638 for(size_type j=0; j<ncols; ++j)
640 (*matrices_[i][j]) *= scalar;
645 void add(
const int localRow,
const int localCol ,
const DofType value)
648 check(localRow,localCol);
650 getValue(localRow,localCol) += value;
653 void set(
const int localRow,
const int localCol ,
const DofType value)
656 check(localRow,localCol);
658 getValue(localRow,localCol) = value;
662 void unitRow(
const int localRow)
664 const int row = (int) localRow / littleRows;
665 const int lRow = localRow%littleRows;
668 doClearRow( row, lRow );
671 (*matrices_[row][row])[lRow][lRow] = 1;
677 const size_type nrows = matrices_.size();
678 for(size_type i=0; i<nrows; ++i)
680 const size_type ncols = matrices_[i].size();
681 for(size_type j=0; j<ncols; ++j)
683 (*matrices_[i][j]) = (DofType) 0;
689 void clearRow (
const int localRow )
691 const int row = (int) localRow / littleRows;
692 const int lRow = localRow%littleRows;
695 doClearRow( row, lRow );
704 void doClearRow (
const int row,
const int lRow )
707 const auto col = this->columns();
708 for(
auto localCol=0; localCol<col; ++localCol)
710 const int col = (int) localCol / littleCols;
711 const int lCol = localCol%littleCols;
712 (*matrices_[row][col])[lRow][lCol] = 0;
718 const RowMapperType& rowMapper_;
719 const ColMapperType& colMapper_;
726 std::vector< std::vector< LittleBlockType* > > matrices_;
729 const MatrixObjectType& matrixObj_;
734 template <
class DomainSpaceImp,
class RangeSpaceImp,
class DomainBlock,
class RangeBlock >
735 class ISTLMatrixObject
739 typedef DomainSpaceImp DomainSpaceType;
741 typedef RangeSpaceImp RangeSpaceType;
744 typedef ISTLMatrixObject< DomainSpaceImp, RangeSpaceImp, DomainBlock, RangeBlock > ThisType;
745 typedef ThisType PreconditionMatrixType;
747 typedef typename DomainSpaceType::GridType GridType;
749 typedef typename RangeSpaceType :: EntityType RangeEntityType ;
750 typedef typename DomainSpaceType :: EntityType DomainEntityType ;
752 enum { littleCols = DomainSpaceType :: localBlockSize };
753 enum { littleRows = RangeSpaceType :: localBlockSize };
755 typedef FieldMatrix<typename DomainSpaceType :: RangeFieldType, littleRows, littleCols> LittleBlockType;
756 typedef LittleBlockType block_type;
757 typedef LittleBlockType MatrixBlockType;
759 typedef ISTLBlockVectorDiscreteFunction< RangeSpaceType, RangeBlock > RowDiscreteFunctionType;
760 typedef ISTLBlockVectorDiscreteFunction< DomainSpaceType, DomainBlock > ColumnDiscreteFunctionType;
762 typedef typename RowDiscreteFunctionType :: DofStorageType RowBlockVectorType;
763 typedef typename ColumnDiscreteFunctionType :: DofStorageType ColumnBlockVectorType;
765 typedef typename RangeSpaceType :: BlockMapperType RowMapperType;
766 typedef typename DomainSpaceType :: BlockMapperType ColMapperType;
769 typedef ImprovedBCRSMatrix< LittleBlockType , ColumnDiscreteFunctionType , RowDiscreteFunctionType > MatrixType;
770 typedef ISTLParallelMatrixAdapterInterface< MatrixType > MatrixAdapterType;
773 typedef ISTLLocalMatrix<ThisType> ObjectType;
774 friend class ISTLLocalMatrix<ThisType>;
776 typedef ThisType LocalMatrixFactoryType;
779 typedef LocalMatrixWrapper< LocalMatrixStackType > LocalMatrixType;
780 typedef ColumnObject< ThisType > LocalColumnObjectType;
783 const DomainSpaceType& domainSpace_;
784 const RangeSpaceType& rangeSpace_;
787 RowMapperType& rowMapper_;
789 ColMapperType& colMapper_;
794 mutable std::unique_ptr< MatrixType > matrix_;
796 mutable LocalMatrixStackType localMatrixStack_;
798 mutable std::unique_ptr< MatrixAdapterType > matrixAdap_;
800 const double overflowFraction_;
801 const bool threading_ ;
803 ISTLSolverParameter param_;
805 ISTLMatrixObject(
const ISTLMatrixObject&) =
delete;
810 ISTLMatrixObject (
const DomainSpaceType &domainSpace,
const RangeSpaceType &rangeSpace,
const ISTLSolverParameter& param = ISTLSolverParameter() ) :
811 domainSpace_(domainSpace)
812 , rangeSpace_(rangeSpace)
813 , rowMapper_( rangeSpace.blockMapper() )
814 , colMapper_( domainSpace.blockMapper() )
817 , localMatrixStack_( *this )
818 , overflowFraction_( param.overflowFraction() )
819 , threading_( param.threading() )
826 MatrixType& matrix()
const
833 bool threading()
const {
return threading_; }
835 void printTexInfo(std::ostream& out)
const
837 out <<
"ISTL MatrixObj: ";
842 std::string preconditionName()
const
847 void createMatrixAdapter (
const ISTLSolverParameter& param )
const
851 matrixAdap_ = ISTLMatrixAdapterFactory< ThisType > :: matrixAdapter( *
this, param );
853 assert( matrixAdap_ );
857 MatrixAdapterType& matrixAdapter(
const ISTLSolverParameter& parameter )
const
859 const ISTLSolverParameter* param =
dynamic_cast< const ISTLSolverParameter*
> (¶meter);
861 createMatrixAdapter( *param );
864 ISTLSolverParameter newparam( parameter );
865 createMatrixAdapter( newparam );
873 MatrixAdapterType& matrixAdapter()
const
875 return matrixAdapter( param_ );
879 MatrixType& exportMatrix()
const
885 bool implicitModeActive()
const
891 if( matrix().buildMode() == MatrixType::implicit && matrix().buildStage() == MatrixType::building )
897 void finalizeAssembly()
const
900 const_cast< ThisType&
> (*this).compress();
906 if( implicitModeActive() )
920 void unitRow(
const size_t row )
922 matrix().unitRow( row );
926 template <
class Container>
927 void setUnitRowImpl(
const Container &rows,
const double diagonal )
929 for (
const auto& r : rows)
931 const std::size_t blockRow( r/(LittleBlockType :: rows) );
932 const std::size_t localRowIdx( r%(LittleBlockType :: rows) );
933 auto& row = matrix()[blockRow];
934 const auto endcol = row.end();
938 for (
auto col=row.begin(); col!=endcol; ++col)
940 for (
auto& entry : (*col)[localRowIdx])
942 if (col.index() == blockRow)
944 (*col)[localRowIdx][localRowIdx] = diagonal;
955 template <
class Container>
956 void setUnitRows(
const Container& unitRows,
const Container& auxRows )
958 setUnitRowImpl( unitRows, 1.0 );
959 setUnitRowImpl( auxRows, 0.0 );
965 reserve( Stencil<DomainSpaceType,RangeSpaceType>(domainSpace_, rangeSpace_),
true );
970 void reserve (
const std::vector< Set >& sparsityPattern )
972 reserve( StencilWrapper< DomainSpaceType,RangeSpaceType, Set >( sparsityPattern ),
false );
976 template <
class Stencil>
977 void reserve(
const Stencil &stencil,
const bool proposeImplicit =
true )
980 if(sequence_ != domainSpace().sequence())
985 const bool implicit = proposeImplicit && MPIManager::numThreads() == 1;
988 auto nnz = stencil.maxNonZerosEstimate();
991 if (domainSpace_.begin() != domainSpace_.end() && rangeSpace_.begin() != rangeSpace_.end())
993 Stencil tmpStencil( stencil );
994 tmpStencil.fill( *(domainSpace_.begin()), *(rangeSpace_.begin()) );
995 nnz = tmpStencil.maxNonZerosEstimate();
998 matrix_.reset(
new MatrixType( rowMapper_.size(), colMapper_.size(), nnz, overflowFraction_ ) );
1002 matrix_.reset(
new MatrixType( rowMapper_.size(), colMapper_.size() ) );
1003 matrix().createEntries( stencil.globalStencil() );
1006 sequence_ = domainSpace().sequence();
1011 template <
class HangingNodesType>
1012 void changeHangingNodes(
const HangingNodesType& hangingNodes)
1015 MatrixType* newMatrix =
new MatrixType(rowMapper_.size(), colMapper_.size());
1018 newMatrix->setup( *matrix_ , hangingNodes );
1024 matrix_.reset( newMatrix );
1029 void extractDiagonal( ColumnDiscreteFunctionType& diag )
const
1032 matrix().extractDiagonal( diag.blockVector() );
1036 bool rightPrecondition()
const
1042 void apply(
const ColumnDiscreteFunctionType& arg, RowDiscreteFunctionType& dest)
const
1044 matrixAdapter().apply( arg.blockVector(), dest.blockVector() );
1048 template <
class CDF,
class RDF>
1049 void apply(
const CDF& arg, RDF& dest)
const
1053 DUNE_THROW(NotImplemented,
"ISTLMatrixObj::apply called for DiscreteFunctions not specified in the template list");
1062 void createPreconditionMatrix()
1066 void print(std::ostream & s)
const
1071 const DomainSpaceType& domainSpace()
const
1073 return domainSpace_;
1075 const RangeSpaceType& rangeSpace()
const
1080 const RowMapperType& rowMapper()
const
1084 const ColMapperType& colMapper()
const
1090 ObjectType* newObject()
const
1092 return new ObjectType(*
this, domainSpace(), rangeSpace());
1099 [[deprecated(
"Use TemporaryLocalMatrix,LocalContribution and {get,add,set}LocalMatrix")]]
1100 LocalMatrixType localMatrix(
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity )
const
1102 return LocalMatrixType( localMatrixStack_, domainEntity, rangeEntity );
1109 [[deprecated(
"Use TemporaryLocalMatrix,LocalContribution and {get,add,set}LocalMatrix")]]
1110 LocalMatrixType localMatrix()
const
1112 return LocalMatrixType( localMatrixStack_ );
1115 LocalColumnObjectType localColumn(
const DomainEntityType &domainEntity )
const
1117 return LocalColumnObjectType ( *
this, domainEntity );
1121 template<
class LocalBlock,
class Operation >
1122 void applyToBlock (
const size_t row,
const size_t col,
1123 const LocalBlock &localBlock,
1124 Operation& operation )
1126 LittleBlockType& block = ( implicitModeActive() ) ? matrix().entry( row, col ) : matrix()[ row ][ col ];
1127 for(
int i = 0; i < littleRows; ++i )
1128 for(
int j = 0; j < littleCols; ++j )
1129 operation( block[ i ][ j ], localBlock[ i ][ j ] );
1132 template<
class LocalBlock >
1133 void setBlock (
const size_t row,
const size_t col,
1134 const LocalBlock &localBlock )
1136 typedef typename DomainSpaceType :: RangeFieldType Field;
1137 auto copy = [] ( Field& a,
const typename LocalBlock::field_type& b ) { a = b; };
1138 applyToBlock( row, col, localBlock, copy );
1141 template<
class LocalBlock >
1142 void addBlock (
const size_t row,
const size_t col,
1143 const LocalBlock &localBlock )
1145 typedef typename DomainSpaceType :: RangeFieldType Field;
1146 auto add = [] ( Field& a,
const typename LocalBlock::field_type& b ) { a += b; };
1147 applyToBlock( row, col, localBlock, add );
1151 template<
class LocalMatrix,
class Operation >
1152 void applyToLocalMatrix (
const DomainEntityType &domainEntity,
1153 const RangeEntityType &rangeEntity,
1154 const LocalMatrix &localMat,
1155 Operation& operation )
1157 typedef typename MatrixType::size_type Index;
1158 if( implicitModeActive() )
1160 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1162 return matrix().entry( index.first, index.second );
1164 auto functor = [ &localMat, blockAccess, operation ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1166 LittleBlockType& block = blockAccess( index );
1167 for(
int i = 0; i < littleRows; ++i )
1168 for(
int j = 0; j < littleCols; ++j )
1169 operation( block[ i ][ j ], localMat.get( local.first * littleRows + i, local.second *littleCols + j ) );
1171 rowMapper_.mapEach( rangeEntity, makePairFunctor( colMapper_, domainEntity, functor ) );
1175 auto blockAccess = [ this ] (
const std::pair< Index, Index > &index ) -> LittleBlockType&
1177 return matrix()[ index.first][ index.second ];
1179 auto functor = [ &localMat, blockAccess, operation ] ( std::pair< int, int > local,
const std::pair< Index, Index > &index )
1181 LittleBlockType& block = blockAccess( index );
1182 for(
int i = 0; i < littleRows; ++i )
1183 for(
int j = 0; j < littleCols; ++j )
1184 operation( block[ i ][ j ], localMat.get( local.first * littleRows + i, local.second *littleCols + j ) );
1186 rowMapper_.mapEach( rangeEntity, makePairFunctor( colMapper_, domainEntity, functor ) );
1190 template<
class LocalMatrix >
1191 void setLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat )
1193 typedef typename DomainSpaceType :: RangeFieldType RangeFieldType;
1194 auto operation = [] ( RangeFieldType& a,
const RangeFieldType& b )
1198 applyToLocalMatrix( domainEntity, rangeEntity, localMat, operation );
1201 template<
class LocalMatrix >
1202 void addLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat )
1204 typedef typename DomainSpaceType :: RangeFieldType RangeFieldType;
1205 auto operation = [] ( RangeFieldType& a,
const RangeFieldType& b )
1209 applyToLocalMatrix( domainEntity, rangeEntity, localMat, operation );
1212 template<
class LocalMatrix,
class Scalar >
1213 void addScaledLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity,
const LocalMatrix &localMat,
const Scalar &s )
1215 typedef typename DomainSpaceType :: RangeFieldType RangeFieldType;
1216 auto operation = [ &s ] ( RangeFieldType& a,
const RangeFieldType& b )
1220 applyToLocalMatrix( domainEntity, rangeEntity, localMat, operation );
1223 template<
class LocalMatrix >
1224 void getLocalMatrix (
const DomainEntityType &domainEntity,
const RangeEntityType &rangeEntity, LocalMatrix &localMat )
const
1229 typedef typename MatrixType::size_type Index;
1230 auto functor = [ &localMat, this ] ( std::pair< int, int > local,
const std::pair< Index, Index > &global )
1232 for( std::size_t i = 0; i < littleRows; ++i )
1233 for( std::size_t j = 0; j < littleCols; ++j )
1234 localMat.set( local.first * littleRows + i, local.second *littleCols + j,
1235 matrix()[ global.first ][ global.second ][i][j] );
1238 rowMapper_.mapEach( rangeEntity, makePairFunctor( colMapper_, domainEntity, functor ) );
1242 void preConErrorMsg(
int preCon)
const
1249 matrixAdap_.reset(
nullptr );
Implementation of the BCRSMatrix class.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
vector space out of a tensor product of fields.
Definition: fvector.hh:97
A few common exception classes.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
#define DUNE_THROW(E,...)
Definition: exceptions.hh:314
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: interface.hh:235
Dune namespace
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
Define general preconditioner interface.