MCPcopy Create free account
hub / github.com/IBAMR/IBAMR / factorizeDenseMatrix

Method factorizeDenseMatrix

src/IB/DirectMobilitySolver.cpp:602–694  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

600} // factorizeBodyMobilityMatrix
601
602void
603DirectMobilitySolver::factorizeDenseMatrix(double* mat_data,
604 const int mat_size,
605 const MobilityMatrixInverseType& inv_type,
606 int* ipiv,
607 const std::string& mat_name,
608 const std::string& err_msg)
609{
610 using MatrixType = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::ColMajor>;
611 Eigen::Map<MatrixType> mat_view(mat_data, Eigen::Index(mat_size), Eigen::Index(mat_size));
612
613 if (inv_type != LAPACK_LU)
614 {
615 // For compatibility with the old code, we copy the lower triangle into
616 // the upper triangle, even if they aren't actually equal
617 for (int i = 0; i < mat_size; ++i)
618 {
619 for (int j = i + 1; j < mat_size; ++j)
620 {
621 mat_view(i, j) = mat_view(j, i);
622 }
623 }
624 }
625
626 if (inv_type == LAPACK_CHOLESKY)
627 {
628 Eigen::LLT<MatrixType> cholesky_factorization(mat_view);
629 mat_view = cholesky_factorization.matrixL();
630 }
631 else if (inv_type == LAPACK_LU)
632 {
633 Eigen::PartialPivLU<MatrixType> plu_factorization(mat_view);
634 mat_view = plu_factorization.matrixLU();
635 const auto& indices = plu_factorization.permutationP().indices();
636 TBOX_ASSERT(indices.rows() * indices.cols() == mat_size);
637 std::copy_n(indices.data(), mat_size, ipiv);
638 }
639 else if (inv_type == LAPACK_SVD)
640 {
641 // Use the symmetric eigenvalue decomposition as a stand-in for the SVD.
642 // In particular, since A = V D V^T, where V is the matrix of eigenvectors
643 // and D is the matrix of eigenvalues, we can factorize A as
644 //
645 // A = V sqrt(D) sqrt(D) V^T
646 // = V sqrt(D) (V sqrt(D))^T
647 //
648 // and instead store A <- V sqrt(D)
649 Eigen::SelfAdjointEigenSolver<MatrixType> eigensolver(mat_view);
650 Eigen::Matrix<double, Eigen::Dynamic, 1> eigenvalues = eigensolver.eigenvalues();
651 const MatrixType eigenvectors = eigensolver.eigenvectors();
652 // Make negative eigenvalues to be equal to min eigen value from
653 // input option
654 int counter = 0, counter_zero = 0;
655 for (int i = 0; i < mat_size; ++i)
656 {
657 if (eigenvalues[i] < d_svd_eps)
658 {
659 eigenvalues[i] = d_svd_replace_value;

Callers

nothing calls this directly

Calls 11

copy_nFunction · 0.85
abs_equal_epsFunction · 0.85
indicesMethod · 0.80
IndexClass · 0.50
sqrtFunction · 0.50
matrixLMethod · 0.45
rowsMethod · 0.45
colsMethod · 0.45
dataMethod · 0.45
eigenvaluesMethod · 0.45
eigenvectorsMethod · 0.45

Tested by

no test coverage detected