From: David Wells Date: Fri, 24 Mar 2023 12:42:44 +0000 (-0400) Subject: Add a move assignment operator to LA::d::V. X-Git-Tag: v9.5.0-rc1~303^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F14969%2Fhead;p=dealii.git Add a move assignment operator to LA::d::V. --- diff --git a/include/deal.II/lac/la_parallel_vector.h b/include/deal.II/lac/la_parallel_vector.h index afd9a24bcd..79fbe965b9 100644 --- a/include/deal.II/lac/la_parallel_vector.h +++ b/include/deal.II/lac/la_parallel_vector.h @@ -443,6 +443,15 @@ namespace LinearAlgebra void swap(Vector &v); + /** + * Move assignment operator. + * + * @note This method may throw an exception (should an MPI check fail) and + * is consequently not `noexcept`. + */ + Vector & + operator=(Vector &&in_vector); // NOLINT + /** * Assigns the vector to the parallel partitioning of the input vector * @p in_vector, and copies all the data. diff --git a/include/deal.II/lac/la_parallel_vector.templates.h b/include/deal.II/lac/la_parallel_vector.templates.h index 20962b80db..a0de1a320e 100644 --- a/include/deal.II/lac/la_parallel_vector.templates.h +++ b/include/deal.II/lac/la_parallel_vector.templates.h @@ -1375,6 +1375,18 @@ namespace LinearAlgebra + template + Vector & + Vector::operator=( // NOLINT + Vector &&v) + { + static_cast(*this) = static_cast(v); + this->swap(v); + return *this; + } + + + template Vector & Vector::operator=(const Number s) diff --git a/tests/lac/parallel_vector_08.cc b/tests/lac/parallel_vector_08.cc index b9c4b6cd97..cc7d46af41 100644 --- a/tests/lac/parallel_vector_08.cc +++ b/tests/lac/parallel_vector_08.cc @@ -14,8 +14,8 @@ // --------------------------------------------------------------------- -// check parallel_vector::copy_from to update ghost values. Same vector layout -// as in parallel_vector_07.cc +// check parallel_vector assignment and ghost values. Same vector layout as in +// parallel_vector_07.cc #include #include @@ -58,10 +58,12 @@ test() IndexSet local_owned(global_size); local_owned.add_range(my_start, my_start + local_size); IndexSet local_relevant(global_size); - local_relevant = local_owned; - unsigned int ghost_indices[10] = { + local_relevant = local_owned; + const std::size_t n_ghosts = 10; + unsigned int ghost_indices[n_ghosts] = { 1, 2, 13, set - 3, set - 2, set - 1, set, set + 1, set + 2, set + 3}; - local_relevant.add_indices(&ghost_indices[0], &ghost_indices[0] + 10); + local_relevant.add_indices(std::begin(ghost_indices), + std::end(ghost_indices)); // v has ghosts, w has none. set some entries // on w, copy into v and check if they are @@ -80,6 +82,29 @@ test() v = w; v.update_ghost_values(); + // Check local and ghost values with move assignment: + { + decltype(v) v_move, v_copy = v; + v_move = std::move(v_copy); + + LinearAlgebra::ReadWriteVector v_rw(local_relevant); + v_rw.import(v, VectorOperation::insert); + LinearAlgebra::ReadWriteVector v_move_rw(local_relevant); + v_move_rw.import(v_move, VectorOperation::insert); + + for (unsigned int i = 0; i < v_rw.locally_owned_size(); ++i) + AssertThrow(v_move_rw.local_element(i) == v_rw.local_element(i), + ExcInternalError()); + + // v_copy should now be empty + AssertThrow(v_copy.locally_owned_size() == 0, ExcInternalError()); + AssertThrow(v_copy.get_partitioner()->size() == 0, ExcInternalError()); + AssertThrow(v_copy.get_partitioner()->n_ghost_indices() == 0, + ExcInternalError()); + AssertThrow(v_copy.get_mpi_communicator() == MPI_COMM_SELF, + ExcInternalError()); + } + // check local values for correctness rw_vector.import(v, VectorOperation::insert); for (unsigned int i = 0; i < local_size; ++i)