diff --git a/opm/simulators/linalg/FlexibleSolver.hpp b/opm/simulators/linalg/FlexibleSolver.hpp index e1fb930e9..aea5f105e 100644 --- a/opm/simulators/linalg/FlexibleSolver.hpp +++ b/opm/simulators/linalg/FlexibleSolver.hpp @@ -105,10 +105,12 @@ private: { // Parallel case. using ParOperatorType = Dune::OverlappingSchwarzOperator; + using pt = const boost::property_tree::ptree; auto linop = std::make_shared(matrix, comm); linearoperator_ = linop; + auto child = prm.get_child_optional("preconditioner"); preconditioner_ - = Opm::PreconditionerFactory::create(*linop, prm.get_child("preconditioner"), + = Opm::PreconditionerFactory::create(*linop, child? *child : pt(), weightsCalculator, comm); scalarproduct_ = Dune::createScalarProduct(comm, linearoperator_->category()); } @@ -118,19 +120,21 @@ private: { // Sequential case. using SeqOperatorType = Dune::MatrixAdapter; + using pt = const boost::property_tree::ptree; auto linop = std::make_shared(matrix); linearoperator_ = linop; - preconditioner_ = Opm::PreconditionerFactory::create(*linop, prm.get_child("preconditioner"), + auto child = prm.get_child_optional("preconditioner"); + preconditioner_ = Opm::PreconditionerFactory::create(*linop, child? *child : pt(), weightsCalculator); scalarproduct_ = std::make_shared>(); } void initSolver(const boost::property_tree::ptree& prm) { - const double tol = prm.get("tol"); - const int maxiter = prm.get("maxiter"); - const int verbosity = prm.get("verbosity"); - const std::string solver_type = prm.get("solver"); + const double tol = prm.get("tol", 1e-2); + const int maxiter = prm.get("maxiter", 200); + const int verbosity = prm.get("verbosity", 0); + const std::string solver_type = prm.get("solver", "bicgstab"); if (solver_type == "bicgstab") { linsolver_.reset(new Dune::BiCGSTABSolver(*linearoperator_, *scalarproduct_, @@ -146,7 +150,7 @@ private: maxiter, // maximum number of iterations verbosity)); } else if (solver_type == "gmres") { - int restart = prm.get("restart"); + int restart = prm.get("restart", 15); linsolver_.reset(new Dune::RestartedGMResSolver(*linearoperator_, *scalarproduct_, *preconditioner_, diff --git a/opm/simulators/linalg/ISTLSolverEbosFlexible.hpp b/opm/simulators/linalg/ISTLSolverEbosFlexible.hpp index 04a0cc853..50e3d3b4b 100644 --- a/opm/simulators/linalg/ISTLSolverEbosFlexible.hpp +++ b/opm/simulators/linalg/ISTLSolverEbosFlexible.hpp @@ -153,30 +153,33 @@ public: std::function weightsCalculator; - if( prm_.get("preconditioner.type") == "cpr" || - prm_.get("preconditioner.type") == "cprt" + auto preconditionerType = prm_.get("preconditioner.type", "cpr"); + if( preconditionerType == "cpr" || + preconditionerType == "cprt" ) { bool transpose = false; - if(prm_.get("preconditioner.type") == "cprt"){ + if(preconditionerType == "cprt"){ transpose = true; } - if(prm_.get("preconditioner.weight_type") == "quasiimpes") { + auto weightsType = prm_.get("preconditioner.weight_type", "quasiimpes"); + auto pressureIndex = this->prm_.get("preconditioner.pressure_var_index", 1); + if(weightsType == "quasiimpes") { // weighs will be created as default in the solver weightsCalculator = - [&mat, this, transpose](){ + [&mat, this, transpose, pressureIndex](){ return Opm::Amg::getQuasiImpesWeights( mat.istlMatrix(), - this->prm_.get("preconditioner.pressure_var_index"), + pressureIndex, transpose); }; - }else if(prm_.get("preconditioner.weight_type") == "trueimpes" ){ + }else if(weightsType == "trueimpes" ){ weightsCalculator = - [this, &b](){ - return this->getTrueImpesWeights(b, this->prm_.get("preconditioner.pressure_var_index")); + [this, &b, pressureIndex](){ + return this->getTrueImpesWeights(b, pressureIndex); }; }else{ throw std::runtime_error("no such weights implemented for cpr"); diff --git a/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp b/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp index 473596365..1fcd0a702 100644 --- a/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp +++ b/opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp @@ -87,22 +87,24 @@ public: OwningTwoLevelPreconditioner(const OperatorType& linearoperator, const pt& prm, const std::function weightsCalculator) : linear_operator_(linearoperator) - , finesmoother_(PrecFactory::create(linearoperator, prm.get_child("finesmoother"))) + , finesmoother_(PrecFactory::create(linearoperator, + prm.get_child_optional("finesmoother")? + prm.get_child("finesmoother"): pt())) , comm_(nullptr) , weightsCalculator_(weightsCalculator) , weights_(weightsCalculator()) , levelTransferPolicy_(dummy_comm_, weights_, prm.get("pressure_var_index")) - , coarseSolverPolicy_(prm.get_child("coarsesolver")) + , coarseSolverPolicy_(prm.get_child_optional("coarsesolver")? prm.get_child("coarsesolver") : pt()) , twolevel_method_(linearoperator, finesmoother_, levelTransferPolicy_, coarseSolverPolicy_, - prm.get("pre_smooth"), - prm.get("post_smooth")) + prm.get("pre_smooth", transpose? 1 : 0), + prm.get("post_smooth", transpose? 0 : 1)) , prm_(prm) { - if (prm.get("verbosity") > 10) { - std::ofstream outfile(prm.get("weights_filename")); + if (prm.get("verbosity", 0) > 10) { + std::ofstream outfile(prm.get("weights_filename", "impes_weights.txt")); if (!outfile) { throw std::runtime_error("Could not write weights"); } @@ -113,24 +115,26 @@ public: OwningTwoLevelPreconditioner(const OperatorType& linearoperator, const pt& prm, const std::function weightsCalculator, const Communication& comm) : linear_operator_(linearoperator) - , finesmoother_(PrecFactory::create(linearoperator, prm.get_child("finesmoother"), comm)) + , finesmoother_(PrecFactory::create(linearoperator, + prm.get_child_optional("finesmoother")? + prm.get_child("finesmoother"): pt(), comm)) , comm_(&comm) , weightsCalculator_(weightsCalculator) , weights_(weightsCalculator()) - , levelTransferPolicy_(*comm_, weights_, prm.get("pressure_var_index")) - , coarseSolverPolicy_(prm.get_child("coarsesolver")) + , levelTransferPolicy_(*comm_, weights_, prm.get("pressure_var_index", 1)) + , coarseSolverPolicy_(prm.get_child_optional("coarsesolver")? prm.get_child("coarsesolver") : pt()) , twolevel_method_(linearoperator, finesmoother_, levelTransferPolicy_, coarseSolverPolicy_, - transpose ? 1 : 0, - transpose ? 0 : 1) + prm.get("pre_smooth", transpose? 1 : 0), + prm.get("post_smooth", transpose? 0 : 1)) , prm_(prm) { //Opm::Amg::getQuasiImpesWeights( // linearoperator.getmat(), prm.get("pressure_var_index"), transpose)) - if (prm.get("verbosity") > 10) { - std::ofstream outfile(prm.get("weights_filename")); + if (prm.get("verbosity", 0) > 10) { + std::ofstream outfile(prm.get("weights_filename", "impes_weights.txt")); if (!outfile) { throw std::runtime_error("Could not write weights"); } @@ -185,14 +189,16 @@ private: void updateImpl(const Comm*) { // Parallel case. - finesmoother_ = PrecFactory::create(linear_operator_, prm_.get_child("finesmoother"), *comm_); + auto child = prm_.get_child_optional("finesmoother"); + finesmoother_ = PrecFactory::create(linear_operator_, child ? *child : pt(), *comm_); twolevel_method_.updatePreconditioner(finesmoother_, coarseSolverPolicy_); } void updateImpl(const Dune::Amg::SequentialInformation*) { // Serial case. - finesmoother_ = PrecFactory::create(linear_operator_, prm_.get_child("finesmoother")); + auto child = prm_.get_child_optional("finesmoother"); + finesmoother_ = PrecFactory::create(linear_operator_, child ? *child : pt()); twolevel_method_.updatePreconditioner(finesmoother_, coarseSolverPolicy_); } diff --git a/opm/simulators/linalg/PreconditionerFactory.hpp b/opm/simulators/linalg/PreconditionerFactory.hpp index daea622cf..195279897 100644 --- a/opm/simulators/linalg/PreconditionerFactory.hpp +++ b/opm/simulators/linalg/PreconditionerFactory.hpp @@ -125,15 +125,15 @@ private: // Helpers for creation of AMG preconditioner. static Criterion amgCriterion(const boost::property_tree::ptree& prm) { - Criterion criterion(15, prm.get("coarsenTarget")); + Criterion criterion(15, prm.get("coarsenTarget", 1200)); criterion.setDefaultValuesIsotropic(2); - criterion.setAlpha(prm.get("alpha")); - criterion.setBeta(prm.get("beta")); - criterion.setMaxLevel(prm.get("maxlevel")); - criterion.setSkipIsolated(prm.get("skip_isolated")); - criterion.setNoPreSmoothSteps(prm.get("pre_smooth")); - criterion.setNoPostSmoothSteps(prm.get("post_smooth")); - criterion.setDebugLevel(prm.get("verbosity")); + criterion.setAlpha(prm.get("alpha", 0.33)); + criterion.setBeta(prm.get("beta", 1e-5)); + criterion.setMaxLevel(prm.get("maxlevel", 15)); + criterion.setSkipIsolated(prm.get("skip_isolated", false)); + criterion.setNoPreSmoothSteps(prm.get("pre_smooth", 1)); + criterion.setNoPostSmoothSteps(prm.get("post_smooth", 1)); + criterion.setDebugLevel(prm.get("verbosity", 0)); return criterion; } @@ -142,11 +142,11 @@ private: { using SmootherArgs = typename Dune::Amg::SmootherTraits::Arguments; SmootherArgs smootherArgs; - smootherArgs.iterations = prm.get("iterations"); + smootherArgs.iterations = prm.get("iterations", 1); // smootherArgs.overlap=SmootherArgs::vertex; // smootherArgs.overlap=SmootherArgs::none; // smootherArgs.overlap=SmootherArgs::aggregate; - smootherArgs.relaxationFactor = prm.get("relaxation"); + smootherArgs.relaxationFactor = prm.get("relaxation", 0.9); return smootherArgs; } @@ -161,8 +161,8 @@ private: Dune::Amg::KAMG< Operator, Vector, Smoother> > >(op, crit, sargs, - prm.get("max_krylov"), - prm.get("min_reduction") ); + prm.get("max_krylov", 1), + prm.get("min_reduction", 1e-1) ); }else{ return std::make_shared>(op, crit, sargs); } @@ -181,45 +181,45 @@ private: using P = boost::property_tree::ptree; using C = Comm; doAddCreator("ILU0", [](const O& op, const P& prm, const std::function&, const C& comm) { - const double w = prm.get("relaxation"); + const double w = prm.get("relaxation", 1.0); return std::make_shared>( op.getmat(), comm, 0, w, Opm::MILU_VARIANT::ILU); }); doAddCreator("ParOverILU0", [](const O& op, const P& prm, const std::function&, const C& comm) { - const double w = prm.get("relaxation"); + const double w = prm.get("relaxation", 1.0); // Already a parallel preconditioner. Need to pass comm, but no need to wrap it in a BlockPreconditioner. return std::make_shared>( op.getmat(), comm, 0, w, Opm::MILU_VARIANT::ILU); }); doAddCreator("ILUn", [](const O& op, const P& prm, const std::function&, const C& comm) { - const int n = prm.get("ilulevel"); - const double w = prm.get("relaxation"); + const int n = prm.get("ilulevel", 0); + const double w = prm.get("relaxation", 1.0); return std::make_shared>( op.getmat(), comm, n, w, Opm::MILU_VARIANT::ILU); }); doAddCreator("Jac", [](const O& op, const P& prm, const std::function&, const C& comm) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapBlockPreconditioner>>(comm, op.getmat(), n, w); }); doAddCreator("GS", [](const O& op, const P& prm, const std::function&, const C& comm) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapBlockPreconditioner>>(comm, op.getmat(), n, w); }); doAddCreator("SOR", [](const O& op, const P& prm, const std::function&, const C& comm) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapBlockPreconditioner>>(comm, op.getmat(), n, w); }); doAddCreator("SSOR", [](const O& op, const P& prm, const std::function&, const C& comm) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapBlockPreconditioner>>(comm, op.getmat(), n, w); }); doAddCreator("amg", [](const O& op, const P& prm, const std::function&, const C& comm) { - const std::string smoother = prm.get("smoother"); + const std::string smoother = prm.get("smoother", "ParOverILU0"); if (smoother == "ILU0" || smoother == "ParOverILU0") { using Smoother = Opm::ParallelOverlappingILU0; auto crit = amgCriterion(prm); @@ -251,44 +251,44 @@ private: using V = Vector; using P = boost::property_tree::ptree; doAddCreator("ILU0", [](const O& op, const P& prm, const std::function&) { - const double w = prm.get("relaxation"); + const double w = prm.get("relaxation", 1.0); return std::make_shared>( op.getmat(), 0, w, Opm::MILU_VARIANT::ILU); }); doAddCreator("ParOverILU0", [](const O& op, const P& prm, const std::function&) { - const double w = prm.get("relaxation"); + const double w = prm.get("relaxation", 1.0); return std::make_shared>( op.getmat(), 0, w, Opm::MILU_VARIANT::ILU); }); doAddCreator("ILUn", [](const O& op, const P& prm, const std::function&) { - const int n = prm.get("ilulevel"); - const double w = prm.get("relaxation"); + const int n = prm.get("ilulevel", 0); + const double w = prm.get("relaxation", 1.0); return std::make_shared>( op.getmat(), n, w, Opm::MILU_VARIANT::ILU); }); doAddCreator("Jac", [](const O& op, const P& prm, const std::function&) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapPreconditioner>(op.getmat(), n, w); }); doAddCreator("GS", [](const O& op, const P& prm, const std::function&) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapPreconditioner>(op.getmat(), n, w); }); doAddCreator("SOR", [](const O& op, const P& prm, const std::function&) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapPreconditioner>(op.getmat(), n, w); }); doAddCreator("SSOR", [](const O& op, const P& prm, const std::function&) { - const int n = prm.get("repeats"); - const double w = prm.get("relaxation"); + const int n = prm.get("repeats", 1); + const double w = prm.get("relaxation", 1.0); return wrapPreconditioner>(op.getmat(), n, w); }); doAddCreator("amg", [](const O& op, const P& prm, const std::function&) { - const std::string smoother = prm.get("smoother"); - if (smoother == "ILU0") { + const std::string smoother = prm.get("smoother", "ParOverILU0"); + if (smoother == "ILU0" || smoother == "ParOverILU0") { #if DUNE_VERSION_NEWER(DUNE_ISTL, 2, 7) using Smoother = SeqILU; #else @@ -318,8 +318,8 @@ private: } }); doAddCreator("kamg", [](const O& op, const P& prm, const std::function&) { - const std::string smoother = prm.get("smoother"); - if (smoother == "ILU0") { + const std::string smoother = prm.get("smoother", "ParOverILU0"); + if (smoother == "ILU0" || smoother == "ParOverILU0") { using Smoother = SeqILU0; return makeAmgPreconditioner(op, prm, true); } else if (smoother == "Jac") { @@ -378,7 +378,7 @@ private: PrecPtr doCreate(const Operator& op, const boost::property_tree::ptree& prm, const std::function weightsCalculator) { - const std::string& type = prm.get("type"); + const std::string& type = prm.get("type", "ParOverILU0"); auto it = creators_.find(type); if (it == creators_.end()) { std::ostringstream msg; @@ -395,7 +395,7 @@ private: PrecPtr doCreate(const Operator& op, const boost::property_tree::ptree& prm, const std::function weightsCalculator, const Comm& comm) { - const std::string& type = prm.get("type"); + const std::string& type = prm.get("type", "ParOverILU0"); auto it = parallel_creators_.find(type); if (it == parallel_creators_.end()) { std::ostringstream msg;