1#ifndef DUNE_FEM_PETSCVECTOR_HH
2#define DUNE_FEM_PETSCVECTOR_HH
12#include <dune/fem/storage/dynamicarray.hh>
13#include <dune/fem/storage/envelope.hh>
15#include <dune/fem/common/hybrid.hh>
17#include <dune/fem/function/blockvectors/defaultblockvectors.hh>
21#include <dune/fem/misc/petsc/petsccommon.hh>
22#include <dune/fem/misc/petsc/petscdofblock.hh>
23#include <dune/fem/space/common/commoperations.hh>
24#include <dune/fem/space/common/dofmanager.hh>
25#include <dune/fem/space/mapper/petsc.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
96 std::cerr <<
"WARNING: PetscVector cannot handle dof compression!" << std::endl;
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)
192 std::size_t
size ()
const {
return mappers().ghostMapper().size(); }
194 void resize(
const std::size_t newsize = 0 )
206 void reserve(
const std::size_t capacity )
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 );
277 DofBlockType operator[] (
const IndexType index ) {
return DofBlockType( *
this,index ); }
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 )
285 assert(
static_cast< std::size_t
>( index ) < mappers().
size() );
286 return DofBlockPtrType(
typename DofBlockType::UnaryConstructorParamType( *
this, index ) );
289 ConstDofBlockPtrType blockPtr ( IndexType index )
const
291 assert(
static_cast< std::size_t
>( index ) < mappers().
size() );
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() ); }
300 DofIteratorType beforeEnd ()
302 DUNE_THROW(NotImplemented,
"PetscVector::beforeEnd is not implemented yet");
306 ConstDofIteratorType beforeEnd ()
const
308 DUNE_THROW(NotImplemented,
"PetscVector::beforeEnd is not implemented yet");
312 DofIteratorType beforeBegin ()
314 DUNE_THROW(NotImplemented,
"PetscVector::beforeBegin is not implemented yet");
317 ConstDofIteratorType beforeBegin ()
const
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 );
369 return this->operator*=( 1./scalar );
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 );
404 for( std::size_t i = 0; i <
size(); i++ )
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_; }
529 std::size_t usedMemorySize()
const
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;
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
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
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447