1#ifndef DUNE_FEM_PETSCVECTOR_HH
2#define DUNE_FEM_PETSCVECTOR_HH
36 template<
class DFSpace >
55 template <
class DiscreteFunctionSpace,
class Mapper >
56 class PetscManagedDofStorage
57 :
public ManagedDofStorageImplementation< typename DiscreteFunctionSpace::GridPartType::GridType, Mapper, PetscVector< DiscreteFunctionSpace > >
59 typedef typename DiscreteFunctionSpace::GridPartType::GridType GridType;
60 typedef Mapper MapperType ;
61 typedef PetscVector< DiscreteFunctionSpace > DofArrayType ;
62 typedef ManagedDofStorageImplementation< GridType, MapperType, DofArrayType > BaseType;
65 typedef typename BaseType :: SizeType SizeType;
69 const MapperType& mapper )
70 : BaseType(
space.
grid(), mapper, myArray_ ),
75 void resize(
const bool )
override
79 void reserve(
const SizeType )
override
84 void dofCompress(
const bool clearResizedArrays )
override
87 if( clearResizedArrays )
94 void enableDofCompression()
override
99 DofArrayType myArray_;
117 template<
class DFSpace >
120 typedef PetscVector< DFSpace > ThisType;
121 friend class PetscDofBlock< ThisType >;
122 friend class PetscDofBlock< const ThisType >;
123 friend class PetscDofProxy< ThisType >;
124 friend class PetscDofProxy< const ThisType >;
126 typedef PetscScalar value_type ;
127 typedef Vec DofContainerType;
129 static constexpr int blockSize = DFSpace::localBlockSize;
130 typedef Hybrid::IndexRange< int, blockSize > BlockIndices;
132 typedef PetscDofBlock< ThisType > DofBlockType;
133 typedef PetscDofBlock< const ThisType > ConstDofBlockType;
134 typedef typename DofBlockType::DofIterator DofIteratorType;
135 typedef typename ConstDofBlockType::DofIterator ConstDofIteratorType;
136 typedef Envelope< DofBlockType > DofBlockPtrType;
137 typedef Envelope< ConstDofBlockType > ConstDofBlockPtrType;
138 typedef typename DofBlockType::IndexType
IndexType;
140 typedef DofIteratorType IteratorType;
141 typedef ConstDofIteratorType ConstIteratorType;
142 typedef typename DFSpace::RangeFieldType FieldType;
143 typedef int SizeType;
145 typedef PetscMappers< DFSpace > MappersType;
149 typedef DFSpace DiscreteFunctionSpaceType;
153 typedef typename DFSpace::template CommDataHandle< FakeDF >::OperationType DefaultCommunicationOperationType;
156 PetscVector (
const DFSpace& space, Vec vec )
157 : mappers_(
space ), vec_(vec), owner_(false)
159 static_assert( DefaultCommunicationOperationType::value == DFCommunicationOperation::copy ||
160 DefaultCommunicationOperationType::value == DFCommunicationOperation::add,
161 "only copy/add are available communication operations for petsc");
162 ::Dune::Petsc::VecGhostGetLocalForm( vec_, &ghostedVec_ );
164 PetscVector (
const DFSpace& space )
165 : mappers_(
space ), owner_(true)
167 static_assert( DefaultCommunicationOperationType::value == DFCommunicationOperation::copy ||
168 DefaultCommunicationOperationType::value == DFCommunicationOperation::add,
169 "only copy/add are available communication operations for petsc");
175 PetscVector (
const ThisType &other )
176 : mappers_( other.mappers_ ), owner_(true)
211 void hasBeenModified () { ++sequence_; }
215 communicateFlag_ =
true;
221 communicateIfNecessary();
225 const Vec* getVector ()
const
227 communicateIfNecessary();
234 communicateIfNecessary();
238 const Vec& array ()
const
240 communicateIfNecessary();
244 Vec* getGhostedVector ()
246 communicateIfNecessary();
250 const Vec* getGhostedVector ()
const
252 communicateIfNecessary();
258 ::Dune::Petsc::VecAssemblyBegin( vec_ );
261 void endAssemble(
const bool communicate )
263 ::Dune::Petsc::VecAssemblyEnd( vec_ );
265 communicateIfNecessary();
269 template <
class Operation>
270 void communicateNow (
const Operation& operation)
const
272 communicateFlag_ =
true;
274 communicateIfNecessary( operation );
278 ConstDofBlockType
operator[] (
const IndexType
index )
const {
return ConstDofBlockType( *
this,
index ); }
280 ConstDofBlockPtrType block ( IndexType
index )
const {
return blockPtr(
index ); }
281 DofBlockPtrType block ( IndexType
index ) {
return blockPtr(
index ); }
283 DofBlockPtrType blockPtr ( IndexType
index )
286 return DofBlockPtrType(
typename DofBlockType::UnaryConstructorParamType( *
this,
index ) );
289 ConstDofBlockPtrType blockPtr ( IndexType
index )
const
292 return ConstDofBlockPtrType(
typename ConstDofBlockType::UnaryConstructorParamType( *
this,
index ) );
295 DofIteratorType
begin () {
return DofIteratorType( *
this, 0, 0 ); }
296 ConstDofIteratorType
begin ()
const {
return ConstDofIteratorType( *
this, 0, 0 ); }
297 DofIteratorType
end () {
return DofIteratorType( *
this, mappers().
size() ); }
298 ConstDofIteratorType
end ()
const {
return ConstDofIteratorType( *
this, mappers().
size() ); }
302 DUNE_THROW(NotImplemented,
"PetscVector::beforeEnd is not implemented yet");
308 DUNE_THROW(NotImplemented,
"PetscVector::beforeEnd is not implemented yet");
314 DUNE_THROW(NotImplemented,
"PetscVector::beforeBegin is not implemented yet");
319 DUNE_THROW(NotImplemented,
"PetscVector::beforeBegin is not implemented yet");
323 DofIteratorType dbegin () {
return begin(); }
324 ConstDofIteratorType dbegin ()
const {
return begin(); }
325 DofIteratorType dend () {
return end(); }
326 ConstDofIteratorType dend ()
const {
return end(); }
330 ::Dune::Petsc::VecSet( *getVector(), 0. );
331 updateGhostRegions();
332 vectorIsUpToDateNow();
335 PetscScalar
operator* (
const ThisType &other )
const
338 ::Dune::Petsc::VecDot( *getVector(), *other.getVector(), &ret );
342 const ThisType&
operator+= (
const ThisType &other )
344 ::Dune::Petsc::VecAXPY( *getVector(), 1., *other.getVector() );
345 updateGhostRegions();
346 vectorIsUpToDateNow();
350 const ThisType&
operator-= (
const ThisType &other )
352 ::Dune::Petsc::VecAXPY( *getVector(), -1., *other.getVector() );
353 updateGhostRegions();
354 vectorIsUpToDateNow();
358 const ThisType&
operator*= ( PetscScalar scalar )
360 ::Dune::Petsc::VecScale( *getVector(), scalar );
361 updateGhostRegions();
362 vectorIsUpToDateNow();
366 const ThisType&
operator/= ( PetscScalar scalar )
368 assert( scalar != 0 );
372 void axpy (
const PetscScalar &scalar,
const ThisType &other )
374 ::Dune::Petsc::VecAXPY( *getVector(), scalar, *other.getVector() );
382 VecGetArray( ghostedVec_,&array );
383 std::fill_n( array + mappers().ghostMapper().interiorSize() * blockSize, mappers().ghostMapper().
ghostSize() * blockSize, PetscScalar( 0 ) );
385 VecRestoreArray( ghostedVec_, &array );
390 void printGlobal (
bool doit )
394 VecView( vec_, PETSC_VIEWER_STDOUT_WORLD );
397 void printGhost (
bool doit)
403 VecGetArray( ghostedVec_,&array );
406 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"%D %G\n",i,PetscRealPart(array[i]));
408 VecRestoreArray( ghostedVec_, &array );
409#if PETSC_VERSION_MAJOR <= 3 && PETSC_VERSION_MINOR < 5
410 PetscSynchronizedFlush( PETSC_COMM_WORLD );
412 PetscSynchronizedFlush( PETSC_COMM_WORLD, PETSC_STDOUT );
417 void assign(
const ThisType& other )
421 other.communicateIfNecessary();
424 ::Dune::Petsc::VecCopy( other.vec_, vec_ );
427 updateGhostRegions();
431 template <
class Container>
432 void assignVector(
const SimpleBlockVector< Container, blockSize >& other )
434 Vec& vec = *getGhostedVector();
437 const auto& mapping = mappers_.ghostMapper().mapping();
438 const size_t blocks = mapping.size();
439 assert( blocks == other.size() );
440 for(
size_t b=0, bs = 0; b<blocks; ++b, bs += blockSize)
442 PetscInt block = mapping[ b ];
443 const PetscScalar* values =
static_cast< const PetscScalar*
> (other.data()+bs);
444 ::Dune::Petsc::VecSetValuesBlocked( vec, 1, &block, values, INSERT_VALUES );
446 ::Dune::Petsc::VecGhostGetLocalForm( vec_, &ghostedVec_ );
448 updateGhostRegions();
452 template <
class DofBlock>
453 void assignVector(
const ISTLBlockVector< DofBlock >& other )
455 assert( DofBlock :: dimension == blockSize );
456 Vec& vec = *getGhostedVector();
459 const auto& mapping = mappers_.ghostMapper().mapping();
460 const size_t blocks = mapping.size();
461 assert( blocks == other.size() );
462 for(
size_t b=0; b<blocks; ++b )
464 PetscInt block = mapping[ b ];
465 const PetscScalar* values =
static_cast< const PetscScalar*
> (&(other[ b ][ 0 ])) ;
466 ::Dune::Petsc::VecSetValuesBlocked( vec, 1, &block, values, INSERT_VALUES );
468 ::Dune::Petsc::VecGhostGetLocalForm( vec_, &ghostedVec_ );
470 updateGhostRegions();
474 template <
class Container>
475 void copyTo( SimpleBlockVector< Container, blockSize >& other )
const
477 typedef typename Container::FieldType FieldType;
478 const PetscScalar *array =
nullptr;
479 VecGetArrayRead( ghostedVec_, &array );
482 const auto& mapping = mappers_.ghostMapper().mapping();
483 const size_t blocks = mapping.size();
484 assert( blocks == other.size() );
485 for(
size_t b=0; b<blocks; ++b )
487 const PetscScalar* petscBlock = array + (blockSize * mapping[ b ]);
488 FieldType* otherBlock = other.data() + (b * blockSize);
489 for(
int i=0; i<blockSize; ++i )
491 otherBlock[ i ] = petscBlock[ i ];
494 VecRestoreArrayRead( ghostedVec_, &array );
498 template <
class DofBlock>
499 void copyTo ( ISTLBlockVector< DofBlock >& other )
const
501 assert( DofBlock :: dimension == blockSize );
502 const PetscScalar *array =
nullptr;
503 VecGetArrayRead( ghostedVec_, &array );
506 const auto& mapping = mappers_.ghostMapper().mapping();
507 const size_t blocks = mapping.size();
508 assert( blocks == other.size() );
509 for(
size_t b=0; b<blocks; ++b )
511 const PetscScalar* petscBlock = array + (blockSize * mapping[ b ]);
512 DofBlock& otherBlock = other[ b ];
513 for(
int i=0; i<blockSize; ++i )
515 otherBlock[ i ] = petscBlock[ i ];
518 VecRestoreArrayRead( ghostedVec_, &array );
521 PetscVector&
operator= (
const ThisType& other )
527 const MappersType &mappers()
const {
return mappers_; }
531 return size() *
sizeof(value_type);
534 static void setMemoryFactor(
const double memFactor)
540 void memMoveBackward(
const int length,
const int oldStartIdx,
const int newStartIdx)
542 DUNE_THROW(NotImplemented,
"memMoveBackward is to be implemented");
546 void memMoveForward(
const int length,
const int oldStartIdx,
const int newStartIdx)
548 DUNE_THROW(NotImplemented,
"memMoveForward is to be implemented");
551 void copyContent(
const int newIndex,
const int oldIndex )
553 DUNE_THROW(NotImplemented,
"copyContent is to be implemented");
562 const PetscInt localBlocks = mappers_.ghostMapper().interiorSize();
563 const PetscInt numGhostBlocks = mappers_.ghostMapper().ghostSize();
565 const PetscInt localSize = localBlocks * blockSize;
566 const PetscInt globalSize = mappers_.parallelMapper().size() * blockSize;
569 const PetscInt *ghostBlocks = mappers_.parallelMapper().mapping().data() + localBlocks;
570 const auto&
comm = mappers_.space().gridPart().comm();
572 ::Dune::Petsc::VecCreateGhost( comm, localSize, globalSize, numGhostBlocks, ghostBlocks, &vec_ );
574 ::Dune::Petsc::VecCreateGhostBlock( comm, blockSize, localSize, globalSize, numGhostBlocks, ghostBlocks, &vec_ );
575 ::Dune::Petsc::VecGhostGetLocalForm( vec_, &ghostedVec_ );
581 ::Dune::Petsc::VecGhostRestoreLocalForm( vec_, &ghostedVec_ );
582 ::Dune::Petsc::VecDestroy( &vec_ );
586 void communicateIfNecessary ()
const
588 DefaultCommunicationOperationType op;
589 communicateIfNecessary( op );
592 template <
class Operation>
593 void communicateIfNecessary (
const Operation& op)
const
596 if( communicateFlag_ && memorySequence_ < sequence_ )
598 if ( memorySequence_ < sequence_ )
600 if ( Operation::value == DFCommunicationOperation::add )
602 ::Dune::Petsc::VecGhostUpdateBegin( vec_, ADD_VALUES, SCATTER_REVERSE );
603 ::Dune::Petsc::VecGhostUpdateEnd( vec_, ADD_VALUES, SCATTER_REVERSE );
605 ::Dune::Petsc::VecGhostUpdateBegin( vec_, INSERT_VALUES, SCATTER_FORWARD );
606 ::Dune::Petsc::VecGhostUpdateEnd( vec_, INSERT_VALUES, SCATTER_FORWARD );
608 memorySequence_ = sequence_;
611 communicateFlag_ =
false;
616 void updateGhostRegions ()
618 ::Dune::Petsc::VecGhostUpdateBegin( vec_, INSERT_VALUES, SCATTER_FORWARD );
619 ::Dune::Petsc::VecGhostUpdateEnd( vec_, INSERT_VALUES, SCATTER_FORWARD );
622 void vectorIsUpToDateNow ()
const
624 memorySequence_ = sequence_;
625 communicateFlag_ =
false;
631 MappersType mappers_;
635 mutable unsigned long memorySequence_ = 0;
636 mutable unsigned long sequence_ = 0;
638 mutable bool communicateFlag_ =
false;
void axpy(const Ta &a, const type &y)
void init(const Matrix *matrix)
reference operator[](size_type i)
SLList< T, A > & operator=(const SLList< T, A > &other)
bigunsignedint< k > & operator/=(const bigunsignedint< k > &x)
bigunsignedint< k > & operator+=(const bigunsignedint< k > &x)
bigunsignedint< k > & operator-=(const bigunsignedint< k > &x)
bigunsignedint< k > & operator*=(const bigunsignedint< k > &x)
friend friend auto operator*(const DiagonalMatrix &matrixA, const DiagonalMatrix< OtherScalar, n > &matrixB)
std::ptrdiff_t index() const
#define DUNE_THROW(E,...)
void assign(T &dst, const T &src, bool mask)
typename Impl::Index< Range >::Type IndexType
Definition hybrid.hh:69
const Grid & grid() const
const Communication & comm() const
int ghostSize(int codim) const