49 using MatrixBlock =
typename Dune::FieldMatrix<Scalar, 1, 1>;
50 using BCRSMatrix =
typename Dune::BCRSMatrix<MatrixBlock>;
62 const auto numRows = getNumRows_(A);
65 auto M = BCRSMatrix(numRows, numRows, BCRSMatrix::random);
68 setOccupationPattern_(M, A);
82 static void setOccupationPattern_(BCRSMatrix& M,
const MultiTypeBlockMatrix& A)
85 const auto numRows = M.N();
86 Dune::MatrixIndexSet occupationPattern;
87 occupationPattern.resize(numRows, numRows);
90 auto addIndices = [&occupationPattern](
const auto& subMatrix,
const std::size_t startRow,
const std::size_t startCol)
93 static const Scalar eps =
getParam<Scalar>(
"MatrixConverter.DeletePatternEntriesBelowAbsThreshold", -1.0);
95 using BlockType =
typename std::decay_t<
decltype(subMatrix)>::block_type;
96 const auto blockSizeI = BlockType::rows;
97 const auto blockSizeJ = BlockType::cols;
98 for(
auto row = subMatrix.begin(); row != subMatrix.end(); ++row)
99 for(
auto col = row->begin(); col != row->end(); ++col)
100 for(std::size_t i = 0; i < blockSizeI; ++i)
101 for(std::size_t j = 0; j < blockSizeJ; ++j)
102 if(abs(subMatrix[row.index()][col.index()][i][j]) > eps)
103 occupationPattern.add(startRow + row.index()*blockSizeI + i, startCol + col.index()*blockSizeJ + j);
107 std::size_t rowIndex = 0;
108 Dune::Hybrid::forEach(A, [&addIndices, &rowIndex, numRows](
const auto& rowOfMultiTypeMatrix)
110 std::size_t colIndex = 0;
111 Dune::Hybrid::forEach(rowOfMultiTypeMatrix, [&addIndices, &colIndex, &rowIndex, numRows](
const auto& subMatrix)
113 addIndices(subMatrix, rowIndex, colIndex);
115 using SubBlockType =
typename std::decay_t<
decltype(subMatrix)>::block_type;
117 colIndex += SubBlockType::cols * subMatrix.M();
120 if(colIndex == numRows)
121 rowIndex += SubBlockType::rows * subMatrix.N();
125 occupationPattern.exportIdx(M);
134 static void copyValues_(BCRSMatrix& M,
const MultiTypeBlockMatrix& A)
137 const auto numRows = M.N();
140 auto copyValues = [&M](
const auto& subMatrix,
const std::size_t startRow,
const std::size_t startCol)
143 static const Scalar
eps =
getParam<Scalar>(
"MatrixConverter.DeletePatternEntriesBelowAbsThreshold", -1.0);
145 using BlockType =
typename std::decay_t<
decltype(subMatrix)>::block_type;
146 const auto blockSizeI = BlockType::rows;
147 const auto blockSizeJ = BlockType::cols;
148 for (
auto row = subMatrix.begin(); row != subMatrix.end(); ++row)
149 for (
auto col = row->begin(); col != row->end(); ++col)
150 for (std::size_t i = 0; i < blockSizeI; ++i)
151 for (std::size_t j = 0; j < blockSizeJ; ++j)
152 if(abs(subMatrix[row.index()][col.index()][i][j]) > eps)
153 M[startRow + row.index()*blockSizeI + i][startCol + col.index()*blockSizeJ + j] = subMatrix[row.index()][col.index()][i][j];
157 std::size_t rowIndex = 0;
158 Dune::Hybrid::forEach(A, [©Values, &rowIndex, numRows](
const auto& rowOfMultiTypeMatrix)
160 std::size_t colIndex = 0;
161 Dune::Hybrid::forEach(rowOfMultiTypeMatrix, [©Values, &colIndex, &rowIndex, numRows](
const auto& subMatrix)
163 copyValues(subMatrix, rowIndex, colIndex);
165 using SubBlockType =
typename std::decay_t<
decltype(subMatrix)>::block_type;
167 colIndex += SubBlockType::cols * subMatrix.M();
170 if(colIndex == numRows)
171 rowIndex += SubBlockType::rows * subMatrix.N();
181 static std::size_t getNumRows_(
const MultiTypeBlockMatrix& A)
184 std::size_t numRows = 0;
185 Dune::Hybrid::forEach(Dune::Hybrid::elementAt(A, Dune::Indices::_0), [&numRows](
const auto& subMatrixInFirstRow)
188 const auto numEq = std::decay_t<
decltype(subMatrixInFirstRow)>::block_type::cols;
189 numRows += numEq * subMatrixInFirstRow.M();