mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Merge pull request #3365 from akva2/wrap_property_tree
Add Opm::PropertyTree
This commit is contained in:
commit
fc5e2be4e2
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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
|
||||
|
@ -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_;
|
||||
|
@ -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_;
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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");
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <dune/istl/preconditioner.hh>
|
||||
#include <memory>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
namespace Dune
|
||||
{
|
||||
|
||||
|
@ -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
|
||||
|
115
opm/simulators/linalg/PropertyTree.cpp
Normal file
115
opm/simulators/linalg/PropertyTree.cpp
Normal 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
|
70
opm/simulators/linalg/PropertyTree.hpp
Normal file
70
opm/simulators/linalg/PropertyTree.hpp
Normal 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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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);
|
||||
};
|
||||
|
@ -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.
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user