Proof Of Concept generic Preconditioner with update

This commit is contained in:
Tobias Meyer Andersen 2024-04-15 15:22:42 +02:00
parent 4f53ea512b
commit e275c637f5
2 changed files with 76 additions and 25 deletions

View File

@ -173,13 +173,13 @@ struct StandardPreconditioners {
F::addCreator("ILUn", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) { F::addCreator("ILUn", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
return createParILU(op, prm, comm, prm.get<int>("ilulevel", 0)); return createParILU(op, prm, comm, prm.get<int>("ilulevel", 0));
}); });
F::addCreator("DuneILU", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) { // F::addCreator("DuneILU", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
const int n = prm.get<int>("ilulevel", 0); // const int n = prm.get<int>("ilulevel", 0);
const double w = prm.get<double>("relaxation", 1.0); // const double w = prm.get<double>("relaxation", 1.0);
const bool resort = prm.get<bool>("resort", false); // const bool resort = prm.get<bool>("resort", false);
return wrapBlockPreconditioner<RebuildOnUpdatePreconditioner<Dune::SeqILU<M, V, V>, const M&>>( // return wrapBlockPreconditioner<RebuildOnUpdatePreconditioner<Dune::SeqILU<M, V, V>, const M&>>(
comm, op.getmat(), n, w, resort); // comm, op.getmat(), n, w, resort);
}); // });
F::addCreator("DILU", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) { F::addCreator("DILU", [](const O& op, const P& prm, const std::function<V()>&, std::size_t, const C& comm) {
DUNE_UNUSED_PARAMETER(prm); DUNE_UNUSED_PARAMETER(prm);
return wrapBlockPreconditioner<MultithreadDILU<M, V, V>>(comm, op.getmat()); return wrapBlockPreconditioner<MultithreadDILU<M, V, V>>(comm, op.getmat());
@ -425,7 +425,7 @@ struct StandardPreconditioners<Operator, Dune::Amg::SequentialInformation> {
const double w = prm.get<double>("relaxation", 1.0); const double w = prm.get<double>("relaxation", 1.0);
const int n = prm.get<int>("ilulevel", 0); const int n = prm.get<int>("ilulevel", 0);
const bool resort = prm.get<bool>("resort", false); const bool resort = prm.get<bool>("resort", false);
return getRebuildOnUpdateWrapper<Dune::SeqILU<M, V, V>, const M&>(op.getmat(), n, w, resort); return getRebuildOnUpdateWrapper<Dune::SeqILU<M, V, V>, const M&, const int, const double, const bool>(op.getmat(), n, w, resort);
}); });
F::addCreator("ParOverILU0", [](const O& op, const P& prm, const std::function<V()>&, std::size_t) { F::addCreator("ParOverILU0", [](const O& op, const P& prm, const std::function<V()>&, std::size_t) {
const double w = prm.get<double>("relaxation", 1.0); const double w = prm.get<double>("relaxation", 1.0);

View File

@ -77,6 +77,48 @@ private:
OriginalPreconditioner orig_precond_; OriginalPreconditioner orig_precond_;
}; };
template <class OriginalPreconditioner>
struct AbstractPreconditionerWithUpdateMaker
{
virtual std::unique_ptr<Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>> make() = 0;
// virtual ~AbstractMaker() {};
};
template <class OriginalPreconditioner, class... Args>
struct PreconditionerMaker : public AbstractPreconditionerWithUpdateMaker<OriginalPreconditioner>
{
PreconditionerMaker(Args&&... args)
: args_(args...)
{
}
std::unique_ptr<Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>> make() override
{
return std::unique_ptr<Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>>{new auto(std::make_from_tuple<OriginalPreconditioner>(args_))};
}
std::tuple<Args...> args_;
};
// struct Contain
// {
// Contain()
// {
// }
// template <class Product, class... Args>
// void fill(Args&&... args)
// {
// using MakerType = Maker<Product, Args...>;
// maker = std::make_unique<MakerType>(std::forward<Args>(args)...);
// recreate();
// }
// void recreate()
// {
// product = maker->make();
// }
// std::unique_ptr<AbstractMaker> maker;
// std::unique_ptr<AbstractProduct> product;
// };
template <class OriginalPreconditioner, class... Args> template <class OriginalPreconditioner, class... Args>
std::shared_ptr<DummyUpdatePreconditioner<OriginalPreconditioner>> std::shared_ptr<DummyUpdatePreconditioner<OriginalPreconditioner>>
getDummyUpdateWrapper(Args&&... args) getDummyUpdateWrapper(Args&&... args)
@ -84,18 +126,16 @@ getDummyUpdateWrapper(Args&&... args)
return std::make_shared<DummyUpdatePreconditioner<OriginalPreconditioner>>(std::forward<Args>(args)...); return std::make_shared<DummyUpdatePreconditioner<OriginalPreconditioner>>(std::forward<Args>(args)...);
} }
template <class OriginalPreconditioner, class Matrix> template <class OriginalPreconditioner, class... Args>
class RebuildOnUpdatePreconditioner : public PreconditionerWithUpdate<typename OriginalPreconditioner::domain_type, class RebuildOnUpdatePreconditioner : public PreconditionerWithUpdate<typename OriginalPreconditioner::domain_type,
typename OriginalPreconditioner::range_type> typename OriginalPreconditioner::range_type>
{ {
public: public:
RebuildOnUpdatePreconditioner(const Matrix &mat, const int n, const double w, const bool resort) RebuildOnUpdatePreconditioner(Args... args)
: orig_precond_(std::make_unique<OriginalPreconditioner>(mat, n, w, resort)) : preconditioner_params_(args...),
, mat_(mat) preconditioner_maker_(std::make_unique<ConcreteMakerType>(std::forward<Args>(args)...))
, n_(n)
, w_(w)
, resort_(resort)
{ {
update();
} }
using X = typename OriginalPreconditioner::domain_type; using X = typename OriginalPreconditioner::domain_type;
@ -124,24 +164,35 @@ public:
// Rebuild the preconditioner on update // Rebuild the preconditioner on update
void update() override void update() override
{ {
orig_precond_ = std::make_unique<OriginalPreconditioner>(mat_, n_, w_, resort_); // orig_precond_ = std::make_unique<OriginalPreconditioner>(mat_, n_, w_, resort_);
orig_precond_ = preconditioner_maker_->make();
} }
private: private:
std::unique_ptr<OriginalPreconditioner> orig_precond_; using AbstractMakerType = AbstractPreconditionerWithUpdateMaker<OriginalPreconditioner>;
const Matrix &mat_; using ConcreteMakerType = PreconditionerMaker<OriginalPreconditioner, Args...>;
const int n_;
const double w_; std::tuple<Args...> preconditioner_params_;
const bool resort_; std::unique_ptr<AbstractMakerType> preconditioner_maker_;
// std::unique_ptr<ConcreteMakerType> preconditioner_maker_;
// std::unique_ptr<OriginalPreconditioner> orig_precond_;
std::unique_ptr<Preconditioner<typename OriginalPreconditioner::domain_type,typename OriginalPreconditioner::range_type>> orig_precond_;
}; };
template <class OriginalPreconditioner, class Matrix> template <class OriginalPreconditioner, class... Args>
std::shared_ptr<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Matrix>> std::shared_ptr<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Args...>>
getRebuildOnUpdateWrapper(const Matrix &mat, const int n, const double w, const bool resort) getRebuildOnUpdateWrapper(Args... args)
{ {
return std::make_shared<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Matrix>>(mat, n, w, resort); return std::make_shared<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Args...>>(std::forward<Args>(args)...);
} }
// template <class OriginalPreconditioner, class Matrix>
// std::shared_ptr<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Matrix>>
// getRebuildOnUpdateWrapper(const Matrix &mat, const int n, const double w, const bool resort)
// {
// return std::make_shared<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Matrix>>(mat, n, w, resort);
// }
} // namespace Dune } // namespace Dune
#endif // OPM_PRECONDITIONERWITHUPDATE_HEADER_INCLUDED #endif // OPM_PRECONDITIONERWITHUPDATE_HEADER_INCLUDED