Merge pull request #3365 from akva2/wrap_property_tree

Add Opm::PropertyTree
This commit is contained in:
Joakim Hove 2021-06-09 17:12:38 +02:00 committed by GitHub
commit fc5e2be4e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 370 additions and 246 deletions

View File

@ -43,6 +43,7 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/linalg/FlexibleSolver2.cpp
opm/simulators/linalg/FlexibleSolver3.cpp
opm/simulators/linalg/FlexibleSolver4.cpp
opm/simulators/linalg/PropertyTree.cpp
opm/simulators/linalg/setupPropertyTree.cpp
opm/simulators/utils/PartiallySupportedFlowKeywords.cpp
opm/simulators/utils/readDeck.cpp
@ -262,12 +263,12 @@ list (APPEND PUBLIC_HEADER_FILES
opm/simulators/linalg/PressureTransferPolicy.hpp
opm/simulators/linalg/PreconditionerFactory.hpp
opm/simulators/linalg/PreconditionerWithUpdate.hpp
opm/simulators/linalg/PropertyTree.hpp
opm/simulators/linalg/WellOperators.hpp
opm/simulators/linalg/WriteSystemMatrixHelper.hpp
opm/simulators/linalg/findOverlapRowsAndColumns.hpp
opm/simulators/linalg/getQuasiImpesWeights.hpp
opm/simulators/linalg/setupPropertyTree.hpp
opm/simulators/linalg/setupPropertyTree_impl.hpp
opm/simulators/timestepping/AdaptiveSimulatorTimer.hpp
opm/simulators/timestepping/AdaptiveTimeSteppingEbos.hpp
opm/simulators/timestepping/ConvergenceReport.hpp

View File

@ -23,12 +23,11 @@
#define OPM_FLEXIBLE_SOLVER_HEADER_INCLUDED
#include <opm/simulators/linalg/PreconditionerWithUpdate.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <dune/istl/solver.hh>
#include <dune/istl/paamg/pinfo.hh>
#include <boost/property_tree/ptree.hpp>
namespace Dune
{
@ -50,14 +49,14 @@ public:
/// Create a sequential solver.
FlexibleSolver(AbstractOperatorType& op,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()>& weightsCalculator = std::function<VectorType()>());
/// Create a parallel solver (if Comm is e.g. OwnerOverlapCommunication).
template <class Comm>
FlexibleSolver(AbstractOperatorType& op,
const Comm& comm,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()>& weightsCalculator = std::function<VectorType()>());
virtual void apply(VectorType& x, VectorType& rhs, Dune::InverseOperatorResult& res) override;
@ -75,20 +74,20 @@ private:
// Machinery for making sequential or parallel operators/preconditioners/scalar products.
template <class Comm>
void initOpPrecSp(AbstractOperatorType& op, const boost::property_tree::ptree& prm,
void initOpPrecSp(AbstractOperatorType& op, const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator, const Comm& comm);
void initOpPrecSp(AbstractOperatorType& op, const boost::property_tree::ptree& prm,
void initOpPrecSp(AbstractOperatorType& op, const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator, const Dune::Amg::SequentialInformation&);
void initSolver(const boost::property_tree::ptree& prm, const bool is_iorank);
void initSolver(const Opm::PropertyTree& prm, const bool is_iorank);
// Main initialization routine.
// Call with Comm == Dune::Amg::SequentialInformation to get a serial solver.
template <class Comm>
void init(AbstractOperatorType& op,
const Comm& comm,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator);
AbstractOperatorType* linearoperator_for_solver_;

View File

@ -32,15 +32,13 @@
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/istl/paamg/pinfo.hh>
#include <boost/property_tree/ptree.hpp>
namespace Dune
{
/// Create a sequential solver.
template <class MatrixType, class VectorType>
FlexibleSolver<MatrixType, VectorType>::
FlexibleSolver(AbstractOperatorType& op,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()>& weightsCalculator)
{
init(op, Dune::Amg::SequentialInformation(), prm, weightsCalculator);
@ -52,7 +50,7 @@ namespace Dune
FlexibleSolver<MatrixType, VectorType>::
FlexibleSolver(AbstractOperatorType& op,
const Comm& comm,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()>& weightsCalculator)
{
init(op, comm, prm, weightsCalculator);
@ -97,18 +95,17 @@ namespace Dune
void
FlexibleSolver<MatrixType, VectorType>::
initOpPrecSp(AbstractOperatorType& op,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator,
const Comm& comm)
{
// Parallel case.
using pt = const boost::property_tree::ptree;
using ParOperatorType = Dune::OverlappingSchwarzOperator<MatrixType, VectorType, VectorType, Comm>;
linearoperator_for_solver_ = &op;
auto op_prec = std::make_shared<ParOperatorType>(op.getmat(), comm);
auto child = prm.get_child_optional("preconditioner");
preconditioner_ = Opm::PreconditionerFactory<ParOperatorType, Comm>::create(*op_prec,
child ? *child : pt(),
child ? *child : Opm::PropertyTree(),
weightsCalculator,
comm);
scalarproduct_ = Dune::createScalarProduct<VectorType, Comm>(comm, op.category());
@ -119,18 +116,17 @@ namespace Dune
void
FlexibleSolver<MatrixType, VectorType>::
initOpPrecSp(AbstractOperatorType& op,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator,
const Dune::Amg::SequentialInformation&)
{
// Sequential case.
using pt = const boost::property_tree::ptree;
using SeqOperatorType = Dune::MatrixAdapter<MatrixType, VectorType, VectorType>;
linearoperator_for_solver_ = &op;
auto op_prec = std::make_shared<SeqOperatorType>(op.getmat());
auto child = prm.get_child_optional("preconditioner");
preconditioner_ = Opm::PreconditionerFactory<SeqOperatorType>::create(*op_prec,
child ? *child : pt(),
child ? *child : Opm::PropertyTree(),
weightsCalculator);
scalarproduct_ = std::make_shared<Dune::SeqScalarProduct<VectorType>>();
linearoperator_for_precond_ = op_prec;
@ -139,7 +135,7 @@ namespace Dune
template <class MatrixType, class VectorType>
void
FlexibleSolver<MatrixType, VectorType>::
initSolver(const boost::property_tree::ptree& prm, const bool is_iorank)
initSolver(const Opm::PropertyTree& prm, const bool is_iorank)
{
const double tol = prm.get<double>("tol", 1e-2);
const int maxiter = prm.get<int>("maxiter", 200);
@ -187,7 +183,7 @@ namespace Dune
FlexibleSolver<MatrixType, VectorType>::
init(AbstractOperatorType& op,
const Comm& comm,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator)
{
initOpPrecSp(op, prm, weightsCalculator, comm);
@ -219,11 +215,11 @@ template class Dune::FlexibleSolver<BM<N>, BV<N>>; \
template class Dune::FlexibleSolver<OBM<N>, BV<N>>; \
template Dune::FlexibleSolver<BM<N>, BV<N>>::FlexibleSolver(AbstractOperatorType& op, \
const Comm& comm, \
const boost::property_tree::ptree& prm, \
const Opm::PropertyTree& prm, \
const std::function<BV<N>()>& weightsCalculator); \
template Dune::FlexibleSolver<OBM<N>, BV<N>>::FlexibleSolver(AbstractOperatorType& op, \
const Comm& comm, \
const boost::property_tree::ptree& prm, \
const Opm::PropertyTree& prm, \
const std::function<BV<N>()>& weightsCalculator);
#else // HAVE_MPI

View File

@ -125,7 +125,10 @@ namespace Opm
comm_.reset( new CommunicationType( simulator_.vanguard().grid().comm() ) );
#endif
parameters_.template init<TypeTag>();
prm_ = setupPropertyTree<TypeTag>(parameters_);
prm_ = setupPropertyTree(parameters_,
EWOMS_PARAM_IS_SET(TypeTag, int, LinearSolverMaxIter),
EWOMS_PARAM_IS_SET(TypeTag, int, CprMaxEllIter));
#if HAVE_CUDA || HAVE_OPENCL || HAVE_FPGA
{
std::string accelerator_mode = EWOMS_GET_PARAM(TypeTag, std::string, AcceleratorMode);
@ -179,7 +182,7 @@ namespace Opm
if (on_io_rank) {
std::ostringstream os;
os << "Property tree for linear solver:\n";
boost::property_tree::write_json(os, prm_, true);
prm_.write_json(os, true);
OpmLog::note(os.str());
}
}
@ -420,10 +423,12 @@ namespace Opm
{
std::function<Vector()> weightsCalculator;
auto preconditionerType = prm_.get("preconditioner.type", "cpr");
using namespace std::string_literals;
auto preconditionerType = prm_.get("preconditioner.type"s, "cpr"s);
if (preconditionerType == "cpr" || preconditionerType == "cprt") {
const bool transpose = preconditionerType == "cprt";
const auto weightsType = prm_.get("preconditioner.weight_type", "quasiimpes");
const auto weightsType = prm_.get("preconditioner.weight_type"s, "quasiimpes"s);
const auto pressureIndex = this->prm_.get("preconditioner.pressure_var_index", 1);
if (weightsType == "quasiimpes") {
// weighs will be created as default in the solver
@ -511,7 +516,7 @@ namespace Opm
size_t interiorCellNum_;
FlowLinearSolverParameters parameters_;
boost::property_tree::ptree prm_;
PropertyTree prm_;
bool scale_variables_;
std::shared_ptr< CommunicationType > comm_;

View File

@ -28,8 +28,6 @@
#include <opm/common/ErrorMacros.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <memory>
#include <utility>
@ -99,7 +97,10 @@ public:
, interiorCellNum_(detail::numMatrixRowsToUseInSolver(simulator_.vanguard().grid(), ownersFirst_))
{
parameters_.template init<TypeTag>();
prm_ = setupPropertyTree<TypeTag>(parameters_);
prm_ = setupPropertyTree(parameters_,
EWOMS_PARAM_IS_SET(TypeTag, int, LinearSolverMaxIter),
EWOMS_PARAM_IS_SET(TypeTag, int, CprMaxEllIter));
extractParallelGridInformationToISTL(simulator_.vanguard().grid(), parallelInformation_);
// For some reason simulator_.model().elementMapper() is not initialized at this stage
// Hence const auto& elemMapper = simulator_.model().elementMapper(); does not work.
@ -120,7 +121,7 @@ public:
if (simulator.gridView().comm().rank() == 0) {
std::ostringstream os;
os << "Property tree for linear solver:\n";
boost::property_tree::write_json(os, prm_, true);
prm_.write_json(os, true);
OpmLog::note(os.str());
}
}
@ -263,10 +264,12 @@ protected:
{
std::function<VectorType()> weightsCalculator;
auto preconditionerType = prm_.get("preconditioner.type", "cpr");
using namespace std::string_literals;
auto preconditionerType = prm_.get("preconditioner.type", "cpr"s);
if (preconditionerType == "cpr" || preconditionerType == "cprt") {
const bool transpose = preconditionerType == "cprt";
const auto weightsType = prm_.get("preconditioner.weight_type", "quasiimpes");
const auto weightsType = prm_.get("preconditioner.weight_type", "quasiimpes"s);
const auto pressureIndex = this->prm_.get("preconditioner.pressure_var_index", 1);
if (weightsType == "quasiimpes") {
// weighs will be created as default in the solver
@ -337,7 +340,7 @@ protected:
std::unique_ptr<AbstractOperatorType> linear_operator_;
std::unique_ptr<SolverType> solver_;
FlowLinearSolverParameters parameters_;
boost::property_tree::ptree prm_;
PropertyTree prm_;
VectorType rhs_;
Dune::InverseOperatorResult res_;
std::any parallelInformation_;

View File

@ -32,8 +32,6 @@
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/paamg/amg.hh>
#include <boost/property_tree/ptree.hpp>
#include <fstream>
#include <type_traits>
@ -82,21 +80,20 @@ template <class OperatorType,
class OwningTwoLevelPreconditioner : public Dune::PreconditionerWithUpdate<VectorType, VectorType>
{
public:
using pt = boost::property_tree::ptree;
using MatrixType = typename OperatorType::matrix_type;
using PrecFactory = Opm::PreconditionerFactory<OperatorType, Communication>;
OwningTwoLevelPreconditioner(const OperatorType& linearoperator, const pt& prm,
OwningTwoLevelPreconditioner(const OperatorType& linearoperator, const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator)
: linear_operator_(linearoperator)
, finesmoother_(PrecFactory::create(linearoperator,
prm.get_child_optional("finesmoother")?
prm.get_child("finesmoother"): pt()))
prm.get_child_optional("finesmoother") ?
prm.get_child("finesmoother") : Opm::PropertyTree()))
, comm_(nullptr)
, weightsCalculator_(weightsCalculator)
, weights_(weightsCalculator())
, levelTransferPolicy_(dummy_comm_, weights_, prm.get<int>("pressure_var_index"))
, coarseSolverPolicy_(prm.get_child_optional("coarsesolver")? prm.get_child("coarsesolver") : pt())
, coarseSolverPolicy_(prm.get_child_optional("coarsesolver")? prm.get_child("coarsesolver") : Opm::PropertyTree())
, twolevel_method_(linearoperator,
finesmoother_,
levelTransferPolicy_,
@ -115,17 +112,17 @@ public:
}
}
OwningTwoLevelPreconditioner(const OperatorType& linearoperator, const pt& prm,
OwningTwoLevelPreconditioner(const OperatorType& linearoperator, const Opm::PropertyTree& prm,
const std::function<VectorType()> weightsCalculator, const Communication& comm)
: linear_operator_(linearoperator)
, finesmoother_(PrecFactory::create(linearoperator,
prm.get_child_optional("finesmoother")?
prm.get_child("finesmoother"): pt(), comm))
prm.get_child_optional("finesmoother") ?
prm.get_child("finesmoother"): Opm::PropertyTree(), comm))
, comm_(&comm)
, weightsCalculator_(weightsCalculator)
, weights_(weightsCalculator())
, levelTransferPolicy_(*comm_, weights_, prm.get<int>("pressure_var_index", 1))
, coarseSolverPolicy_(prm.get_child_optional("coarsesolver")? prm.get_child("coarsesolver") : pt())
, coarseSolverPolicy_(prm.get_child_optional("coarsesolver")? prm.get_child("coarsesolver") : Opm::PropertyTree())
, twolevel_method_(linearoperator,
finesmoother_,
levelTransferPolicy_,
@ -192,7 +189,7 @@ private:
{
// Parallel case.
auto child = prm_.get_child_optional("finesmoother");
finesmoother_ = PrecFactory::create(linear_operator_, child ? *child : pt(), *comm_);
finesmoother_ = PrecFactory::create(linear_operator_, child ? *child : Opm::PropertyTree(), *comm_);
twolevel_method_.updatePreconditioner(finesmoother_, coarseSolverPolicy_);
}
@ -200,7 +197,7 @@ private:
{
// Serial case.
auto child = prm_.get_child_optional("finesmoother");
finesmoother_ = PrecFactory::create(linear_operator_, child ? *child : pt());
finesmoother_ = PrecFactory::create(linear_operator_, child ? *child : Opm::PropertyTree());
twolevel_method_.updatePreconditioner(finesmoother_, coarseSolverPolicy_);
}
@ -212,7 +209,7 @@ private:
LevelTransferPolicy levelTransferPolicy_;
CoarseSolverPolicy coarseSolverPolicy_;
TwoLevelMethod twolevel_method_;
boost::property_tree::ptree prm_;
Opm::PropertyTree prm_;
Communication dummy_comm_;
};

View File

@ -26,6 +26,7 @@
#include <opm/simulators/linalg/OwningTwoLevelPreconditioner.hpp>
#include <opm/simulators/linalg/ParallelOverlappingILU0.hpp>
#include <opm/simulators/linalg/PreconditionerWithUpdate.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <opm/simulators/linalg/amgcpr.hh>
#include <dune/istl/paamg/amg.hh>
@ -33,8 +34,6 @@
#include <dune/istl/paamg/fastamg.hh>
#include <dune/istl/preconditioners.hh>
#include <boost/property_tree/ptree.hpp>
#include <map>
#include <memory>
@ -58,15 +57,15 @@ public:
using PrecPtr = std::shared_ptr<Dune::PreconditionerWithUpdate<Vector, Vector>>;
/// The type of creator functions passed to addCreator().
using Creator = std::function<PrecPtr(const Operator&, const boost::property_tree::ptree&, const std::function<Vector()>&)>;
using ParCreator = std::function<PrecPtr(const Operator&, const boost::property_tree::ptree&, const std::function<Vector()>&, const Comm&)>;
using Creator = std::function<PrecPtr(const Operator&, const PropertyTree&, const std::function<Vector()>&)>;
using ParCreator = std::function<PrecPtr(const Operator&, const PropertyTree&, const std::function<Vector()>&, const Comm&)>;
/// Create a new serial preconditioner and return a pointer to it.
/// \param op operator to be preconditioned.
/// \param prm parameters for the preconditioner, in particular its type.
/// \param weightsCalculator Calculator for weights used in CPR.
/// \return (smart) pointer to the created preconditioner.
static PrecPtr create(const Operator& op, const boost::property_tree::ptree& prm,
static PrecPtr create(const Operator& op, const PropertyTree& prm,
const std::function<Vector()>& weightsCalculator = std::function<Vector()>())
{
return instance().doCreate(op, prm, weightsCalculator);
@ -78,7 +77,7 @@ public:
/// \param comm communication object (typically OwnerOverlapCopyCommunication).
/// \param weightsCalculator Calculator for weights used in CPR.
/// \return (smart) pointer to the created preconditioner.
static PrecPtr create(const Operator& op, const boost::property_tree::ptree& prm,
static PrecPtr create(const Operator& op, const PropertyTree& prm,
const std::function<Vector()>& weightsCalculator, const Comm& comm)
{
return instance().doCreate(op, prm, weightsCalculator, comm);
@ -89,7 +88,7 @@ public:
/// \param prm parameters for the preconditioner, in particular its type.
/// \param comm communication object (typically OwnerOverlapCopyCommunication).
/// \return (smart) pointer to the created preconditioner.
static PrecPtr create(const Operator& op, const boost::property_tree::ptree& prm, const Comm& comm)
static PrecPtr create(const Operator& op, const PropertyTree& prm, const Comm& comm)
{
return instance().doCreate(op, prm, std::function<Vector()>(), comm);
}
@ -123,7 +122,7 @@ private:
using Criterion = Dune::Amg::CoarsenCriterion<CriterionBase>;
// Helpers for creation of AMG preconditioner.
static Criterion amgCriterion(const boost::property_tree::ptree& prm)
static Criterion amgCriterion(const PropertyTree& prm)
{
Criterion criterion(15, prm.get<int>("coarsenTarget", 1200));
criterion.setDefaultValuesIsotropic(2);
@ -151,13 +150,13 @@ private:
template <typename X> struct Id { using Type = X; };
template <typename Smoother>
static auto amgSmootherArgs(const boost::property_tree::ptree& prm)
static auto amgSmootherArgs(const PropertyTree& prm)
{
return amgSmootherArgs(prm, Id<Smoother>());
}
template <typename Smoother>
static auto amgSmootherArgs(const boost::property_tree::ptree& prm,
static auto amgSmootherArgs(const PropertyTree& prm,
Id<Smoother>)
{
using SmootherArgs = typename Dune::Amg::SmootherTraits<Smoother>::Arguments;
@ -170,7 +169,7 @@ private:
return smootherArgs;
}
static auto amgSmootherArgs(const boost::property_tree::ptree& prm,
static auto amgSmootherArgs(const PropertyTree& prm,
Id<Opm::ParallelOverlappingILU0<Matrix, Vector, Vector, Comm>>)
{
using Smoother = Opm::ParallelOverlappingILU0<Matrix, Vector, Vector, Comm>;
@ -189,7 +188,7 @@ private:
}
template <class Smoother>
static PrecPtr makeAmgPreconditioner(const Operator& op, const boost::property_tree::ptree& prm, bool useKamg = false)
static PrecPtr makeAmgPreconditioner(const Operator& op, const PropertyTree& prm, bool useKamg = false)
{
auto crit = amgCriterion(prm);
auto sargs = amgSmootherArgs<Smoother>(prm);
@ -230,7 +229,7 @@ private:
}
static PrecPtr
createParILU(const Operator& op, const boost::property_tree::ptree& prm, const Comm& comm, const int ilulevel)
createParILU(const Operator& op, const PropertyTree& prm, const Comm& comm, const int ilulevel)
{
const double w = prm.get<double>("relaxation", 1.0);
const bool redblack = prm.get<bool>("redblack", false);
@ -256,7 +255,7 @@ private:
using O = Operator;
using M = Matrix;
using V = Vector;
using P = boost::property_tree::ptree;
using P = PropertyTree;
using C = Comm;
doAddCreator("ILU0", [](const O& op, const P& prm, const std::function<Vector()>&, const C& comm) {
return createParILU(op, prm, comm, 0);
@ -325,7 +324,7 @@ private:
using O = Operator;
using M = Matrix;
using V = Vector;
using P = boost::property_tree::ptree;
using P = PropertyTree;
doAddCreator("ILU0", [](const O& op, const P& prm, const std::function<Vector()>&) {
const double w = prm.get<double>("relaxation", 1.0);
return std::make_shared<Opm::ParallelOverlappingILU0<M, V, V>>(
@ -461,7 +460,7 @@ private:
}
// Actually creates the product object.
PrecPtr doCreate(const Operator& op, const boost::property_tree::ptree& prm,
PrecPtr doCreate(const Operator& op, const PropertyTree& prm,
const std::function<Vector()> weightsCalculator)
{
const std::string& type = prm.get<std::string>("type", "ParOverILU0");
@ -478,7 +477,7 @@ private:
return it->second(op, prm, weightsCalculator);
}
PrecPtr doCreate(const Operator& op, const boost::property_tree::ptree& prm,
PrecPtr doCreate(const Operator& op, const PropertyTree& prm,
const std::function<Vector()> weightsCalculator, const Comm& comm)
{
const std::string& type = prm.get<std::string>("type", "ParOverILU0");

View File

@ -22,7 +22,7 @@
#include <dune/istl/preconditioner.hh>
#include <memory>
#include <boost/property_tree/ptree.hpp>
namespace Dune
{

View File

@ -21,8 +21,7 @@
#define OPM_PRESSURE_SOLVER_POLICY_HEADER_INCLUDED
#include <opm/simulators/linalg/PressureTransferPolicy.hpp>
#include <boost/property_tree/ptree.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <dune/istl/solver.hh>
#include <dune/istl/owneroverlapcopy.hh>
@ -31,8 +30,6 @@ namespace Dune
{
namespace Amg
{
namespace pt = boost::property_tree;
template <class OperatorType, class Solver, class LevelTransferPolicy>
class PressureSolverPolicy
{
@ -43,7 +40,7 @@ namespace Amg
* @brief Constructs the coarse solver policy.
* @param prm Parameter tree specifying the solver details.
*/
explicit PressureSolverPolicy(const pt::ptree prm)
explicit PressureSolverPolicy(const Opm::PropertyTree& prm)
: prm_(prm)
{
}
@ -61,7 +58,7 @@ namespace Amg
#if HAVE_MPI
template <typename GlobalIndex, typename LocalIndex>
PressureInverseOperator(Operator& op,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const Dune::OwnerOverlapCopyCommunication<GlobalIndex, LocalIndex>& comm)
: linsolver_()
{
@ -71,7 +68,7 @@ namespace Amg
#endif // HAVE_MPI
PressureInverseOperator(Operator& op,
const boost::property_tree::ptree& prm,
const Opm::PropertyTree& prm,
const SequentialInformation&)
: linsolver_()
{
@ -132,7 +129,7 @@ namespace Amg
private:
/** @brief The coarse level operator. */
std::shared_ptr<Operator> coarseOperator_;
pt::ptree prm_;
Opm::PropertyTree prm_;
};
} // namespace Amg
} // namespace Dune

View File

@ -0,0 +1,115 @@
/*
Copyright 2019, 2020 SINTEF Digital, Mathematics and Cybernetics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <boost/property_tree/json_parser.hpp>
namespace Opm
{
PropertyTree::PropertyTree()
: tree_(std::make_unique<boost::property_tree::ptree>())
{
}
PropertyTree::PropertyTree(const PropertyTree& tree)
: tree_(std::make_unique<boost::property_tree::ptree>(*tree.tree_))
{
}
PropertyTree::PropertyTree(const std::string& jsonFile)
: tree_(std::make_unique<boost::property_tree::ptree>())
{
boost::property_tree::read_json(jsonFile, *tree_);
}
PropertyTree::PropertyTree(const boost::property_tree::ptree& tree)
: tree_(std::make_unique<boost::property_tree::ptree>(tree))
{
}
PropertyTree::~PropertyTree() = default;
template<class T>
T PropertyTree::get(const std::string& key) const
{
return tree_->get<T>(key);
}
template<class T>
T PropertyTree::get(const std::string& key, const T& defValue) const
{
return tree_->get<T>(key, defValue);
}
template<class T>
void PropertyTree::put(const std::string& key, const T& value)
{
tree_->put(key,value);
}
void PropertyTree::write_json(std::ostream &os, bool pretty) const
{
boost::property_tree::write_json(os, *tree_, pretty);
}
PropertyTree
PropertyTree::get_child(const std::string& key) const
{
auto pt = tree_->get_child(key);
return PropertyTree(pt);
}
std::optional<PropertyTree>
PropertyTree::get_child_optional(const std::string& key) const
{
auto pt = tree_->get_child_optional(key);
if (!pt)
return std::nullopt;
return PropertyTree(pt.get());
}
PropertyTree& PropertyTree::operator=(const PropertyTree& tree)
{
tree_ = std::make_unique<boost::property_tree::ptree>(*tree.tree_);
return *this;
}
template std::string PropertyTree::get<std::string>(const std::string& key) const;
template std::string PropertyTree::get<std::string>(const std::string& key, const std::string& defValue) const;
template double PropertyTree::get<double>(const std::string& key) const;
template double PropertyTree::get<double>(const std::string& key, const double& defValue) const;
template int PropertyTree::get<int>(const std::string& key) const;
template int PropertyTree::get<int>(const std::string& key, const int& defValue) const;
template size_t PropertyTree::get<size_t>(const std::string& key) const;
template size_t PropertyTree::get<size_t>(const std::string& key, const size_t& defValue) const;
template bool PropertyTree::get<bool>(const std::string& key) const;
template bool PropertyTree::get<bool>(const std::string& key, const bool& defValue) const;
template void PropertyTree::put<std::string>(const std::string& key, const std::string& value);
template void PropertyTree::put<double>(const std::string& key, const double& value);
template void PropertyTree::put<int>(const std::string& key, const int& value);
} // namespace Opm

View File

@ -0,0 +1,70 @@
/*
Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_PROPERTYTREE_HEADER_INCLUDED
#define OPM_PROPERTYTREE_HEADER_INCLUDED
#include <iosfwd>
#include <memory>
#include <optional>
namespace boost {
namespace property_tree {
template<class T1, class T2, class T3> class basic_ptree;
using ptree = basic_ptree<std::string,std::string,std::less<std::string>>;
}
}
namespace Opm
{
class PropertyTree {
public:
PropertyTree();
PropertyTree(const std::string& jsonFile);
PropertyTree(const PropertyTree& tree);
~PropertyTree();
template<class T>
void put(const std::string& key, const T& data);
template<class T>
T get(const std::string& key) const;
template<class T>
T get(const std::string& key, const T& defValue) const;
PropertyTree get_child(const std::string& key) const;
std::optional<PropertyTree> get_child_optional(const std::string& key) const;
PropertyTree& operator=(const PropertyTree& tree);
void write_json(std::ostream& os, bool pretty) const;
protected:
PropertyTree(const boost::property_tree::ptree& tree);
std::unique_ptr<boost::property_tree::ptree> tree_;
};
} // namespace Opm
#endif // OPM_PROPERTYTREE_HEADER_INCLUDED

View File

@ -21,35 +21,98 @@
#include <opm/simulators/linalg/setupPropertyTree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/version.hpp>
#include <opm/common/utility/FileSystem.hpp>
namespace Opm
{
boost::property_tree::ptree
/// Set up a property tree intended for FlexibleSolver by either reading
/// the tree from a JSON file or creating a tree giving the default solver
/// and preconditioner. If the latter, the parameters --linear-solver-reduction,
/// --linear-solver-maxiter and --linear-solver-verbosity are used, but if reading
/// from file the data in the JSON file will override any other options.
PropertyTree
setupPropertyTree(FlowLinearSolverParameters p, // Note: copying the parameters to potentially override.
bool LinearSolverMaxIterSet,
bool CprMaxEllIterSet)
{
std::string conf = p.linsolver_;
// Get configuration from file.
if (conf.size() > 5 && conf.substr(conf.size() - 5, 5) == ".json") { // the ends_with() method is not available until C++20
#if BOOST_VERSION / 100 % 1000 > 48
if ( !filesystem::exists(conf) ) {
OPM_THROW(std::invalid_argument, "JSON file " << conf << " does not exist.");
}
try {
return PropertyTree(conf);
}
catch (...) {
OPM_THROW(std::invalid_argument, "Failed reading linear solver configuration from JSON file " << conf);
}
#else
OPM_THROW(std::invalid_argument,
"--linear-solver-configuration=file.json not supported with "
<< "boost version. Needs version > 1.48.");
#endif
}
// Use CPR configuration.
if ((conf == "cpr") || (conf == "cpr_trueimpes") || (conf == "cpr_quasiimpes")) {
if (conf == "cpr") {
// Treat "cpr" as short cut for the true IMPES variant.
conf = "cpr_trueimpes";
}
if (!LinearSolverMaxIterSet) {
// Use our own default unless it was explicitly overridden by user.
p.linear_solver_maxiter_ = 20;
}
if (!CprMaxEllIterSet) {
// Use our own default unless it was explicitly overridden by user.
p.cpr_max_ell_iter_ = 1;
}
return setupCPR(conf, p);
}
if (conf == "amg") {
return setupAMG(conf, p);
}
// Use ILU0 configuration.
if (conf == "ilu0") {
return setupILU(conf, p);
}
// No valid configuration option found.
OPM_THROW(std::invalid_argument,
conf << " is not a valid setting for --linear-solver-configuration."
<< " Please use ilu0, cpr, cpr_trueimpes, or cpr_quasiimpes");
}
PropertyTree
setupCPR(const std::string& conf, const FlowLinearSolverParameters& p)
{
boost::property_tree::ptree prm;
using namespace std::string_literals;
PropertyTree prm;
prm.put("maxiter", p.linear_solver_maxiter_);
prm.put("tol", p.linear_solver_reduction_);
prm.put("verbosity", p.linear_solver_verbosity_);
prm.put("solver", "bicgstab");
prm.put("preconditioner.type", "cpr");
prm.put("solver", "bicgstab"s);
prm.put("preconditioner.type", "cpr"s);
if (conf == "cpr_quasiimpes") {
prm.put("preconditioner.weight_type", "quasiimpes");
prm.put("preconditioner.weight_type", "quasiimpes"s);
} else {
prm.put("preconditioner.weight_type", "trueimpes");
prm.put("preconditioner.weight_type", "trueimpes"s);
}
prm.put("preconditioner.finesmoother.type", "ParOverILU0");
prm.put("preconditioner.finesmoother.type", "ParOverILU0"s);
prm.put("preconditioner.finesmoother.relaxation", 1.0);
prm.put("preconditioner.pressure_var_index", 1);
prm.put("preconditioner.verbosity", 0);
prm.put("preconditioner.coarsesolver.maxiter", 1);
prm.put("preconditioner.coarsesolver.tol", 1e-1);
prm.put("preconditioner.coarsesolver.solver", "loopsolver");
prm.put("preconditioner.coarsesolver.solver", "loopsolver"s);
prm.put("preconditioner.coarsesolver.verbosity", 0);
prm.put("preconditioner.coarsesolver.preconditioner.type", "amg");
prm.put("preconditioner.coarsesolver.preconditioner.type", "amg"s);
prm.put("preconditioner.coarsesolver.preconditioner.alpha", 0.333333333333);
prm.put("preconditioner.coarsesolver.preconditioner.relaxation", 1.0);
prm.put("preconditioner.coarsesolver.preconditioner.iterations", p.cpr_max_ell_iter_);
@ -57,7 +120,7 @@ setupCPR(const std::string& conf, const FlowLinearSolverParameters& p)
prm.put("preconditioner.coarsesolver.preconditioner.pre_smooth", 1);
prm.put("preconditioner.coarsesolver.preconditioner.post_smooth", 1);
prm.put("preconditioner.coarsesolver.preconditioner.beta", 1e-5);
prm.put("preconditioner.coarsesolver.preconditioner.smoother", "ILU0");
prm.put("preconditioner.coarsesolver.preconditioner.smoother", "ILU0"s);
prm.put("preconditioner.coarsesolver.preconditioner.verbosity", 0);
prm.put("preconditioner.coarsesolver.preconditioner.maxlevel", 15);
prm.put("preconditioner.coarsesolver.preconditioner.skip_isolated", 0);
@ -74,15 +137,16 @@ setupCPR(const std::string& conf, const FlowLinearSolverParameters& p)
}
boost::property_tree::ptree
PropertyTree
setupAMG([[maybe_unused]] const std::string& conf, const FlowLinearSolverParameters& p)
{
boost::property_tree::ptree prm;
using namespace std::string_literals;
PropertyTree prm;
prm.put("tol", p.linear_solver_reduction_);
prm.put("maxiter", p.linear_solver_maxiter_);
prm.put("verbosity", p.linear_solver_verbosity_);
prm.put("solver", "bicgstab");
prm.put("preconditioner.type", "amg");
prm.put("solver", "bicgstab"s);
prm.put("preconditioner.type", "amg"s);
prm.put("preconditioner.alpha", 0.333333333333);
prm.put("preconditioner.relaxation", 1.0);
prm.put("preconditioner.iterations", 20);
@ -90,7 +154,7 @@ setupAMG([[maybe_unused]] const std::string& conf, const FlowLinearSolverParamet
prm.put("preconditioner.pre_smooth", 1);
prm.put("preconditioner.post_smooth", 1);
prm.put("preconditioner.beta", 1e-5);
prm.put("preconditioner.smoother", "ILU0");
prm.put("preconditioner.smoother", "ILU0"s);
prm.put("preconditioner.verbosity", 0);
prm.put("preconditioner.maxlevel", 15);
prm.put("preconditioner.skip_isolated", 0);
@ -107,15 +171,16 @@ setupAMG([[maybe_unused]] const std::string& conf, const FlowLinearSolverParamet
}
boost::property_tree::ptree
PropertyTree
setupILU([[maybe_unused]] const std::string& conf, const FlowLinearSolverParameters& p)
{
boost::property_tree::ptree prm;
using namespace std::string_literals;
PropertyTree prm;
prm.put("tol", p.linear_solver_reduction_);
prm.put("maxiter", p.linear_solver_maxiter_);
prm.put("verbosity", p.linear_solver_verbosity_);
prm.put("solver", "bicgstab");
prm.put("preconditioner.type", "ParOverILU0");
prm.put("solver", "bicgstab"s);
prm.put("preconditioner.type", "ParOverILU0"s);
prm.put("preconditioner.relaxation", p.ilu_relaxation_);
prm.put("preconditioner.ilulevel", p.ilu_fillin_level_);
return prm;

View File

@ -21,21 +21,21 @@
#define OPM_SETUPPROPERTYTREE_HEADER_INCLUDED
#include <opm/simulators/linalg/FlowLinearSolverParameters.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <boost/property_tree/ptree.hpp>
#include <string>
namespace Opm
{
template<class TypeTag>
boost::property_tree::ptree setupPropertyTree(FlowLinearSolverParameters p);
PropertyTree setupPropertyTree(FlowLinearSolverParameters p,
bool LinearSolverMaxIterSet,
bool CprMaxEllIterSet);
boost::property_tree::ptree setupCPR(const std::string& conf, const FlowLinearSolverParameters& p);
boost::property_tree::ptree setupAMG(const std::string& conf, const FlowLinearSolverParameters& p);
boost::property_tree::ptree setupILU(const std::string& conf, const FlowLinearSolverParameters& p);
PropertyTree setupCPR(const std::string& conf, const FlowLinearSolverParameters& p);
PropertyTree setupAMG(const std::string& conf, const FlowLinearSolverParameters& p);
PropertyTree setupILU(const std::string& conf, const FlowLinearSolverParameters& p);
} // namespace Opm
#include "setupPropertyTree_impl.hpp"
#endif // OPM_SETUPPROPERTYTREE_HEADER_INCLUDED

View File

@ -1,96 +0,0 @@
/*
Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <opm/simulators/linalg/setupPropertyTree.hpp>
#include <boost/version.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <opm/common/utility/FileSystem.hpp>
namespace Opm
{
/// Set up a property tree intended for FlexibleSolver by either reading
/// the tree from a JSON file or creating a tree giving the default solver
/// and preconditioner. If the latter, the parameters --linear-solver-reduction,
/// --linear-solver-maxiter and --linear-solver-verbosity are used, but if reading
/// from file the data in the JSON file will override any other options.
template<class TypeTag>
boost::property_tree::ptree
setupPropertyTree(FlowLinearSolverParameters p) // Note: copying the parameters to potentially override.
{
std::string conf = p.linsolver_;
// Get configuration from file.
if (conf.size() > 5 && conf.substr(conf.size() - 5, 5) == ".json") { // the ends_with() method is not available until C++20
#if BOOST_VERSION / 100 % 1000 > 48
if ( !filesystem::exists(conf) ) {
OPM_THROW(std::invalid_argument, "JSON file " << conf << " does not exist.");
}
try {
boost::property_tree::ptree prm;
boost::property_tree::read_json(conf, prm);
return prm;
}
catch (...) {
OPM_THROW(std::invalid_argument, "Failed reading linear solver configuration from JSON file " << conf);
}
#else
OPM_THROW(std::invalid_argument,
"--linear-solver-configuration=file.json not supported with "
<< "boost version. Needs version > 1.48.");
#endif
}
// Use CPR configuration.
if ((conf == "cpr") || (conf == "cpr_trueimpes") || (conf == "cpr_quasiimpes")) {
if (conf == "cpr") {
// Treat "cpr" as short cut for the true IMPES variant.
conf = "cpr_trueimpes";
}
if (!EWOMS_PARAM_IS_SET(TypeTag, int, LinearSolverMaxIter)) {
// Use our own default unless it was explicitly overridden by user.
p.linear_solver_maxiter_ = 20;
}
if (!EWOMS_PARAM_IS_SET(TypeTag, int, CprMaxEllIter)) {
// Use our own default unless it was explicitly overridden by user.
p.cpr_max_ell_iter_ = 1;
}
return setupCPR(conf, p);
}
if (conf == "amg") {
return setupAMG(conf, p);
}
// Use ILU0 configuration.
if (conf == "ilu0") {
return setupILU(conf, p);
}
// No valid configuration option found.
OPM_THROW(std::invalid_argument,
conf << " is not a valid setting for --linear-solver-configuration."
<< " Please use ilu0, cpr, cpr_trueimpes, or cpr_quasiimpes");
}
} // namespace Opm

View File

@ -296,8 +296,9 @@ void runBlackoilAmgLaplace()
Dune::OverlappingSchwarzScalarProduct<Vector,Communication> sp(comm);
Dune::InverseOperatorResult r;
boost::property_tree::ptree prm;
prm.put("type", "amg");
using namespace std::string_literals;
Opm::PropertyTree prm;
prm.put("type", "amg"s);
std::function<Vector()> weights = [&mat]() {
return Opm::Amg::getQuasiImpesWeights<BCRSMat, Vector>(mat, 0, false);
};

View File

@ -30,20 +30,19 @@
#include <opm/simulators/linalg/FlexibleSolver.hpp>
#include <opm/simulators/linalg/getQuasiImpesWeights.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/matrixmarket.hh>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <fstream>
#include <iostream>
template <int bz>
Dune::BlockVector<Dune::FieldVector<double, bz>>
testSolver(const boost::property_tree::ptree& prm, const std::string& matrix_filename, const std::string& rhs_filename)
testSolver(const Opm::PropertyTree& prm, const std::string& matrix_filename, const std::string& rhs_filename)
{
using Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, bz, bz>>;
using Vector = Dune::BlockVector<Dune::FieldVector<double, bz>>;
@ -86,15 +85,8 @@ testSolver(const boost::property_tree::ptree& prm, const std::string& matrix_fil
BOOST_AUTO_TEST_CASE(TestFlexibleSolver)
{
namespace pt = boost::property_tree;
pt::ptree prm;
// Read parameters.
{
std::ifstream file("options_flexiblesolver.json");
pt::read_json(file, prm);
// pt::write_json(std::cout, prm);
}
Opm::PropertyTree prm("options_flexiblesolver.json");
// Test with 1x1 block solvers.
{

View File

@ -29,6 +29,7 @@
BOOST_VERSION / 100 % 1000 > 48
#include <opm/simulators/linalg/PreconditionerFactory.hpp>
#include <opm/simulators/linalg/PropertyTree.hpp>
#include <opm/simulators/linalg/FlexibleSolver.hpp>
#include <dune/common/fvector.hh>
@ -37,9 +38,6 @@
#include <dune/istl/matrixmarket.hh>
#include <dune/istl/solvers.hh>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <fstream>
#include <iostream>
@ -70,7 +68,7 @@ public:
template <int bz>
Dune::BlockVector<Dune::FieldVector<double, bz>>
testPrec(const boost::property_tree::ptree& prm, const std::string& matrix_filename, const std::string& rhs_filename)
testPrec(const Opm::PropertyTree& prm, const std::string& matrix_filename, const std::string& rhs_filename)
{
using Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, bz, bz>>;
using Vector = Dune::BlockVector<Dune::FieldVector<double, bz>>;
@ -113,9 +111,7 @@ testPrec(const boost::property_tree::ptree& prm, const std::string& matrix_filen
return x;
}
namespace pt = boost::property_tree;
void test1(const pt::ptree& prm)
void test1(const Opm::PropertyTree& prm)
{
const int bz = 1;
auto sol = testPrec<bz>(prm, "matr33.txt", "rhs3.txt");
@ -136,7 +132,7 @@ void test1(const pt::ptree& prm)
}
}
void test3(const pt::ptree& prm)
void test3(const Opm::PropertyTree& prm)
{
const int bz = 3;
auto sol = testPrec<bz>(prm, "matr33.txt", "rhs3.txt");
@ -155,13 +151,8 @@ void test3(const pt::ptree& prm)
BOOST_AUTO_TEST_CASE(TestDefaultPreconditionerFactory)
{
pt::ptree prm;
// Read parameters.
{
std::ifstream file("options_flexiblesolver.json");
pt::read_json(file, prm);
}
Opm::PropertyTree prm("options_flexiblesolver.json");
// Test with 1x1 block solvers.
test1(prm);
@ -183,14 +174,8 @@ using PF = Opm::PreconditionerFactory<O<bz>>;
BOOST_AUTO_TEST_CASE(TestAddingPreconditioner)
{
namespace pt = boost::property_tree;
pt::ptree prm;
// Read parameters.
{
std::ifstream file("options_flexiblesolver_simple.json"); // Requests "nothing" for preconditioner type.
pt::read_json(file, prm);
}
Opm::PropertyTree prm("options_flexiblesolver_simple.json");
// Test with 1x1 block solvers.
{
@ -206,7 +191,7 @@ BOOST_AUTO_TEST_CASE(TestAddingPreconditioner)
// Add preconditioner to factory for block size 1.
PF<1>::addCreator("nothing", [](const O<1>&, const pt::ptree&, const std::function<V<1>()>&) {
PF<1>::addCreator("nothing", [](const O<1>&, const Opm::PropertyTree&, const std::function<V<1>()>&) {
return Dune::wrapPreconditioner<NothingPreconditioner<V<1>>>();
});
@ -221,7 +206,7 @@ BOOST_AUTO_TEST_CASE(TestAddingPreconditioner)
}
// Add preconditioner to factory for block size 3.
PF<3>::addCreator("nothing", [](const O<3>&, const pt::ptree&, const std::function<V<3>()>&) {
PF<3>::addCreator("nothing", [](const O<3>&, const Opm::PropertyTree&, const std::function<V<3>()>&) {
return Dune::wrapPreconditioner<NothingPreconditioner<V<3>>>();
});
@ -288,7 +273,7 @@ protected:
template <int bz>
Dune::BlockVector<Dune::FieldVector<double, bz>>
testPrecRepeating(const boost::property_tree::ptree& prm, const std::string& matrix_filename, const std::string& rhs_filename)
testPrecRepeating(const Opm::PropertyTree& prm, const std::string& matrix_filename, const std::string& rhs_filename)
{
using Matrix = Dune::BCRSMatrix<Dune::FieldMatrix<double, bz, bz>>;
using Vector = Dune::BlockVector<Dune::FieldVector<double, bz>>;
@ -313,7 +298,7 @@ testPrecRepeating(const boost::property_tree::ptree& prm, const std::string& mat
using PrecFactory = Opm::PreconditionerFactory<Operator>;
// Add no-oppreconditioner to factory for block size 1.
PrecFactory::addCreator("nothing", [](const Operator&, const pt::ptree&, const std::function<Vector()>&) {
PrecFactory::addCreator("nothing", [](const Operator&, const Opm::PropertyTree&, const std::function<Vector()>&) {
return Dune::wrapPreconditioner<NothingPreconditioner<Vector>>();
});
@ -325,7 +310,7 @@ testPrecRepeating(const boost::property_tree::ptree& prm, const std::string& mat
return x;
}
void test1rep(const pt::ptree& prm)
void test1rep(const Opm::PropertyTree& prm)
{
const int bz = 1;
auto sol = testPrecRepeating<bz>(prm, "matr33rep.txt", "rhs3rep.txt");
@ -346,7 +331,7 @@ void test1rep(const pt::ptree& prm)
}
}
void test3rep(const pt::ptree& prm)
void test3rep(const Opm::PropertyTree& prm)
{
const int bz = 3;
auto sol = testPrecRepeating<bz>(prm, "matr33rep.txt", "rhs3rep.txt");
@ -366,13 +351,8 @@ void test3rep(const pt::ptree& prm)
BOOST_AUTO_TEST_CASE(TestWithRepeatingOperator)
{
pt::ptree prm;
// Read parameters.
{
std::ifstream file("options_flexiblesolver_simple.json");
pt::read_json(file, prm);
}
Opm::PropertyTree prm("options_flexiblesolver_simple.json");
// Test with 1x1 block solvers.
test1rep(prm);