3#if HAVE_SUITESPARSE_CHOLMOD
33 explicit operator bool()
const {
return false; }
39 template<
class BlockedVector,
class FlatVector>
40 void copyToFlatVector(
const BlockedVector& blockedVector, FlatVector& flatVector)
44 flatVector.resize(len);
47 flatVector[offset] = entry;
52 template<
class FlatVector>
53 void copyToFlatVector(
const NoIgnore&, FlatVector&)
59 template<
class FlatVector,
class BlockedVector>
60 void copyToBlockedVector(
const FlatVector& flatVector, BlockedVector& blockedVector)
63 entry = flatVector[offset];
75class Cholmod :
public InverseOperator<Vector, Vector>
97 cholmod_free_factor(&L_, &c_);
102 Cholmod(
const Cholmod&) =
delete;
103 Cholmod&
operator=(
const Cholmod&) =
delete;
108 void apply (Vector& x, Vector& b, [[maybe_unused]]
double reduction, InverseOperatorResult& res)
118 void apply(Vector& x, Vector& b, InverseOperatorResult& res)
126 if (x.size() != b.size())
130 auto b2 = std::make_unique<double[]>(L_->n);
131 auto x2 = std::make_unique<double[]>(L_->n);
137 if ( subIndices_.empty() )
138 bp[ flatIndex ] = entry;
141 bp[ subIndices_[ flatIndex ] ] = entry;
145 auto b3 = make_cholmod_dense(cholmod_allocate_dense(L_->n, 1, L_->n, CHOLMOD_REAL, &c_), &c_);
147 auto b4 =
static_cast<double*
>(b3->x);
148 std::copy(b2.get(), b2.get() + L_->n, b4);
151 auto x3 = make_cholmod_dense(cholmod_solve(CHOLMOD_A, L_, b3.get(), &c_), &c_);
153 auto xp =
static_cast<double*
>(x3->x);
157 if ( subIndices_.empty() )
158 entry = xp[ flatIndex ];
161 entry = xp[ subIndices_[ flatIndex ] ];
166 res.converged =
true;
175 template<
class Matrix>
176 void setMatrix(
const Matrix& matrix)
178 const Impl::NoIgnore* noIgnore =
nullptr;
179 setMatrix(matrix, noIgnore);
196 template<
class Matrix,
class Ignore>
197 void setMatrix(
const Matrix& matrix,
const Ignore* ignore)
201 int numberOfIgnoredDofs = 0;
204 auto [flatRows,flatCols] =
flatMatrixForEach( matrix, [&](
auto&& ,
auto&& flatRowIndex,
auto&& flatColIndex){
205 if( flatRowIndex <= flatColIndex )
213 Impl::copyToFlatVector(*ignore,flatIgnore);
214 numberOfIgnoredDofs =
std::count(flatIgnore.begin(),flatIgnore.end(),
true);
218 int N = flatRows - numberOfIgnoredDofs;
232 const auto deleter = [c = &this->c_](
auto* p) {
233 cholmod_free_sparse(&p, c);
236 cholmod_allocate_sparse(
N,
247 int* Ap =
static_cast<int*
>(
M->p);
248 int* Ai =
static_cast<int*
>(
M->i);
249 double* Ax =
static_cast<double*
>(
M->x);
261 if ( not flatIgnore[ i ] )
263 subIndices_[ i ] = subIndexCounter++;
270 flatMatrixForEach(matrix, [&](
auto&& ,
auto&& flatRowIndex,
auto&& flatColIndex){
273 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )
277 if ( flatRowIndex > flatColIndex )
281 auto idx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;
288 for (
int i=0; i<
N; i++ )
297 flatMatrixForEach(matrix, [&](
auto&& entry,
auto&& flatRowIndex,
auto&& flatColIndex){
300 if ( ignore and ( flatIgnore[flatRowIndex] or flatIgnore[flatColIndex] ) )
304 if ( flatRowIndex > flatColIndex )
308 auto rowIdx = ignore ? subIndices_[flatRowIndex] : flatRowIndex;
309 auto colIdx = ignore ? subIndices_[flatColIndex] : flatColIndex;
310 auto rowStart = Ap[rowIdx];
311 auto rowPos = rowPosition[rowIdx];
312 Ai[ rowStart + rowPos ] = colIdx;
313 Ax[ rowStart + rowPos ] = entry;
314 rowPosition[rowIdx]++;
319 L_ = cholmod_analyze(
M.get(), &c_);
322 cholmod_factorize(
M.get(), L_, &c_);
325 virtual SolverCategory::Category category()
const
327 return SolverCategory::Category::sequential;
335 cholmod_common& cholmodCommonObject()
343 auto make_cholmod_dense(cholmod_dense* x, cholmod_common* c)
345 const auto deleter = [c](
auto* p) {
346 cholmod_free_dense(&p, c);
352 cholmod_factor* L_ =
nullptr;
355 bool nIsZero_ =
false;
361 struct CholmodCreator{
363 template<
int k>
struct isValidBlock<FieldVector<double,k>> :
std::true_type{};
364 template<
int k>
struct isValidBlock<FieldVector<float,k>> :
std::true_type{};
366 template<
class TL,
typename M>
373 auto solver = std::make_shared<Dune::Cholmod<D>>();
374 solver->setMatrix(
mat);
379 template<
typename TL,
typename M>
385 DUNE_THROW(UnsupportedType,
"Unsupported Type in Cholmod");
#define DUNE_REGISTER_DIRECT_SOLVER(name,...)
Definition solverregistry.hh:11
This file implements a vector space as a tensor product of a given vector space. The number of compon...
Implementation of the BCRSMatrix class.
Define general, extensible interface for inverse operators.
Matrix & mat
Definition matrixmatrix.hh:345
reference operator[](size_type i)
SLList< T, A > & operator=(const SLList< T, A > &other)
static constexpr size_type M()
static constexpr size_type N()
virtual void operator()()=0
std::pair< std::size_t, std::size_t > flatMatrixForEach(Matrix &&matrix, F &&f, std::size_t rowOffset=0, std::size_t colOffset=0)
Traverse a blocked matrix and call a functor at each scalar entry.
Definition foreach.hh:129
std::size_t flatVectorForEach(Vector &&vector, F &&f, std::size_t offset=0)
Traverse a blocked vector and call a functor at each scalar entry.
Definition foreach.hh:92