16 #ifndef dealii_tensor_product_matrix_h 17 #define dealii_tensor_product_matrix_h 75 template <
int dim,
typename Number,
int n_rows_1d = -1>
241 template <
int dim,
typename Number,
int n_rows_1d = -1>
320 template <
typename MatrixArray>
322 reinit_impl(MatrixArray &&mass_matrix, MatrixArray &&derivative_matrix);
335 template <
int dim,
typename Number,
int n_rows_1d>
338 VectorizedArray<Number>,
402 template <
typename MatrixArray>
414 namespace TensorProductMatrix
424 template <
typename Number>
428 const unsigned int n_rows,
429 const unsigned int n_cols,
435 auto &&transpose_fill_nm = [](Number * out,
437 const unsigned int n,
438 const unsigned int m) {
439 for (
unsigned int mm = 0; mm <
m; ++mm)
440 for (
unsigned int nn = 0; nn <
n; ++nn)
441 out[mm + nn * m] = *(in++);
444 std::vector<::Vector<Number>> eigenvecs(n_rows);
448 transpose_fill_nm(&(mass_copy(0, 0)), mass_matrix, n_rows, n_cols);
449 transpose_fill_nm(&(deriv_copy(0, 0)), derivative_matrix, n_rows, n_cols);
454 for (
unsigned int i = 0; i < n_rows; ++i)
455 for (
unsigned int j = 0; j < n_cols; ++j, ++
eigenvectors)
456 *eigenvectors = eigenvecs[j][i];
458 for (
unsigned int i = 0; i < n_rows; ++i, ++
eigenvalues)
459 *eigenvalues = deriv_copy.
eigenvalue(i).real();
465 template <
int dim,
typename Number,
int n_rows_1d>
470 for (
unsigned int d = 1;
d < dim; ++
d)
477 template <
int dim,
typename Number,
int n_rows_1d>
482 for (
unsigned int d = 1;
d < dim; ++
d)
489 template <
int dim,
typename Number,
int n_rows_1d>
497 std::lock_guard<std::mutex> lock(this->
mutex);
498 const unsigned int n = Utilities::fixed_power<dim>(
499 n_rows_1d > 0 ? n_rows_1d :
eigenvalues[0].size());
501 constexpr
int kernel_size = n_rows_1d > 0 ? n_rows_1d : 0;
513 const Number *src = src_view.
begin();
514 Number * dst = dst_view.
data();
519 eval.template apply<0, false, false>(
A, src, dst);
528 eval.template apply<0, false, false>(M0, src, t);
529 eval.template apply<1, false, false>(A1, t, dst);
530 eval.template apply<0, false, false>(A0, src, t);
531 eval.template apply<1, false, true>(M1, t, dst);
542 eval.template apply<0, false, false>(M0, src, t +
n);
543 eval.template apply<1, false, false>(M1, t +
n, t);
544 eval.template apply<2, false, false>(A2, t, dst);
545 eval.template apply<1, false, false>(A1, t +
n, t);
546 eval.template apply<0, false, false>(A0, src, t +
n);
547 eval.template apply<1, false, true>(M1, t +
n, t);
548 eval.template apply<2, false, true>(M2, t, dst);
557 template <
int dim,
typename Number,
int n_rows_1d>
565 std::lock_guard<std::mutex> lock(this->
mutex);
566 const unsigned int n = n_rows_1d > 0 ? n_rows_1d :
eigenvalues[0].size();
568 constexpr
int kernel_size = n_rows_1d > 0 ? n_rows_1d : 0;
580 const Number *src = src_view.
data();
581 Number * dst = dst_view.
data();
591 eval.template apply<0, true, false>(S, src, t);
592 for (
unsigned int i = 0; i <
n; ++i)
594 eval.template apply<0, false, false>(S, t, dst);
601 eval.template apply<0, true, false>(S0, src, t);
602 eval.template apply<1, true, false>(S1, t, dst);
603 for (
unsigned int i1 = 0, c = 0; i1 <
n; ++i1)
604 for (
unsigned int i0 = 0; i0 <
n; ++i0, ++c)
606 eval.template apply<0, false, false>(S0, dst, t);
607 eval.template apply<1, false, false>(S1, t, dst);
615 eval.template apply<0, true, false>(S0, src, t);
616 eval.template apply<1, true, false>(S1, t, dst);
617 eval.template apply<2, true, false>(S2, dst, t);
618 for (
unsigned int i2 = 0, c = 0; i2 <
n; ++i2)
619 for (
unsigned int i1 = 0; i1 <
n; ++i1)
620 for (
unsigned int i0 = 0; i0 <
n; ++i0, ++c)
623 eval.template apply<0, false, false>(S0, t, dst);
624 eval.template apply<1, false, false>(S1, dst, t);
625 eval.template apply<2, false, false>(S2, t, dst);
635 template <
int dim,
typename Number,
int n_rows_1d>
646 template <
int dim,
typename Number,
int n_rows_1d>
657 template <
int dim,
typename Number,
int n_rows_1d>
662 reinit(mass_matrix, derivative_matrix);
667 template <
int dim,
typename Number,
int n_rows_1d>
668 template <
typename MatrixArray>
671 MatrixArray &&mass_matrices_,
672 MatrixArray &&derivative_matrices_)
674 auto &&mass_matrices = std::forward<MatrixArray>(mass_matrices_);
675 auto &&derivative_matrices = std::forward<MatrixArray>(derivative_matrices_);
676 this->mass_matrix = mass_matrices;
677 this->derivative_matrix = derivative_matrices;
679 for (
int dir = 0; dir < dim; ++dir)
682 (n_rows_1d > 0 && static_cast<unsigned int>(n_rows_1d) ==
683 mass_matrices[dir].n_rows()),
685 AssertDimension(mass_matrices[dir].n_rows(), mass_matrices[dir].n_cols());
687 derivative_matrices[dir].n_rows());
689 derivative_matrices[dir].n_cols());
691 this->
eigenvectors[dir].reinit(mass_matrices[dir].n_cols(),
692 mass_matrices[dir].n_rows());
693 this->
eigenvalues[dir].resize(mass_matrices[dir].n_cols());
694 internal::TensorProductMatrix::spectral_assembly<Number>(
695 &(mass_matrices[dir](0, 0)),
696 &(derivative_matrices[dir](0, 0)),
697 mass_matrices[dir].n_rows(),
698 mass_matrices[dir].n_cols(),
706 template <
int dim,
typename Number,
int n_rows_1d>
712 reinit_impl(mass_matrix, derivative_matrix);
717 template <
int dim,
typename Number,
int n_rows_1d>
723 std::array<Table<2, Number>, dim> mass_copy;
724 std::array<Table<2, Number>, dim> deriv_copy;
733 derivative_matrix.cend(),
739 reinit_impl(std::move(mass_copy), std::move(deriv_copy));
744 template <
int dim,
typename Number,
int n_rows_1d>
750 std::array<Table<2, Number>, dim> mass_matrices;
751 std::array<Table<2, Number>, dim> derivative_matrices;
753 std::fill(mass_matrices.begin(), mass_matrices.end(),
mass_matrix);
754 std::fill(derivative_matrices.begin(),
755 derivative_matrices.end(),
758 reinit_impl(std::move(mass_matrices), std::move(derivative_matrices));
765 template <
int dim,
typename Number,
int n_rows_1d>
769 TensorProductMatrixSymmetricSum(
773 reinit(mass_matrix, derivative_matrix);
778 template <
int dim,
typename Number,
int n_rows_1d>
782 TensorProductMatrixSymmetricSum(
786 reinit(mass_matrix, derivative_matrix);
791 template <
int dim,
typename Number,
int n_rows_1d>
792 template <
typename MatrixArray>
795 reinit_impl(MatrixArray &&mass_matrices_, MatrixArray &&derivative_matrices_)
797 auto &&mass_matrix = std::forward<MatrixArray>(mass_matrices_);
798 auto &&derivative_matrix = std::forward<MatrixArray>(derivative_matrices_);
803 std::size_t n_rows_max = (n_rows_1d > 0) ? n_rows_1d : 0;
805 for (
unsigned int d = 0;
d < dim; ++
d)
806 n_rows_max =
std::max(n_rows_max, mass_matrix[
d].n_rows());
807 const std::size_t nm_flat_size_max = n_rows_max * n_rows_max * macro_size;
808 const std::size_t n_flat_size_max = n_rows_max * macro_size;
810 std::vector<Number> mass_matrix_flat;
811 std::vector<Number> deriv_matrix_flat;
812 std::vector<Number> eigenvalues_flat;
813 std::vector<Number> eigenvectors_flat;
814 mass_matrix_flat.resize(nm_flat_size_max);
815 deriv_matrix_flat.resize(nm_flat_size_max);
816 eigenvalues_flat.resize(n_flat_size_max);
817 eigenvectors_flat.resize(nm_flat_size_max);
818 std::array<unsigned int, macro_size> offsets_nm;
819 std::array<unsigned int, macro_size> offsets_n;
820 for (
int dir = 0; dir < dim; ++dir)
823 (n_rows_1d > 0 && static_cast<unsigned int>(n_rows_1d) ==
824 mass_matrix[dir].n_rows()),
828 derivative_matrix[dir].n_rows());
830 derivative_matrix[dir].n_cols());
832 const unsigned int n_rows = mass_matrix[dir].n_rows();
833 const unsigned int n_cols = mass_matrix[dir].n_cols();
834 const unsigned int nm = n_rows * n_cols;
835 for (
unsigned int vv = 0; vv < macro_size; ++vv)
836 offsets_nm[vv] = nm * vv;
840 &(mass_matrix[dir](0, 0)),
842 mass_matrix_flat.data());
845 &(derivative_matrix[dir](0, 0)),
847 deriv_matrix_flat.data());
849 const Number *mass_cbegin = mass_matrix_flat.data();
850 const Number *deriv_cbegin = deriv_matrix_flat.data();
851 Number * eigenvec_begin = eigenvectors_flat.data();
852 Number * eigenval_begin = eigenvalues_flat.data();
853 for (
unsigned int lane = 0; lane < macro_size; ++lane)
854 internal::TensorProductMatrix::spectral_assembly<Number>(
855 mass_cbegin + nm * lane,
856 deriv_cbegin + nm * lane,
859 eigenval_begin + n_rows * lane,
860 eigenvec_begin + nm * lane);
864 for (
unsigned int vv = 0; vv < macro_size; ++vv)
865 offsets_n[vv] = n_rows * vv;
867 eigenvalues_flat.data(),
871 eigenvectors_flat.data(),
879 template <
int dim,
typename Number,
int n_rows_1d>
886 reinit_impl(mass_matrix, derivative_matrix);
891 template <
int dim,
typename Number,
int n_rows_1d>
897 std::array<Table<2, VectorizedArray<Number>>, dim> mass_matrices;
898 std::array<Table<2, VectorizedArray<Number>>, dim> derivative_matrices;
900 std::fill(mass_matrices.begin(), mass_matrices.end(),
mass_matrix);
901 std::fill(derivative_matrices.begin(),
902 derivative_matrices.end(),
905 reinit_impl(std::move(mass_matrices), std::move(derivative_matrices));
void transform(const InputIterator &begin_in, const InputIterator &end_in, OutputIterator out, const Predicate &predicate, const unsigned int grainsize)
void reinit(MatrixBlock< MatrixType > &v, const BlockSparsityPattern &p)
#define AssertDimension(dim1, dim2)
static constexpr int n_rows_1d_static
std::array< AlignedVector< Number >, dim > eigenvalues
AlignedVector< Number > tmp_array
std::complex< number > eigenvalue(const size_type i) const
TensorProductMatrixSymmetricSumBase()=default
void vmult(const ArrayView< Number > &dst, const ArrayView< const Number > &src) const
#define AssertThrow(cond, exc)
void apply_inverse(const ArrayView< Number > &dst, const ArrayView< const Number > &src) const
void vectorized_load_and_transpose(const unsigned int n_entries, const Number *in, const unsigned int *offsets, VectorizedArray< Number, width > *out)
#define Assert(cond, exc)
static ::ExceptionBase & ExcDimensionMismatch(std::size_t arg1, std::size_t arg2)
void reinit(const std::array< Table< 2, Number >, dim > &mass_matrix, const std::array< Table< 2, Number >, dim > &derivative_matrix)
#define DEAL_II_NAMESPACE_CLOSE
static constexpr std::size_t size()
value_type * data() const noexcept
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
void reinit_impl(MatrixArray &&mass_matrix, MatrixArray &&derivative_matrix)
std::array< Table< 2, Number >, dim > eigenvectors
TensorProductMatrixSymmetricSum()=default
void resize_fast(const size_type size)
#define DEAL_II_NAMESPACE_OPEN
void compute_generalized_eigenvalues_symmetric(LAPACKFullMatrix< number > &B, const number lower_bound, const number upper_bound, const number abs_accuracy, Vector< number > &eigenvalues, std::vector< Vector< number >> &eigenvectors, const types::blas_int itype=1)
static ::ExceptionBase & ExcNotImplemented()
std::array< Table< 2, Number >, dim > derivative_matrix
void vectorized_transpose_and_store(const bool add_into, const unsigned int n_entries, const VectorizedArray< Number, width > *in, const unsigned int *offsets, Number *out)
std::array< Table< 2, Number >, dim > mass_matrix
T max(const T &t, const MPI_Comm &mpi_communicator)