Merge pull request #2667 from atgeirr/flexible-solver-separate-compile-unit

Use explicit instantiation for FlexibleSolver to reduce compile times.
This commit is contained in:
Atgeirr Flø Rasmussen 2020-06-19 15:03:30 +02:00 committed by GitHub
commit 5105b80e50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 455 additions and 130 deletions

View File

@ -28,6 +28,10 @@ list (APPEND MAIN_SOURCE_FILES
opm/simulators/timestepping/SimulatorReport.cpp opm/simulators/timestepping/SimulatorReport.cpp
opm/simulators/flow/MissingFeatures.cpp opm/simulators/flow/MissingFeatures.cpp
opm/simulators/linalg/ExtractParallelGridInformationToISTL.cpp opm/simulators/linalg/ExtractParallelGridInformationToISTL.cpp
opm/simulators/linalg/FlexibleSolver1.cpp
opm/simulators/linalg/FlexibleSolver2.cpp
opm/simulators/linalg/FlexibleSolver3.cpp
opm/simulators/linalg/FlexibleSolver4.cpp
opm/simulators/timestepping/TimeStepControl.cpp opm/simulators/timestepping/TimeStepControl.cpp
opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp opm/simulators/timestepping/AdaptiveSimulatorTimer.cpp
opm/simulators/timestepping/SimulatorTimer.cpp opm/simulators/timestepping/SimulatorTimer.cpp

View File

@ -1,5 +1,6 @@
/* /*
Copyright 2019 SINTEF Digital, Mathematics and Cybernetics. Copyright 2019, 2020 SINTEF Digital, Mathematics and Cybernetics.
Copyright 2020 Equinor.
This file is part of the Open Porous Media project (OPM). This file is part of the Open Porous Media project (OPM).
@ -21,7 +22,7 @@
#ifndef OPM_FLEXIBLE_SOLVER_HEADER_INCLUDED #ifndef OPM_FLEXIBLE_SOLVER_HEADER_INCLUDED
#define OPM_FLEXIBLE_SOLVER_HEADER_INCLUDED #define OPM_FLEXIBLE_SOLVER_HEADER_INCLUDED
#include <opm/simulators/linalg/PreconditionerFactory.hpp> #include <opm/simulators/linalg/PreconditionerWithUpdate.hpp>
#include <dune/common/fmatrix.hh> #include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh> #include <dune/istl/bcrsmatrix.hh>
@ -35,19 +36,6 @@
namespace Dune namespace Dune
{ {
template<class C>
struct IsComm : std::false_type
{};
template<>
struct IsComm<Dune::Amg::SequentialInformation> : std::true_type
{};
#if HAVE_MPI
template<class Index>
struct IsComm<Dune::OwnerOverlapCopyCommunication<Index>> : std::true_type
{};
#endif
/// A solver class that encapsulates all needed objects for a linear solver /// A solver class that encapsulates all needed objects for a linear solver
/// (operator, scalar product, iterative solver and preconditioner) and sets /// (operator, scalar product, iterative solver and preconditioner) and sets
/// them up based on runtime parameters, using the PreconditionerFactory for /// them up based on runtime parameters, using the PreconditionerFactory for
@ -60,52 +48,28 @@ public:
using VectorType = VectorTypeT; using VectorType = VectorTypeT;
/// Create a sequential solver. /// Create a sequential solver.
FlexibleSolver(const boost::property_tree::ptree& prm, const MatrixType& matrix, FlexibleSolver(const MatrixType& matrix,
const std::function<VectorTypeT()>& weightsCalculator = std::function<VectorTypeT()>()) const boost::property_tree::ptree& prm,
{ const std::function<VectorTypeT()>& weightsCalculator = std::function<VectorTypeT()>());
init(prm, matrix, weightsCalculator, Dune::Amg::SequentialInformation());
}
/// Create a parallel solver (if Comm is e.g. OwnerOverlapCommunication). /// Create a parallel solver (if Comm is e.g. OwnerOverlapCommunication).
template <class Comm> template <class Comm>
FlexibleSolver(const boost::property_tree::ptree& prm, FlexibleSolver(const MatrixType& matrix,
const MatrixType& matrix, const Comm& comm,
const typename std::enable_if<IsComm<Comm>::value, Comm>::type& comm) const boost::property_tree::ptree& prm,
{ const std::function<VectorTypeT()>& weightsCalculator = std::function<VectorTypeT()>());
init(prm, matrix, std::function<VectorTypeT()>(), comm);
}
/// Create a parallel solver (if Comm is e.g. OwnerOverlapCommunication). virtual void apply(VectorType& x, VectorType& rhs, Dune::InverseOperatorResult& res) override;
template <class Comm>
FlexibleSolver(const boost::property_tree::ptree& prm, const MatrixType& matrix,
const std::function<VectorTypeT()>& weightsCalculator, const Comm& comm)
{
init(prm, matrix, weightsCalculator, comm);
}
virtual void apply(VectorType& x, VectorType& rhs, Dune::InverseOperatorResult& res) override virtual void apply(VectorType& x, VectorType& rhs, double reduction, Dune::InverseOperatorResult& res) override;
{
linsolver_->apply(x, rhs, res);
}
virtual void apply(VectorType& x, VectorType& rhs, double reduction, Dune::InverseOperatorResult& res) override
{
linsolver_->apply(x, rhs, reduction, res);
}
/// Type of the contained preconditioner. /// Type of the contained preconditioner.
using AbstractPrecondType = Dune::PreconditionerWithUpdate<VectorType, VectorType>; using AbstractPrecondType = Dune::PreconditionerWithUpdate<VectorType, VectorType>;
/// Access the contained preconditioner. /// Access the contained preconditioner.
AbstractPrecondType& preconditioner() AbstractPrecondType& preconditioner();
{
return *preconditioner_;
}
virtual Dune::SolverCategory::Category category() const override virtual Dune::SolverCategory::Category category() const override;
{
return linearoperator_->category();
}
private: private:
using AbstractOperatorType = Dune::AssembledLinearOperator<MatrixType, VectorType, VectorType>; using AbstractOperatorType = Dune::AssembledLinearOperator<MatrixType, VectorType, VectorType>;
@ -115,83 +79,20 @@ private:
// Machinery for making sequential or parallel operators/preconditioners/scalar products. // Machinery for making sequential or parallel operators/preconditioners/scalar products.
template <class Comm> template <class Comm>
void initOpPrecSp(const MatrixType& matrix, const boost::property_tree::ptree& prm, void initOpPrecSp(const MatrixType& matrix, const boost::property_tree::ptree& prm,
const std::function<VectorTypeT()> weightsCalculator, const Comm& comm) const std::function<VectorTypeT()> weightsCalculator, const Comm& comm);
{
// Parallel case.
using ParOperatorType = Dune::OverlappingSchwarzOperator<MatrixType, VectorType, VectorType, Comm>;
using pt = const boost::property_tree::ptree;
auto linop = std::make_shared<ParOperatorType>(matrix, comm);
linearoperator_ = linop;
auto child = prm.get_child_optional("preconditioner");
preconditioner_
= Opm::PreconditionerFactory<ParOperatorType, Comm>::create(*linop, child? *child : pt(),
weightsCalculator, comm);
scalarproduct_ = Dune::createScalarProduct<VectorType, Comm>(comm, linearoperator_->category());
}
void initOpPrecSp(const MatrixType& matrix, const boost::property_tree::ptree& prm, void initOpPrecSp(const MatrixType& matrix, const boost::property_tree::ptree& prm,
const std::function<VectorTypeT()> weightsCalculator, const Dune::Amg::SequentialInformation&) const std::function<VectorTypeT()> weightsCalculator, const Dune::Amg::SequentialInformation&);
{
// Sequential case.
using SeqOperatorType = Dune::MatrixAdapter<MatrixType, VectorType, VectorType>;
using pt = const boost::property_tree::ptree;
auto linop = std::make_shared<SeqOperatorType>(matrix);
linearoperator_ = linop;
auto child = prm.get_child_optional("preconditioner");
preconditioner_ = Opm::PreconditionerFactory<SeqOperatorType>::create(*linop, child? *child : pt(),
weightsCalculator);
scalarproduct_ = std::make_shared<Dune::SeqScalarProduct<VectorType>>();
}
void initSolver(const boost::property_tree::ptree& prm, bool isMaster)
{
const double tol = prm.get<double>("tol", 1e-2);
const int maxiter = prm.get<int>("maxiter", 200);
const int verbosity = isMaster? prm.get<int>("verbosity", 0) : 0;
const std::string solver_type = prm.get<std::string>("solver", "bicgstab");
if (solver_type == "bicgstab") {
linsolver_.reset(new Dune::BiCGSTABSolver<VectorType>(*linearoperator_,
*scalarproduct_,
*preconditioner_,
tol, // desired residual reduction factor
maxiter, // maximum number of iterations
verbosity));
} else if (solver_type == "loopsolver") {
linsolver_.reset(new Dune::LoopSolver<VectorType>(*linearoperator_,
*scalarproduct_,
*preconditioner_,
tol, // desired residual reduction factor
maxiter, // maximum number of iterations
verbosity));
} else if (solver_type == "gmres") {
int restart = prm.get<int>("restart", 15);
linsolver_.reset(new Dune::RestartedGMResSolver<VectorType>(*linearoperator_,
*scalarproduct_,
*preconditioner_,
tol,
restart, // desired residual reduction factor
maxiter, // maximum number of iterations
verbosity));
#if HAVE_SUITESPARSE_UMFPACK
} else if (solver_type == "umfpack") {
bool dummy = false;
linsolver_.reset(new Dune::UMFPack<MatrixType>(linearoperator_->getmat(), verbosity, dummy));
#endif
} else {
OPM_THROW(std::invalid_argument, "Properties: Solver " << solver_type << " not known.");
}
}
void initSolver(const boost::property_tree::ptree& prm, bool isMaster);
// Main initialization routine. // Main initialization routine.
// Call with Comm == Dune::Amg::SequentialInformation to get a serial solver. // Call with Comm == Dune::Amg::SequentialInformation to get a serial solver.
template <class Comm> template <class Comm>
void init(const boost::property_tree::ptree& prm, const MatrixType& matrix, void init(const MatrixType& matrix,
const std::function<VectorTypeT()> weightsCalculator, const Comm& comm) const Comm& comm,
{ const boost::property_tree::ptree& prm,
initOpPrecSp(matrix, prm, weightsCalculator, comm); const std::function<VectorTypeT()> weightsCalculator);
initSolver(prm, comm.communicator().rank()==0);
}
std::shared_ptr<AbstractOperatorType> linearoperator_; std::shared_ptr<AbstractOperatorType> linearoperator_;
std::shared_ptr<AbstractPrecondType> preconditioner_; std::shared_ptr<AbstractPrecondType> preconditioner_;

View File

@ -0,0 +1,56 @@
/*
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/FlexibleSolver_impl.hpp>
#include <opm/simulators/linalg/matrixblock.hh>
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/solvers.hh>
#include <dune/istl/umfpack.hh>
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/istl/paamg/pinfo.hh>
// Explicit instantiations of FlexibleSolver
template <int N>
using BV = Dune::BlockVector<Dune::FieldVector<double, N>>;
template <int N>
using BM = Dune::BCRSMatrix<Dune::FieldMatrix<double, N, N>>;
template <int N>
using OBM = Dune::BCRSMatrix<Opm::MatrixBlock<double, N, N>>;
// Variants using Dune::FieldMatrix blocks.
template class Dune::FlexibleSolver<BM<1>, BV<1>>;
// Variants using Opm::MatrixBlock blocks.
template class Dune::FlexibleSolver<OBM<1>, BV<1>>;
#if HAVE_MPI
using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
template Dune::FlexibleSolver<OBM<1>, BV<1>>::FlexibleSolver(const MatrixType& matrix,
const Comm& comm,
const boost::property_tree::ptree& prm,
const std::function<BV<1>()>& weightsCalculator);
#endif // HAVE_MPI

View File

@ -0,0 +1,56 @@
/*
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/FlexibleSolver_impl.hpp>
#include <opm/simulators/linalg/matrixblock.hh>
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/solvers.hh>
#include <dune/istl/umfpack.hh>
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/istl/paamg/pinfo.hh>
// Explicit instantiations of FlexibleSolver
template <int N>
using BV = Dune::BlockVector<Dune::FieldVector<double, N>>;
template <int N>
using BM = Dune::BCRSMatrix<Dune::FieldMatrix<double, N, N>>;
template <int N>
using OBM = Dune::BCRSMatrix<Opm::MatrixBlock<double, N, N>>;
// Variants using Dune::FieldMatrix blocks.
template class Dune::FlexibleSolver<BM<2>, BV<2>>;
// Variants using Opm::MatrixBlock blocks.
template class Dune::FlexibleSolver<OBM<2>, BV<2>>;
#if HAVE_MPI
using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
template Dune::FlexibleSolver<OBM<2>, BV<2>>::FlexibleSolver(const MatrixType& matrix,
const Comm& comm,
const boost::property_tree::ptree& prm,
const std::function<BV<2>()>& weightsCalculator);
#endif // HAVE_MPI

View File

@ -0,0 +1,56 @@
/*
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/FlexibleSolver_impl.hpp>
#include <opm/simulators/linalg/matrixblock.hh>
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/solvers.hh>
#include <dune/istl/umfpack.hh>
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/istl/paamg/pinfo.hh>
// Explicit instantiations of FlexibleSolver
template <int N>
using BV = Dune::BlockVector<Dune::FieldVector<double, N>>;
template <int N>
using BM = Dune::BCRSMatrix<Dune::FieldMatrix<double, N, N>>;
template <int N>
using OBM = Dune::BCRSMatrix<Opm::MatrixBlock<double, N, N>>;
// Variants using Dune::FieldMatrix blocks.
template class Dune::FlexibleSolver<BM<3>, BV<3>>;
// Variants using Opm::MatrixBlock blocks.
template class Dune::FlexibleSolver<OBM<3>, BV<3>>;
#if HAVE_MPI
using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
template Dune::FlexibleSolver<OBM<3>, BV<3>>::FlexibleSolver(const MatrixType& matrix,
const Comm& comm,
const boost::property_tree::ptree& prm,
const std::function<BV<3>()>& weightsCalculator);
#endif // HAVE_MPI

View File

@ -0,0 +1,56 @@
/*
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/FlexibleSolver_impl.hpp>
#include <opm/simulators/linalg/matrixblock.hh>
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/solvers.hh>
#include <dune/istl/umfpack.hh>
#include <dune/istl/owneroverlapcopy.hh>
#include <dune/istl/paamg/pinfo.hh>
// Explicit instantiations of FlexibleSolver
template <int N>
using BV = Dune::BlockVector<Dune::FieldVector<double, N>>;
template <int N>
using BM = Dune::BCRSMatrix<Dune::FieldMatrix<double, N, N>>;
template <int N>
using OBM = Dune::BCRSMatrix<Opm::MatrixBlock<double, N, N>>;
// Variants using Dune::FieldMatrix blocks.
template class Dune::FlexibleSolver<BM<4>, BV<4>>;
// Variants using Opm::MatrixBlock blocks.
template class Dune::FlexibleSolver<OBM<4>, BV<4>>;
#if HAVE_MPI
using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
template Dune::FlexibleSolver<OBM<4>, BV<4>>::FlexibleSolver(const MatrixType& matrix,
const Comm& comm,
const boost::property_tree::ptree& prm,
const std::function<BV<4>()>& weightsCalculator);
#endif // HAVE_MPI

View File

@ -0,0 +1,191 @@
/*
Copyright 2019, 2020 SINTEF Digital, Mathematics and Cybernetics.
Copyright 2020 Equinor.
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_FLEXIBLE_SOLVER_IMPL_HEADER_INCLUDED
#define OPM_FLEXIBLE_SOLVER_IMPL_HEADER_INCLUDED
#include <opm/simulators/linalg/FlexibleSolver.hpp>
#include <opm/simulators/linalg/PreconditionerFactory.hpp>
#include <opm/simulators/linalg/matrixblock.hh>
#include <dune/common/fmatrix.hh>
#include <dune/istl/bcrsmatrix.hh>
#include <dune/istl/solvers.hh>
#include <dune/istl/umfpack.hh>
#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(const MatrixType& matrix,
const boost::property_tree::ptree& prm,
const std::function<VectorType()>& weightsCalculator)
{
init(matrix, Dune::Amg::SequentialInformation(), prm, weightsCalculator);
}
/// Create a parallel solver (if Comm is e.g. OwnerOverlapCommunication).
template <class MatrixType, class VectorType>
template <class Comm>
FlexibleSolver<MatrixType, VectorType>::
FlexibleSolver(const MatrixType& matrix,
const Comm& comm,
const boost::property_tree::ptree& prm,
const std::function<VectorType()>& weightsCalculator)
{
init(matrix, comm, prm, weightsCalculator);
}
template <class MatrixType, class VectorType>
void
FlexibleSolver<MatrixType, VectorType>::
apply(VectorType& x, VectorType& rhs, Dune::InverseOperatorResult& res)
{
linsolver_->apply(x, rhs, res);
}
template <class MatrixType, class VectorType>
void
FlexibleSolver<MatrixType, VectorType>::
apply(VectorType& x, VectorType& rhs, double reduction, Dune::InverseOperatorResult& res)
{
linsolver_->apply(x, rhs, reduction, res);
}
/// Access the contained preconditioner.
template <class MatrixType, class VectorType>
auto
FlexibleSolver<MatrixType, VectorType>::
preconditioner() -> AbstractPrecondType&
{
return *preconditioner_;
}
template <class MatrixType, class VectorType>
Dune::SolverCategory::Category
FlexibleSolver<MatrixType, VectorType>::
category() const
{
return linearoperator_->category();
}
// Machinery for making sequential or parallel operators/preconditioners/scalar products.
template <class MatrixType, class VectorType>
template <class Comm>
void
FlexibleSolver<MatrixType, VectorType>::
initOpPrecSp(const MatrixType& matrix, const boost::property_tree::ptree& prm,
const std::function<VectorType()> weightsCalculator, const Comm& comm)
{
// Parallel case.
using ParOperatorType = Dune::OverlappingSchwarzOperator<MatrixType, VectorType, VectorType, Comm>;
using pt = const boost::property_tree::ptree;
auto linop = std::make_shared<ParOperatorType>(matrix, comm);
linearoperator_ = linop;
auto child = prm.get_child_optional("preconditioner");
preconditioner_
= Opm::PreconditionerFactory<ParOperatorType, Comm>::create(*linop, child? *child : pt(),
weightsCalculator, comm);
scalarproduct_ = Dune::createScalarProduct<VectorType, Comm>(comm, linearoperator_->category());
}
template <class MatrixType, class VectorType>
void
FlexibleSolver<MatrixType, VectorType>::
initOpPrecSp(const MatrixType& matrix, const boost::property_tree::ptree& prm,
const std::function<VectorType()> weightsCalculator, const Dune::Amg::SequentialInformation&)
{
// Sequential case.
using SeqOperatorType = Dune::MatrixAdapter<MatrixType, VectorType, VectorType>;
using pt = const boost::property_tree::ptree;
auto linop = std::make_shared<SeqOperatorType>(matrix);
linearoperator_ = linop;
auto child = prm.get_child_optional("preconditioner");
preconditioner_ = Opm::PreconditionerFactory<SeqOperatorType>::create(*linop, child? *child : pt(),
weightsCalculator);
scalarproduct_ = std::make_shared<Dune::SeqScalarProduct<VectorType>>();
}
template <class MatrixType, class VectorType>
void
FlexibleSolver<MatrixType, VectorType>::
initSolver(const boost::property_tree::ptree& prm, bool isMaster)
{
const double tol = prm.get<double>("tol", 1e-2);
const int maxiter = prm.get<int>("maxiter", 200);
const int verbosity = isMaster? prm.get<int>("verbosity", 0) : 0;
const std::string solver_type = prm.get<std::string>("solver", "bicgstab");
if (solver_type == "bicgstab") {
linsolver_.reset(new Dune::BiCGSTABSolver<VectorType>(*linearoperator_,
*scalarproduct_,
*preconditioner_,
tol, // desired residual reduction factor
maxiter, // maximum number of iterations
verbosity));
} else if (solver_type == "loopsolver") {
linsolver_.reset(new Dune::LoopSolver<VectorType>(*linearoperator_,
*scalarproduct_,
*preconditioner_,
tol, // desired residual reduction factor
maxiter, // maximum number of iterations
verbosity));
} else if (solver_type == "gmres") {
int restart = prm.get<int>("restart", 15);
linsolver_.reset(new Dune::RestartedGMResSolver<VectorType>(*linearoperator_,
*scalarproduct_,
*preconditioner_,
tol,
restart, // desired residual reduction factor
maxiter, // maximum number of iterations
verbosity));
#if HAVE_SUITESPARSE_UMFPACK
} else if (solver_type == "umfpack") {
bool dummy = false;
linsolver_.reset(new Dune::UMFPack<MatrixType>(linearoperator_->getmat(), verbosity, dummy));
#endif
} else {
OPM_THROW(std::invalid_argument, "Properties: Solver " << solver_type << " not known.");
}
}
// Main initialization routine.
// Call with Comm == Dune::Amg::SequentialInformation to get a serial solver.
template <class MatrixType, class VectorType>
template <class Comm>
void
FlexibleSolver<MatrixType, VectorType>::
init(const MatrixType& matrix,
const Comm& comm,
const boost::property_tree::ptree& prm,
const std::function<VectorType()> weightsCalculator)
{
initOpPrecSp(matrix, prm, weightsCalculator, comm);
initSolver(prm, comm.communicator().rank()==0);
}
} // namespace Dune
#endif // OPM_FLEXIBLE_SOLVER_IMPL_HEADER_INCLUDED

View File

@ -905,10 +905,10 @@ protected:
if (isParallel()) { if (isParallel()) {
#if HAVE_MPI #if HAVE_MPI
assert(noGhostMat_); assert(noGhostMat_);
flexibleSolver_.reset(new FlexibleSolverType(prm_, *noGhostMat_, weightsCalculator, *comm_)); flexibleSolver_.reset(new FlexibleSolverType(*noGhostMat_, *comm_, prm_, weightsCalculator));
#endif #endif
} else { } else {
flexibleSolver_.reset(new FlexibleSolverType(prm_, *matrix_, weightsCalculator)); flexibleSolver_.reset(new FlexibleSolverType(*matrix_, prm_, weightsCalculator));
} }
} }
else else

View File

@ -199,11 +199,11 @@ public:
if (isParallel()) { if (isParallel()) {
#if HAVE_MPI #if HAVE_MPI
matrix_ = &mat.istlMatrix(); matrix_ = &mat.istlMatrix();
solver_.reset(new SolverType(prm_, mat.istlMatrix(), weightsCalculator, *comm_)); solver_.reset(new SolverType(mat.istlMatrix(), *comm_, prm_, weightsCalculator));
#endif #endif
} else { } else {
matrix_ = &mat.istlMatrix(); matrix_ = &mat.istlMatrix();
solver_.reset(new SolverType(prm_, mat.istlMatrix(), weightsCalculator)); solver_.reset(new SolverType(mat.istlMatrix(), prm_, weightsCalculator));
} }
rhs_ = b; rhs_ = b;
} else { } else {

View File

@ -60,13 +60,17 @@ namespace Amg
PressureInverseOperator(Operator& op, const boost::property_tree::ptree& prm, const Comm& comm) PressureInverseOperator(Operator& op, const boost::property_tree::ptree& prm, const Comm& comm)
: linsolver_() : linsolver_()
{ {
if (op.category() == Dune::SolverCategory::overlapping) { assert(op.category() == Dune::SolverCategory::overlapping);
linsolver_.reset(new Solver(prm, op.getmat(), std::function<X()>(), comm)); linsolver_.reset(new Solver(op.getmat(), comm, prm, std::function<X()>()));
} else {
linsolver_.reset(new Solver(prm, op.getmat(), std::function<X()>()));
} }
PressureInverseOperator(Operator& op, const boost::property_tree::ptree& prm, const SequentialInformation&)
: linsolver_()
{
assert(op.category() != Dune::SolverCategory::overlapping);
linsolver_.reset(new Solver(op.getmat(), prm, std::function<X()>()));
} }
Dune::SolverCategory::Category category() const override Dune::SolverCategory::Category category() const override
{ {
return linsolver_->category(); return linsolver_->category();

View File

@ -29,6 +29,7 @@
BOOST_VERSION / 100 % 1000 > 48 BOOST_VERSION / 100 % 1000 > 48
#include <opm/simulators/linalg/FlexibleSolver.hpp> #include <opm/simulators/linalg/FlexibleSolver.hpp>
#include <opm/simulators/linalg/getQuasiImpesWeights.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
@ -70,7 +71,7 @@ testSolver(const boost::property_tree::ptree& prm, const std::string& matrix_fil
prm.get<int>("preconditioner.pressure_var_index"), prm.get<int>("preconditioner.pressure_var_index"),
transpose); transpose);
}; };
Dune::FlexibleSolver<Matrix, Vector> solver(prm, matrix, wc); Dune::FlexibleSolver<Matrix, Vector> solver(matrix, prm, wc);
Vector x(rhs.size()); Vector x(rhs.size());
Dune::InverseOperatorResult res; Dune::InverseOperatorResult res;
solver.apply(x, rhs, res); solver.apply(x, rhs, res);