Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Tensor::unroll() work with iterators. #12692

Merged
merged 2 commits into from
Sep 9, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
104 changes: 80 additions & 24 deletions include/deal.II/base/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,17 @@ class Tensor<0, dim, Number>
constexpr DEAL_II_CUDA_HOST_DEV real_type
norm_square() const;

/**
* Fill a range with all tensor elements. Since this type of Tensor only has
* one entry this just copies the value of this tensor into <tt>*begin</tt>.
*
* The template type Number must be convertible to the type of
* <tt>*begin</tt>.
*/
template <class Iterator>
void
unroll(const Iterator begin, const Iterator end) const;
drwells marked this conversation as resolved.
Show resolved Hide resolved

/**
* Read or write the data of this object to or from a stream for the purpose
* of serialization using the [BOOST serialization
Expand All @@ -407,10 +418,9 @@ class Tensor<0, dim, Number>
/**
* Internal helper function for unroll.
*/
template <typename OtherNumber>
void
unroll_recursion(Vector<OtherNumber> &result,
unsigned int & start_index) const;
template <typename Iterator>
Iterator
unroll_recursion(const Iterator current, const Iterator end) const;
drwells marked this conversation as resolved.
Show resolved Hide resolved

// Allow an arbitrary Tensor to access the underlying values.
template <int, int, typename>
Expand Down Expand Up @@ -793,11 +803,28 @@ class Tensor
* This function unrolls all tensor entries into a single, linearly numbered
* vector. As usual in C++, the rightmost index of the tensor marches
* fastest.
*
* @deprecated Use the more general function that takes a pair of iterators
* instead.
*/
template <typename OtherNumber>
void
DEAL_II_DEPRECATED_EARLY void
unroll(Vector<OtherNumber> &result) const;

/**
* Fill a range with all tensor elements.
*
* This function unrolls all tensor entries into a single, linearly numbered
* sequence. The order of the elements is the one given by
* component_to_unrolled_index().
*
* The template type Number must be convertible to the type of
* <tt>*begin</tt>.
*/
template <class Iterator>
void
unroll(const Iterator begin, const Iterator end) const;

/**
* Return an unrolled index in the range $[0,\text{dim}^{\text{rank}}-1]$
* for the element of the tensor indexed by the argument to the function.
Expand Down Expand Up @@ -846,10 +873,9 @@ class Tensor
/**
* Internal helper function for unroll.
*/
template <typename OtherNumber>
void
unroll_recursion(Vector<OtherNumber> &result,
unsigned int & start_index) const;
template <typename Iterator>
Iterator
unroll_recursion(const Iterator current, const Iterator end) const;

/**
* This constructor is for internal use. It provides a way
Expand Down Expand Up @@ -1040,6 +1066,7 @@ constexpr inline DEAL_II_ALWAYS_INLINE
}



template <int dim, typename Number>
template <typename OtherNumber>
constexpr inline DEAL_II_ALWAYS_INLINE
Expand Down Expand Up @@ -1212,19 +1239,24 @@ constexpr DEAL_II_CUDA_HOST_DEV inline DEAL_II_ALWAYS_INLINE
}



template <int dim, typename Number>
template <typename OtherNumber>
inline void
Tensor<0, dim, Number>::unroll_recursion(Vector<OtherNumber> &result,
unsigned int & index) const
template <typename Iterator>
Iterator
Tensor<0, dim, Number>::unroll_recursion(const Iterator current,
const Iterator end) const
{
Assert(dim != 0,
ExcMessage("Cannot unroll an object of type Tensor<0,0,Number>"));
result[index] = value;
++index;
Assert(std::distance(current, end) >= 1,
ExcMessage("The provided iterator range must contain at least one "
"element."));
*current = value;
return std::next(current);
}



template <int dim, typename Number>
constexpr inline void
Tensor<0, dim, Number>::clear()
Expand All @@ -1235,6 +1267,18 @@ Tensor<0, dim, Number>::clear()
}



template <int dim, typename Number>
template <class Iterator>
inline void
Tensor<0, dim, Number>::unroll(const Iterator begin, const Iterator end) const
{
AssertDimension(std::distance(begin, end), n_independent_components);
unroll_recursion(begin, end);
}



template <int dim, typename Number>
template <class Archive>
inline void
Expand Down Expand Up @@ -1704,27 +1748,39 @@ constexpr inline DEAL_II_ALWAYS_INLINE DEAL_II_CUDA_HOST_DEV
}



template <int rank_, int dim, typename Number>
template <typename OtherNumber>
inline void
Tensor<rank_, dim, Number>::unroll(Vector<OtherNumber> &result) const
{
AssertDimension(result.size(),
(Utilities::fixed_power<rank_, unsigned int>(dim)));

unsigned int index = 0;
unroll_recursion(result, index);
unroll(result.begin(), result.end());
}



template <int rank_, int dim, typename Number>
template <typename OtherNumber>
template <class Iterator>
inline void
Tensor<rank_, dim, Number>::unroll_recursion(Vector<OtherNumber> &result,
unsigned int & index) const
Tensor<rank_, dim, Number>::unroll(const Iterator begin,
const Iterator end) const
{
AssertDimension(std::distance(begin, end), n_independent_components);
unroll_recursion(begin, end);
}



template <int rank_, int dim, typename Number>
template <typename Iterator>
Iterator
Tensor<rank_, dim, Number>::unroll_recursion(const Iterator current,
const Iterator end) const
{
auto next = current;
for (unsigned int i = 0; i < dim; ++i)
values[i].unroll_recursion(result, index);
next = values[i].unroll_recursion(next, end);
return next;
}


Expand Down