8#include <compile_time_options.h>
12#include <deal.II/base/mpi.h>
13#include <deal.II/base/partitioner.h>
14#include <deal.II/base/vectorization.h>
15#include <deal.II/lac/la_parallel_vector.h>
40 std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
42 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
44 const unsigned int n_components);
57 template <
typename Number,
59 int simd_length = dealii::VectorizedArray<Number>::size()>
61 :
public dealii::LinearAlgebra::distributed::Vector<Number>
76 using ScalarVector = dealii::LinearAlgebra::distributed::Vector<Number>;
82 using ScalarVector::operator=;
91 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
109 unsigned int component)
const;
125 unsigned int component);
136 template <
typename Number2 = Number,
137 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
148 template <
typename Number2 = Number,
149 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
165 template <
typename Number2 = Number,
166 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
182 template <
typename Number2 = Number,
183 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
191 template <
typename Number,
int n_comp,
int simd_length>
194 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
201 auto vector_partitioner =
204 dealii::LinearAlgebra::distributed::Vector<Number>::reinit(
209 template <
typename Number,
int n_comp,
int simd_length>
211 ScalarVector &scalar_vector,
unsigned int component)
const
215 "Cannot extract from a vector with zero components."));
217 Assert(n_comp * scalar_vector.get_partitioner()->locally_owned_size() ==
218 this->get_partitioner()->locally_owned_size(),
219 dealii::ExcMessage(
"Called with a scalar_vector argument that has "
220 "incompatible local range."));
221 const auto local_size =
222 scalar_vector.get_partitioner()->locally_owned_size();
223 for (
unsigned int i = 0; i < local_size; ++i)
224 scalar_vector.local_element(i) =
225 this->local_element(i * n_comp + component);
226 scalar_vector.update_ghost_values();
230 template <
typename Number,
int n_comp,
int simd_length>
232 const ScalarVector &scalar_vector,
unsigned int component)
236 "Cannot insert into a vector with zero components."));
238 Assert(n_comp * scalar_vector.get_partitioner()->locally_owned_size() ==
239 this->get_partitioner()->locally_owned_size(),
240 dealii::ExcMessage(
"Called with a scalar_vector argument that has "
241 "incompatible local range."));
242 const auto local_size =
243 scalar_vector.get_partitioner()->locally_owned_size();
244 for (
unsigned int i = 0; i < local_size; ++i)
245 this->local_element(i * n_comp + component) =
246 scalar_vector.local_element(i);
251 template <
typename Number,
int n_comp,
int simd_length>
252 template <
typename Number2,
typename Tensor>
253 DEAL_II_ALWAYS_INLINE
inline Tensor
255 const unsigned int i)
const
257 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
258 "dummy type mismatch");
262 if constexpr (n_comp == 0)
265 if constexpr (std::is_same<Number, Number2>::value) {
268 for (
unsigned int d = 0; d < n_comp; ++d)
269 tensor[d] = this->local_element(i * n_comp + d);
271 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
274 std::array<
unsigned int, VectorizedArray::size()> indices;
275 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
276 indices[k] = k * n_comp;
278 dealii::vectorized_load_and_transpose(
279 n_comp, this->begin() + i * n_comp, indices.data(), &tensor[0]);
290 template <
typename Number,
int n_comp,
int simd_length>
291 template <
typename Number2,
typename Tensor>
292 DEAL_II_ALWAYS_INLINE
inline Tensor
294 const unsigned int *js)
const
296 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
297 "dummy type mismatch");
301 if constexpr (n_comp == 0)
304 if constexpr (std::is_same<Number, Number2>::value) {
307 for (
unsigned int d = 0; d < n_comp; ++d)
308 tensor[d] = this->local_element(js[0] * n_comp + d);
310 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
313 std::array<
unsigned int, VectorizedArray::size()> indices;
314 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
315 indices[k] = js[k] * n_comp;
317 dealii::vectorized_load_and_transpose(
318 n_comp, this->begin(), indices.data(), &tensor[0]);
329 template <
typename Number,
int n_comp,
int simd_length>
330 template <
typename Number2,
typename Tensor>
331 DEAL_II_ALWAYS_INLINE
inline void
333 const Tensor &tensor,
const unsigned int i)
335 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
336 "dummy type mismatch");
339 if constexpr (n_comp == 0)
342 if constexpr (std::is_same<Number, Number2>::value) {
345 for (
unsigned int d = 0; d < n_comp; ++d)
346 this->local_element(i * n_comp + d) = tensor[d];
348 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
351 std::array<
unsigned int, VectorizedArray::size()> indices;
352 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
353 indices[k] = k * n_comp;
355 dealii::vectorized_transpose_and_store(
false,
359 this->begin() + i * n_comp);
368 template <
typename Number,
int n_comp,
int simd_length>
369 template <
typename Number2,
typename Tensor>
370 DEAL_II_ALWAYS_INLINE
inline void
372 const Tensor &tensor,
const unsigned int i)
374 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
375 "dummy type mismatch");
378 if constexpr (n_comp == 0)
381 if constexpr (std::is_same<Number, Number2>::value) {
384 for (
unsigned int d = 0; d < n_comp; ++d)
385 this->local_element(i * n_comp + d) += tensor[d];
387 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
390 std::array<
unsigned int, VectorizedArray::size()> indices;
391 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
392 indices[k] = k * n_comp;
394 dealii::vectorized_transpose_and_store(
true,
398 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