Make function that infers templates, avoid use of new

This commit is contained in:
Tobias Meyer Andersen
2024-04-16 15:39:17 +02:00
parent 9e7b7b3e40
commit 296f41ecc0
2 changed files with 18 additions and 19 deletions

View File

@@ -177,7 +177,7 @@ struct StandardPreconditioners {
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&, const int, const double, const bool>>( return wrapBlockPreconditioner<RebuildOnUpdatePreconditioner<Dune::SeqILU<M, V, V>>>(
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) {
@@ -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&, const int, const double, const bool>(op.getmat(), n, w, resort); return getRebuildOnUpdateWrapper<Dune::SeqILU<M, V, V>>(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);
@@ -523,7 +523,7 @@ struct StandardPreconditioners<Operator, Dune::Amg::SequentialInformation> {
Dune::Amg::Parameters parms; Dune::Amg::Parameters parms;
parms.setNoPreSmoothSteps(1); parms.setNoPreSmoothSteps(1);
parms.setNoPostSmoothSteps(1); parms.setNoPostSmoothSteps(1);
return getRebuildOnUpdateWrapper<Dune::Amg::FastAMG<O, V>, O, decltype(crit), decltype(parms)>(op, crit, parms); return getRebuildOnUpdateWrapper<Dune::Amg::FastAMG<O, V>>(op, crit, parms);
}); });
} }
if constexpr (std::is_same_v<O, WellModelMatrixAdapter<M, V, V, false>>) { if constexpr (std::is_same_v<O, WellModelMatrixAdapter<M, V, V, false>>) {

View File

@@ -99,32 +99,34 @@ struct GeneralPreconditionerMaker {
/// @tparam ...Args - All arguments needed to construct the preconditioner of choice /// @tparam ...Args - All arguments needed to construct the preconditioner of choice
template <class OriginalPreconditioner, class... Args> template <class OriginalPreconditioner, class... Args>
struct PreconditionerMaker : public GeneralPreconditionerMaker<OriginalPreconditioner> { struct PreconditionerMaker : public GeneralPreconditionerMaker<OriginalPreconditioner> {
using GenericPreconditioner = Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>;
PreconditionerMaker(Args&&... args) PreconditionerMaker(Args&&... args)
: args_(args...) : args_(args...)
{ {
} }
std::unique_ptr< std::unique_ptr<GenericPreconditioner>
Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>>
make() override make() override
{ {
return std::unique_ptr< // return std::unique_ptr<GenericPreconditioner> {new auto(std::make_from_tuple<OriginalPreconditioner>(args_))};
Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>> { return std::apply(
new auto(std::make_from_tuple<OriginalPreconditioner>(args_))}; [](auto&&... args) {
return std::make_unique<OriginalPreconditioner>(std::forward<Args>(args)...);
}, args_);
} }
std::tuple<Args...> args_; std::tuple<Args...> args_;
}; };
/// @brief Wrapper class of preconditioners that should be reconstructed on update /// @brief Wrapper class of preconditioners that should be reconstructed on update
/// @tparam OriginalPreconditioner - Preconditioner of your choice /// @tparam OriginalPreconditioner - Preconditioner of your choice
/// @tparam ...Args - All arguments neededc to construct the preconditioner of choice template <class OriginalPreconditioner>
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:
template<class... Args>
RebuildOnUpdatePreconditioner(Args... args) RebuildOnUpdatePreconditioner(Args... args)
: preconditioner_params_(args...) : preconditioner_maker_(std::make_unique<PreconditionerMaker<OriginalPreconditioner, Args...>>(std::forward<Args>(args)...))
, preconditioner_maker_(std::make_unique<ConcreteMakerType>(std::forward<Args>(args)...))
{ {
update(); update();
} }
@@ -160,13 +162,10 @@ public:
private: private:
using AbstractMakerType = GeneralPreconditionerMaker<OriginalPreconditioner>; using AbstractMakerType = GeneralPreconditionerMaker<OriginalPreconditioner>;
using ConcreteMakerType = PreconditionerMaker<OriginalPreconditioner, Args...>; using GenericPreconditioner = Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>;
std::tuple<Args...> preconditioner_params_;
std::unique_ptr<AbstractMakerType> preconditioner_maker_; std::unique_ptr<AbstractMakerType> preconditioner_maker_;
std::unique_ptr< std::unique_ptr<GenericPreconditioner> orig_precond_;
Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>>
orig_precond_;
}; };
/// @brief Wrapper function creating and return a shared pointer to a preconditioner which is reconstructed on update /// @brief Wrapper function creating and return a shared pointer to a preconditioner which is reconstructed on update
@@ -175,10 +174,10 @@ private:
/// @param ...args - Arguments needed to construct the preconditioner of choice /// @param ...args - Arguments needed to construct the preconditioner of choice
/// @return Shared pointer to preconditioner which has an update function that reconstrcuts the preconditioner /// @return Shared pointer to preconditioner which has an update function that reconstrcuts the preconditioner
template <class OriginalPreconditioner, class... Args> template <class OriginalPreconditioner, class... Args>
std::shared_ptr<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Args...>> auto
getRebuildOnUpdateWrapper(Args... args) getRebuildOnUpdateWrapper(Args... args)
{ {
return std::make_shared<RebuildOnUpdatePreconditioner<OriginalPreconditioner, Args...>>( return std::make_shared<RebuildOnUpdatePreconditioner<OriginalPreconditioner>>(
std::forward<Args>(args)...); std::forward<Args>(args)...);
} }