VectorType & dst,
const VectorType & src) const = 0;
+ /**
+ * Prolongate a vector from level <tt>to_level-1</tt> to level
+ * <tt>to_level</tt>, summing into the previous content of <tt>dst</tt>.
+ *
+ * @arg src is a vector with as many elements as there are degrees of
+ * freedom on the coarser level involved.
+ *
+ * @arg dst has as many elements as there are degrees of freedom on the
+ * finer level.
+ */
+ virtual void
+ prolongate_and_add(const unsigned int to_level,
+ VectorType & dst,
+ const VectorType & src) const;
+
/**
* Restrict a vector from level <tt>from_level</tt> to level
* <tt>from_level-1</tt> and add this restriction to <tt>dst</tt>. If the
LinearAlgebra::distributed::Vector<Number> & dst,
const LinearAlgebra::distributed::Vector<Number> &src) const override;
+ virtual void
+ prolongate_and_add(
+ const unsigned int to_level,
+ LinearAlgebra::distributed::Vector<Number> & dst,
+ const LinearAlgebra::distributed::Vector<Number> &src) const override;
+
/**
* Restrict a vector from level <tt>from_level</tt> to level
* <tt>from_level-1</tt> using the transpose operation of the prolongate()
LinearAlgebra::distributed::BlockVector<Number> & dst,
const LinearAlgebra::distributed::BlockVector<Number> &src) const override;
+ virtual void
+ prolongate_and_add(
+ const unsigned int to_level,
+ LinearAlgebra::distributed::BlockVector<Number> & dst,
+ const LinearAlgebra::distributed::BlockVector<Number> &src) const override;
+
/**
* Restrict a vector from level <tt>from_level</tt> to level
* <tt>from_level-1</tt> using the transpose operation of the prolongate()
const unsigned int to_level,
LinearAlgebra::distributed::Vector<Number> & dst,
const LinearAlgebra::distributed::Vector<Number> &src) const
+{
+ dst = 0;
+ prolongate_and_add(to_level, dst, src);
+}
+
+
+
+template <int dim, typename Number>
+void
+MGTransferMatrixFree<dim, Number>::prolongate_and_add(
+ const unsigned int to_level,
+ LinearAlgebra::distributed::Vector<Number> & dst,
+ const LinearAlgebra::distributed::Vector<Number> &src) const
{
Assert((to_level >= 1) && (to_level <= level_dof_indices.size()),
ExcIndexRange(to_level, 1, level_dof_indices.size() + 1));
this->vector_partitioners[to_level]);
AssertDimension(this->ghosted_level_vector[to_level].locally_owned_size(),
dst.locally_owned_size());
+ this->ghosted_level_vector[to_level] = 0.;
}
const LinearAlgebra::distributed::Vector<Number> &src_vec =
LinearAlgebra::distributed::Vector<Number> &dst_vec =
dst_inplace ? dst : this->ghosted_level_vector[to_level];
- dst_vec = 0.;
-
src_vec.update_ghost_values();
// the implementation in do_prolongate_add is templated in the degree of the
// element (for efficiency reasons), so we need to find the appropriate
dst_vec.compress(VectorOperation::add);
if (dst_inplace == false)
- dst.copy_locally_owned_data_from(this->ghosted_level_vector[to_level]);
+ dst += dst_vec;
if (src_inplace == true)
src.zero_out_ghost_values();
+template <int dim, typename Number>
+void
+MGTransferBlockMatrixFree<dim, Number>::prolongate_and_add(
+ const unsigned int to_level,
+ LinearAlgebra::distributed::BlockVector<Number> & dst,
+ const LinearAlgebra::distributed::BlockVector<Number> &src) const
+{
+ const unsigned int n_blocks = src.n_blocks();
+ AssertDimension(dst.n_blocks(), n_blocks);
+
+ if (!same_for_all)
+ AssertDimension(matrix_free_transfer_vector.size(), n_blocks);
+
+ for (unsigned int b = 0; b < n_blocks; ++b)
+ {
+ const unsigned int data_block = same_for_all ? 0 : b;
+ matrix_free_transfer_vector[data_block].prolongate_and_add(to_level,
+ dst.block(b),
+ src.block(b));
+ }
+}
+
+
+
template <int dim, typename Number>
void
MGTransferBlockMatrixFree<dim, Number>::restrict_and_add(