10#include <deal.II/base/mpi.h>
11#include <deal.II/base/partitioner.h>
12#include <deal.II/base/vectorization.h>
13#include <deal.II/lac/la_parallel_vector.h>
38 std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
40 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
42 const unsigned int n_components);
55 template <
typename Number,
57 int simd_length = dealii::VectorizedArray<Number>::size()>
59 :
public dealii::LinearAlgebra::distributed::Vector<Number>
74 using ScalarVector = dealii::LinearAlgebra::distributed::Vector<Number>;
80 using ScalarVector::operator=;
89 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
107 unsigned int component)
const;
123 unsigned int component);
134 template <
typename Number2 = Number,
135 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
146 template <
typename Number2 = Number,
147 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
163 template <
typename Number2 = Number,
164 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
180 template <
typename Number2 = Number,
181 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
189 template <
typename Number,
int n_comp,
int simd_length>
192 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
199 auto vector_partitioner =
202 dealii::LinearAlgebra::distributed::Vector<Number>::reinit(
207 template <
typename Number,
int n_comp,
int simd_length>
209 ScalarVector &scalar_vector,
unsigned int component)
const
213 "Cannot extract from a vector with zero components."));
215 Assert(n_comp * scalar_vector.get_partitioner()->locally_owned_size() ==
216 this->get_partitioner()->locally_owned_size(),
217 dealii::ExcMessage(
"Called with a scalar_vector argument that has "
218 "incompatible local range."));
219 const auto local_size =
220 scalar_vector.get_partitioner()->locally_owned_size();
221 for (
unsigned int i = 0; i < local_size; ++i)
222 scalar_vector.local_element(i) =
223 this->local_element(i * n_comp + component);
224 scalar_vector.update_ghost_values();
228 template <
typename Number,
int n_comp,
int simd_length>
230 const ScalarVector &scalar_vector,
unsigned int component)
234 "Cannot insert into a vector with zero components."));
236 Assert(n_comp * scalar_vector.get_partitioner()->locally_owned_size() ==
237 this->get_partitioner()->locally_owned_size(),
238 dealii::ExcMessage(
"Called with a scalar_vector argument that has "
239 "incompatible local range."));
240 const auto local_size =
241 scalar_vector.get_partitioner()->locally_owned_size();
242 for (
unsigned int i = 0; i < local_size; ++i)
243 this->local_element(i * n_comp + component) =
244 scalar_vector.local_element(i);
249 template <
typename Number,
int n_comp,
int simd_length>
250 template <
typename Number2,
typename Tensor>
251 DEAL_II_ALWAYS_INLINE
inline Tensor
253 const unsigned int i)
const
255 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
256 "dummy type mismatch");
260 if constexpr (n_comp == 0)
263 if constexpr (std::is_same<Number, Number2>::value) {
266 for (
unsigned int d = 0; d < n_comp; ++d)
267 tensor[d] = this->local_element(i * n_comp + d);
269 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
272 std::array<
unsigned int, VectorizedArray::size()> indices;
273 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
274 indices[k] = k * n_comp;
276 dealii::vectorized_load_and_transpose(
277 n_comp, this->begin() + i * n_comp, indices.data(), &tensor[0]);
288 template <
typename Number,
int n_comp,
int simd_length>
289 template <
typename Number2,
typename Tensor>
290 DEAL_II_ALWAYS_INLINE
inline Tensor
292 const unsigned int *js)
const
294 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
295 "dummy type mismatch");
299 if constexpr (n_comp == 0)
302 if constexpr (std::is_same<Number, Number2>::value) {
305 for (
unsigned int d = 0; d < n_comp; ++d)
306 tensor[d] = this->local_element(js[0] * n_comp + d);
308 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
311 std::array<
unsigned int, VectorizedArray::size()> indices;
312 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
313 indices[k] = js[k] * n_comp;
315 dealii::vectorized_load_and_transpose(
316 n_comp, this->begin(), indices.data(), &tensor[0]);
327 template <
typename Number,
int n_comp,
int simd_length>
328 template <
typename Number2,
typename Tensor>
329 DEAL_II_ALWAYS_INLINE
inline void
331 const Tensor &tensor,
const unsigned int i)
333 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
334 "dummy type mismatch");
337 if constexpr (n_comp == 0)
340 if constexpr (std::is_same<Number, Number2>::value) {
343 for (
unsigned int d = 0; d < n_comp; ++d)
344 this->local_element(i * n_comp + d) = tensor[d];
346 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
349 std::array<
unsigned int, VectorizedArray::size()> indices;
350 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
351 indices[k] = k * n_comp;
353 dealii::vectorized_transpose_and_store(
false,
357 this->begin() + i * n_comp);
366 template <
typename Number,
int n_comp,
int simd_length>
367 template <
typename Number2,
typename Tensor>
368 DEAL_II_ALWAYS_INLINE
inline void
370 const Tensor &tensor,
const unsigned int i)
372 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
373 "dummy type mismatch");
376 if constexpr (n_comp == 0)
379 if constexpr (std::is_same<Number, Number2>::value) {
382 for (
unsigned int d = 0; d < n_comp; ++d)
383 this->local_element(i * n_comp + d) += tensor[d];
385 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
388 std::array<
unsigned int, VectorizedArray::size()> indices;
389 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
390 indices[k] = k * n_comp;
392 dealii::vectorized_transpose_and_store(
true,
396 this->begin() + i * n_comp);
void write_tensor(const Tensor &tensor, const unsigned int i)
void extract_component(ScalarVector &scalar_vector, unsigned int component) const
void add_tensor(const Tensor &tensor, const unsigned int i)
Tensor get_tensor(const unsigned int *js) const
void insert_component(const ScalarVector &scalar_vector, unsigned int component)
dealii::VectorizedArray< Number, simd_length > VectorizedArray
dealii::LinearAlgebra::distributed::Vector< Number > ScalarVector
void reinit_with_scalar_partitioner(const std::shared_ptr< const dealii::Utilities::MPI::Partitioner > &scalar_partitioner)
Tensor get_tensor(const unsigned int i) const
std::shared_ptr< const dealii::Utilities::MPI::Partitioner > create_vector_partitioner(const std::shared_ptr< const dealii::Utilities::MPI::Partitioner > &scalar_partitioner, const unsigned int n_components)
dealii::LinearAlgebra::distributed::Vector< Number > ScalarVector