8#include <kernel/util/math.hpp>
9#include <kernel/lafem/dense_vector.hpp>
10#include <kernel/lafem/sparse_matrix_csr.hpp>
11#include <kernel/lafem/sparse_matrix_banded.hpp>
12#include <kernel/lafem/pointstar_structure.hpp>
25 template<
typename DataType_,
typename IndexType_>
37 XASSERTM(m >=
Index(3),
"You need at least 3 inner nodes per dimension");
100 const DataType_ xsf = DataType_(Math::pi<DataType_>()) / DataType_(
_m+1);
102 for(
Index i(0); i < neq; ++i)
104 for(
Index quo(1); quo < neq; quo *=
_m)
135 const DataType_ xsf = DataType_(1) / DataType_(
_m+1);
137 for(
Index i(0); i < neq; ++i)
139 for(
Index quo(1); quo < neq; quo *=
_m)
142 DataType_ x(xsf * DataType_(((i / quo) %
_m) +
Index(1)));
143 v[i] *= DataType_(4) * x * (DataType_(1) - x);
165 template<
typename DataType_,
typename IndexType_>
195 Index i,j,k,l,n,neq,nnze,bpl,rpb,rps,b;
196 IndexType_ *epr,*dor,*ior,*col_idx;
203 for(i = 1; i < d; ++i)
206 nnze += 2*(m-1) * neq;
247 for(l = 0; l < d; ++l)
253 for(b = 0; b < bpl; ++b)
259 for(j = 0; j < rps; ++j)
263 for(i = 1; i < m - 1; ++i)
267 for(j = 0; j < rps; ++j)
276 for(j = 0; j < rps; ++j)
292 for(i = 0; i < neq; ++i)
294 ior[i+1] = ior[i] + epr[i];
299 const DataType_ v1 = DataType_(2*d);
300 const DataType_ v2 = DataType_(-1);
301 for(i = 0; i < neq; ++i)
304 for(j = ior[i]; j < dor[i]; ++j)
311 for(j = dor[i]+1; j < ior[i+1]; ++j)
320 for(i = 0; i < neq; ++i)
322 epr[i] = ior[i+1] - dor[i] - 1;
323 col_idx[dor[i]] = IndexType_(i);
342 for(l = 0; l < d; ++l)
348 for(b = 0; b < bpl; ++b)
354 for(i = 0; i < rpb - rps; ++i)
357 col_idx[dor[k+i]+epr[k+i]] = IndexType_(k + i + rps);
358 col_idx[dor[neq-k-i-1]-epr[k+i]] = IndexType_(neq - k - i - rps - 1);
361 for(i = 0; i < rpb - rps; ++i)
389 return DataType_(2) * DataType_(this->
_d) *
390 (DataType_(1) -
Math::cos(Math::pi<DataType_>() / DataType_(this->
_m+1)));
406 return DataType_(2) * DataType_(this->
_d) *
407 (DataType_(1) +
Math::cos(Math::pi<DataType_>() / DataType_(this->
_m+1)));
423 template<
typename DataType_,
typename IndexType_>
452 Index i,j,k,l,n,neq,nnze,bpl,rpb,rps,b;
453 IndexType_ *epr,*dor,*ior,*col_idx;
460 for(i = 1; i < d; i++)
503 for(l = 0; l < d; ++l)
509 for(b = 0; b < bpl; ++b)
515 for(j = 0; j < rps; ++j)
519 for(i = 1; i < m - 1; ++i)
523 for(j = 0; j < rps; ++j)
525 dor[n+j] += epr[n+j];
532 for(j = 0; j < rps; ++j)
534 dor[n+j] += epr[n+j];
549 for(i = 0; i < neq; ++i)
551 ior[i+1] = ior[i] + epr[i];
557 for(i = 1; i < d; ++i)
559 const DataType_ v1 = DataType_(j -
Index(1));
560 const DataType_ v2 = DataType_(-1);
562 for(i = 0; i < neq; ++i)
565 for(j = ior[i]; j < dor[i]; ++j)
572 for(j = dor[i]+1; j < ior[i+1]; ++j)
579 for(i = 0; i < neq; ++i)
582 for(j = ior[i]; j < ior[i+1]; ++j)
583 col_idx[j] = IndexType_(neq+i);
593 for(l = d; l > 0; --l)
599 for(b = 0; b < bpl; ++b)
605 for(i = 0; i < rps; ++i)
607 for(n = 0; 2*n*epr[k+i] < ior[k+i+1]-ior[k+i]; ++n)
609 for(j = 0; j < epr[k+i]; ++j)
611 col_idx[ior[k+i]+2*n*epr[k+i]+j+epr[k+i]] += IndexType_(rps);
612 col_idx[ior[neq-k-i]-2*n*epr[k+i]-j-epr[k+i]-1] -= IndexType_(rps);
620 for(i = rps; i < rpb - rps; ++i)
622 for(n = 0; 3*n*epr[k+i] < ior[k+i+1]-ior[k+i]; ++n)
624 for(j = 0; j < epr[k+i]; ++j)
626 col_idx[ior[k+i]+3*n*epr[k+i]+j+2*epr[k+i]] += IndexType_(rps);
627 col_idx[ior[neq-k-i]-3*n*epr[k+i]-j-2*epr[k+i]-1] -= IndexType_(rps);
642 for(i = 0; i < nnze; ++i)
643 col_idx[i] -= IndexType_(neq);
664 const IndexType_ m = IndexType_(this->
_m);
665 const IndexType_* row_ptr = matrix.
row_ptr();
666 const IndexType_* col_idx = matrix.
col_ind();
667 DataType_* val = matrix.
val();
673 const IndexType_ row = 0;
674 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
676 const IndexType_ col = col_idx[k];
678 val[k] = DataType_(4);
679 else if(col == row+1)
680 val[k] = DataType_(-1);
681 else if(col == row+m)
682 val[k] = DataType_(-1);
683 else if(col == row+m+1)
684 val[k] = DataType_(-2);
691 for(IndexType_ jj(1); jj + 1 < m; ++jj)
694 const IndexType_ row = jj;
695 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
697 const IndexType_ col = col_idx[k];
699 val[k] = DataType_(8);
700 else if(col+1 == row)
701 val[k] = DataType_(-1);
702 else if(col == row+1)
703 val[k] = DataType_(-1);
705 val[k] = DataType_(-2);
711 const IndexType_ row = m - 1;
712 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
714 const IndexType_ col = col_idx[k];
716 val[k] = DataType_(4);
717 else if(col+1 == row)
718 val[k] = DataType_(-1);
719 else if(col == row+m)
720 val[k] = DataType_(-1);
721 else if(col+1 == row+m)
722 val[k] = DataType_(-2);
730 for(IndexType_ ii(1); ii + 1 < m; ++ii)
734 const IndexType_ row = ii*m;
735 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
737 const IndexType_ col = col_idx[k];
739 val[k] = DataType_(8);
740 else if(col+m == row)
741 val[k] = DataType_(-1);
742 else if(col == row+m)
743 val[k] = DataType_(-1);
745 val[k] = DataType_(-2);
750 for(IndexType_ jj(1); jj + 1 < m; ++jj)
753 const IndexType_ row = ii*m + jj;
754 for(IndexType_ k(row_ptr[row]); k < row_ptr[row+1]; ++k)
755 val[k] = DataType_(col_idx[k] == row ? 16 : -2);
760 const IndexType_ row = ii*m + m - 1;
761 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
763 const IndexType_ col = col_idx[k];
765 val[k] = DataType_(8);
766 else if(col+m == row)
767 val[k] = DataType_(-1);
768 else if(col == row+m)
769 val[k] = DataType_(-1);
771 val[k] = DataType_(-2);
781 const IndexType_ row = (m-1)*m;
782 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
784 const IndexType_ col = col_idx[k];
786 val[k] = DataType_(4);
787 else if(col == row+1)
788 val[k] = DataType_(-1);
789 else if(col+m == row)
790 val[k] = DataType_(-1);
791 else if(col+m == row+1)
792 val[k] = DataType_(-2);
799 for(IndexType_ jj(1); jj + 1 < m; ++jj)
802 const IndexType_ row = (m-1)*m + jj;
803 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
805 const IndexType_ col = col_idx[k];
807 val[k] = DataType_(8);
808 else if(col+1 == row)
809 val[k] = DataType_(-1);
810 else if(col == row+1)
811 val[k] = DataType_(-1);
813 val[k] = DataType_(-2);
819 const IndexType_ row = (m-1)*m + m - 1;
820 for(IndexType_ k(row_ptr[row]); k < row_ptr[row + 1]; ++k)
822 const IndexType_ col = col_idx[k];
824 val[k] = DataType_(4);
825 else if(col+1 == row)
826 val[k] = DataType_(-1);
827 else if(col+m == row)
828 val[k] = DataType_(-1);
829 else if(col+m+1 == row)
830 val[k] = DataType_(-2);
847 const DataType_ c(
Math::cos(Math::pi<DataType_>() / DataType_(this->
_m+1)));
853 for(
Index i(0); i < this->
_d; ++i)
859 DataType_ y = DataType_(v);
860 for(
Index k(1); k < this->
_d; ++k)
862 (y *= c) += DataType_((v *= this->_d - k +
Index(1)) /= (
Index(2) * k));
865 return DataType_(a -
Index(1)) - c*y;
873 return DataType_(8) + DataType_(4)*
Math::sqr(
Math::cos(Math::pi<DataType_>() / DataType_(this->
_m+1)));
883 template<
typename DataType_,
typename IndexType_>
895 const std::vector<DataType_> & dimensions) :
980 template<
typename DataType_,
typename IndexType_>
994 const std::vector<DataType_> & dimensions) :
1009 const IndexType_ d(IndexType_(this->
_d));
1011 const DataType_ *
const pdim(this->
_dimensions.data());
1017 const IndexType_ neq(IndexType_(matrix.
rows()));
1018 DataType_ *
const pval(matrix.
val());
1024 DataType_ diagonal_entry(0);
1025 for (IndexType_ i(0); i < d; ++i)
1027 diagonal_entry += DataType_(2.0) *
Math::sqr(pdim[i] / DataType_(pnos[i + 1]));
1031 for (IndexType_ i(0); i < neq; ++i)
1033 pval[neq * d + i] = diagonal_entry;
1037 for (IndexType_ i(0), k(pnos[0] - 1); i < d; ++i, k *= pnos[i] - 1)
1039 const DataType_ subdiagonal_entry(-
Math::sqr(pdim[i] / DataType_(pnos[i + 1])));
1041 for (IndexType_ j(0); j < neq / k / (pnos[i + 1] - 1); ++j)
1043 const IndexType_ k1(neq * d + k * (pnos[i + 1] - 1) * j);
1044 const IndexType_ k2(neq * (i + 1));
1048 for (IndexType_ l(pnos[i] - 1); l > 0; --l)
1050 pval[k1 + k2 - l] = DataType_(0);
1051 pval[k1 - k2 - l + k] = DataType_(0);
1055 for (IndexType_ l(0); l < k * (pnos[i + 1] - 2); ++l)
1057 pval[k1 + l + k2] = subdiagonal_entry;
1058 pval[k1 + l - k2 + k] = subdiagonal_entry;
1079 DataType_ x(DataType_(0.0));
1081 const DataType_ *
const pdim(this->
_dimensions.data());
1083 for (
Index i(0); i < this->
_d; ++i)
1085 const DataType_ h(pdim[i] / DataType_(pnos[i + 1]));
1086 x +=
Math::sqr(h) * (DataType_(1.0) -
Math::cos(Math::pi<DataType_>() * h / pdim[i]));
1089 return DataType_(2) * x;
1104 DataType_ x(DataType_(0.0));
1106 const DataType_ *
const pdim(this->
_dimensions.data());
1108 for (
Index i(0); i < this->
_d; ++i)
1110 const DataType_ h(pdim[i] / DataType_(pnos[i + 1]));
1111 x +=
Math::sqr(h) * (DataType_(1.0) +
Math::cos(Math::pi<DataType_>() * h / pdim[i]));
1114 return DataType_(2) * x;
1124 for (
Index i(1); i <= d; ++i)
1126 size *= pnos[i] - 1;
1133 for(
Index i(0); i < size; ++i)
1135 for(
Index j(0), quo(1); j < d; ++j, quo *= pnos[j] - 1)
1138 const DataType_ xsf(Math::pi<DataType_>() / DataType_(pnos[j + 1]));
1139 v[i] *=
Math::sin(xsf * DataType_(((i / quo) % (pnos[j + 1] - 1)) +
Index(1)));
1160 const DataType_ *
const pdim(this->
_dimensions.data());
1164 for (
Index i(1); i <= d; ++i)
1166 size *= pnos[i] - 1;
1173 for(
Index i(0); i < size; ++i)
1175 for(
Index j(0), quo(1); j < d; ++j, quo *= pnos[j] - 1)
1178 const DataType_ xsf(pdim[j] / DataType_(pnos[j + 1]));
1181 DataType_ x(xsf * DataType_(((i / quo) % (pnos[j + 1] - 1)) +
Index(1)));
1183 v[i] *= DataType_(4) * x * (DataType_(1) - x);
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Dense data vector class template.
DT_ * elements()
Get a pointer to the data array.
Pointstar factory base class.
virtual DenseVector< DataType_, IndexType_ > eigenvector_min() const =0
Computes the eigenvector of the smallest eigenvalue.
virtual DataType_ lambda_min() const =0
Computes the smallest eigenvalue of the pointstar matrix.
virtual DenseVector< DataType_, IndexType_ > vector_q2_bubble() const =0
Computes a Q2-bubble vector.
const std::vector< DataType_ > & _dimensions
vector with lengths of the n-dimensional hypercube
virtual DataType_ lambda_max() const =0
Computes the largest eigenvalue of the pointstar matrix.
virtual DataType_ spectral_cond() const
Computes the spectral condition number of the pointstar matrix.
const Index _d
number of dimensions
const std::vector< IndexType_ > & _num_of_subintervalls
vector with number of subintervalls per dimension (plus a leading 2).
virtual SparseMatrixBanded< DataType_, IndexType_ > matrix_banded() const =0
Computes the pointstar matrix in banded format.
Pointstar factory base class.
virtual DataType_ lambda_max() const =0
Computes the largest eigenvalue of the pointstar matrix.
Index _m
number of inner nodes per dimension
Index _d
number of dimensions
virtual SparseMatrixCSR< DataType_, IndexType_ > matrix_csr() const =0
Computes the pointstar matrix in CSR format.
DenseVector< DataType_, IndexType_ > vector_q2_bubble() const
Computes a Q2-bubble vector.
virtual DataType_ spectral_cond() const
Computes the spectral condition number of the pointstar matrix.
virtual DenseVector< DataType_, IndexType_ > eigenvector_min() const
Computes the eigenvector of the smallest eigenvalue.
virtual DataType_ lambda_min() const =0
Computes the smallest eigenvalue of the pointstar matrix.
Finite-Differences pointstar matrix factory.
DenseVector< DataType_, IndexType_ > vector_q2_bubble() const override
Computes a Q2-bubble vector.
virtual DataType_ lambda_min() const override
Computes the smallest eigenvalue of the FD-style matrix.
virtual SparseMatrixBanded< DataType_, IndexType_ > matrix_banded() const override
Generates a FD-style pointstar banded matrix.
virtual DataType_ lambda_max() const override
Computes the largest eigenvalue of the FD-style matrix.
virtual DenseVector< DataType_, IndexType_ > eigenvector_min() const override
Computes the eigenvector of the smallest eigenvalue.
PointstarFactoryFD2(const std::vector< IndexType_ > &num_of_subintervalls, const std::vector< DataType_ > &dimensions)
Creates the pointstar factory.
Finite-Differences pointstar matrix factory.
virtual DataType_ lambda_max() const override
Computes the largest eigenvalue of the FD-style matrix.
PointstarFactoryFD(Index m, Index d=Index(2))
Creates the pointstar factory.
virtual DataType_ lambda_min() const override
Computes the smallest eigenvalue of the FD-style matrix.
virtual SparseMatrixCSR< DataType_, IndexType_ > matrix_csr() const override
Generates a FD-style pointstar CSR matrix.
Finite-Element pointstar matrix factory.
virtual DataType_ lambda_min() const override
Computes the smallest eigenvalue of the FE-style matrix.
PointstarFactoryFE(Index m)
Creates the pointstar factory.
virtual SparseMatrixCSR< DataType_, IndexType_ > matrix_csr_neumann() const
Generates a FE-style pointstar CSR matrix with Neumann boundaries.
virtual SparseMatrixCSR< DataType_, IndexType_ > matrix_csr() const override
Generates a FE-style pointstar CSR matrix.
virtual DataType_ lambda_max() const override
Computes the largest eigenvalue of the FE-style matrix.
Index rows() const
Retrieve matrix row count.
DT_ * val()
Retrieve element array.
IT_ * col_ind()
Retrieve column indices array.
DT_ * val()
Retrieve non zero element array.
IT_ * row_ptr()
Retrieve row start index array.
T_ sin(T_ x)
Returns the sine of a value.
T_ sqr(T_ x)
Returns the square of a value.
T_ cos(T_ x)
Returns the cosine of a value.
std::uint64_t Index
Index data type.