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>
36 std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
38 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
40 const unsigned int n_components);
53 template <
typename Number,
55 int simd_length = dealii::VectorizedArray<Number>::size()>
57 :
public dealii::LinearAlgebra::distributed::Vector<Number>
72 using scalar_type = dealii::LinearAlgebra::distributed::Vector<Number>;
78 using scalar_type::operator=;
87 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
105 unsigned int component)
const;
121 unsigned int component);
132 template <
typename Number2 = Number,
133 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
144 template <
typename Number2 = Number,
145 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
161 template <
typename Number2 = Number,
162 typename Tensor = dealii::Tensor<1, n_comp, Number2>>
170 template <
typename Number,
int n_comp,
int simd_length>
173 const std::shared_ptr<const dealii::Utilities::MPI::Partitioner>
180 auto vector_partitioner =
183 dealii::LinearAlgebra::distributed::Vector<Number>::reinit(
188 template <
typename Number,
int n_comp,
int simd_length>
190 scalar_type &scalar_vector,
unsigned int component)
const
194 "Cannot extract from a vector with zero components."));
196 Assert(n_comp * scalar_vector.get_partitioner()->locally_owned_size() ==
197 this->get_partitioner()->locally_owned_size(),
198 dealii::ExcMessage(
"Called with a scalar_vector argument that has "
199 "incompatible local range."));
200 const auto local_size =
201 scalar_vector.get_partitioner()->locally_owned_size();
202 for (
unsigned int i = 0; i < local_size; ++i)
203 scalar_vector.local_element(i) =
204 this->local_element(i * n_comp + component);
205 scalar_vector.update_ghost_values();
209 template <
typename Number,
int n_comp,
int simd_length>
211 const scalar_type &scalar_vector,
unsigned int component)
215 "Cannot insert into 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 this->local_element(i * n_comp + component) =
225 scalar_vector.local_element(i);
230 template <
typename Number,
int n_comp,
int simd_length>
231 template <
typename Number2,
typename Tensor>
232 DEAL_II_ALWAYS_INLINE
inline Tensor
234 const unsigned int i)
const
236 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
237 "dummy type mismatch");
241 if constexpr (n_comp == 0)
244 if constexpr (std::is_same<Number, Number2>::value) {
247 for (
unsigned int d = 0; d < n_comp; ++d)
248 tensor[d] = this->local_element(i * n_comp + d);
250 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
253 std::array<
unsigned int, VectorizedArray::size()> indices;
254 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
255 indices[k] = k * n_comp;
257 dealii::vectorized_load_and_transpose(
258 n_comp, this->begin() + i * n_comp, indices.data(), &tensor[0]);
269 template <
typename Number,
int n_comp,
int simd_length>
270 template <
typename Number2,
typename Tensor>
271 DEAL_II_ALWAYS_INLINE
inline Tensor
273 const unsigned int *js)
const
275 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
276 "dummy type mismatch");
280 if constexpr (n_comp == 0)
283 if constexpr (std::is_same<Number, Number2>::value) {
286 for (
unsigned int d = 0; d < n_comp; ++d)
287 tensor[d] = this->local_element(js[0] * n_comp + d);
289 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
292 std::array<
unsigned int, VectorizedArray::size()> indices;
293 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
294 indices[k] = js[k] * n_comp;
296 dealii::vectorized_load_and_transpose(
297 n_comp, this->begin(), indices.data(), &tensor[0]);
308 template <
typename Number,
int n_comp,
int simd_length>
309 template <
typename Number2,
typename Tensor>
310 DEAL_II_ALWAYS_INLINE
inline void
312 const Tensor &tensor,
const unsigned int i)
314 static_assert(std::is_same<Number2, typename Tensor::value_type>::value,
315 "dummy type mismatch");
318 if constexpr (n_comp == 0)
321 if constexpr (std::is_same<Number, Number2>::value) {
324 for (
unsigned int d = 0; d < n_comp; ++d)
325 this->local_element(i * n_comp + d) = tensor[d];
327 }
else if constexpr (std::is_same<VectorizedArray, Number2>::value) {
330 std::array<
unsigned int, VectorizedArray::size()> indices;
331 for (
unsigned int k = 0; k < VectorizedArray::size(); ++k)
332 indices[k] = k * n_comp;
334 dealii::vectorized_transpose_and_store(
false,
338 this->begin() + i * n_comp);
void reinit_with_scalar_partitioner(const std::shared_ptr< const dealii::Utilities::MPI::Partitioner > &scalar_partitioner)
void insert_component(const scalar_type &scalar_vector, unsigned int component)
void extract_component(scalar_type &scalar_vector, unsigned int component) const
Tensor get_tensor(const unsigned int i) const
dealii::LinearAlgebra::distributed::Vector< Number > scalar_type
dealii::VectorizedArray< Number, simd_length > VectorizedArray
void write_tensor(const Tensor &tensor, const unsigned int i)
Tensor get_tensor(const unsigned int *js) 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)