#ifdef DEAL_II_WITH_PETSC
+ namespace petsc_helpers
+ {
+ template <typename PETSC_Number, typename Number>
+ void
+ copy_petsc_vector(const PETSC_Number *petsc_start_ptr,
+ const PETSC_Number *petsc_end_ptr,
+ Number * ptr)
+ {
+ std::copy(petsc_start_ptr, petsc_end_ptr, ptr);
+ }
+
+ template <typename PETSC_Number, typename Number>
+ void
+ copy_petsc_vector(const std::complex<PETSC_Number> *petsc_start_ptr,
+ const std::complex<PETSC_Number> *petsc_end_ptr,
+ std::complex<Number> * ptr)
+ {
+ std::copy(petsc_start_ptr, petsc_end_ptr, ptr);
+ }
+
+ template <typename PETSC_Number, typename Number>
+ void
+ copy_petsc_vector(const std::complex<PETSC_Number> * /*petsc_start_ptr*/,
+ const std::complex<PETSC_Number> * /*petsc_end_ptr*/,
+ Number * /*ptr*/)
+ {
+ AssertThrow(false, ExcMessage("Tried to copy complex -> real"));
+ }
+ } // namespace petsc_helpers
+
+
+
template <typename Number>
BlockVector<Number> &
BlockVector<Number>::
AssertDimension(this->n_blocks(), petsc_vec.n_blocks());
for (unsigned int i = 0; i < this->n_blocks(); ++i)
{
- const auto &partitioner = this->block(i).get_partitioner();
- IndexSet combined_set = partitioner->locally_owned_range();
- combined_set.add_indices(partitioner->ghost_indices());
- ReadWriteVector<Number> rw_vector(combined_set);
- rw_vector.import(petsc_vec.block(i), VectorOperation::insert);
- this->block(i).import(rw_vector, VectorOperation::insert);
-
- if (this->block(i).has_ghost_elements() ||
+ // We would like to use the same compact infrastructure as for the
+ // Trilinos vector below, but the interface through ReadWriteVector
+ // does not support overlapping (ghosted) PETSc vectors, which we need
+ // for backward compatibility.
+
+ Assert(petsc_vec.block(i).locally_owned_elements() ==
+ this->block(i).locally_owned_elements(),
+ StandardExceptions::ExcInvalidState());
+
+ // get a representation of the vector and copy it
+ PetscScalar * start_ptr;
+ PetscErrorCode ierr =
+ VecGetArray(static_cast<const Vec &>(petsc_vec.block(i)),
+ &start_ptr);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+
+ const size_type vec_size = this->block(i).local_size();
+ petsc_helpers::copy_petsc_vector(start_ptr,
+ start_ptr + vec_size,
+ this->block(i).begin());
+
+ // restore the representation of the vector
+ ierr = VecRestoreArray(static_cast<const Vec &>(petsc_vec.block(i)),
+ &start_ptr);
+ AssertThrow(ierr == 0, ExcPETScError(ierr));
+
+ // spread ghost values between processes?
+ if (this->block(i).vector_is_ghosted ||
petsc_vec.block(i).has_ghost_elements())
this->block(i).update_ghost_values();
}
-#ifdef DEAL_II_WITH_PETSC
-
- namespace petsc_helpers
- {
- template <typename PETSC_Number, typename Number>
- void
- copy_petsc_vector(const PETSC_Number *petsc_start_ptr,
- const PETSC_Number *petsc_end_ptr,
- Number * ptr)
- {
- std::copy(petsc_start_ptr, petsc_end_ptr, ptr);
- }
-
- template <typename PETSC_Number, typename Number>
- void
- copy_petsc_vector(const std::complex<PETSC_Number> *petsc_start_ptr,
- const std::complex<PETSC_Number> *petsc_end_ptr,
- std::complex<Number> * ptr)
- {
- std::copy(petsc_start_ptr, petsc_end_ptr, ptr);
- }
-
- template <typename PETSC_Number, typename Number>
- void
- copy_petsc_vector(const std::complex<PETSC_Number> * /*petsc_start_ptr*/,
- const std::complex<PETSC_Number> * /*petsc_end_ptr*/,
- Number * /*ptr*/)
- {
- AssertThrow(false, ExcMessage("Tried to copy complex -> real"));
- }
- } // namespace petsc_helpers
-
-#endif
-
-
-
template <typename Number, typename MemorySpaceType>
void
Vector<Number, MemorySpaceType>::compress(