Merge pull request #460 from blattms/parallel-interleaved

Fix parallel flow_cp for the interleaved case
This commit is contained in:
Atgeirr Flø Rasmussen 2015-09-07 10:09:16 +02:00
commit b77e306688
4 changed files with 80 additions and 36 deletions

View File

@ -0,0 +1,58 @@
/*
Copyright 2015 Dr. Blatt - HPC-Simulation-Software & Services
Copyright 2015 Statoil AS
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_ADDITIONALOBJECTDELETER_HEADER_INCLUDED
#define OPM_ADDITIONALOBJECTDELETER_HEADER_INCLUDED
namespace Opm
{
//! \brief A custom deleter that will delete an additional object, too.
//!
//! In dune-istl most parallel preconditioners hold a reference to
//! a sequential preconditioner.
//! In CPRPreconditioner and NewtonIterationBlackoilInterleaved we use unique_ptr
//! for the memory management.
//! Ergo we need to construct the sequential preconditioner with new and
//! make sure that it gets deleted together with the enclosing parallel
//! preconditioner. Therefore this deleter stores a pointer to it and deletes
//! it during destruction.
//! \tparam The type of the additional object to be deleted.
template<class T>
class AdditionalObjectDeleter
{
public:
//! \brief empty constructor.
AdditionalObjectDeleter()
: additional_object_()
{}
//! \brief Constructor taking the object that needs to deleted.
AdditionalObjectDeleter(T& additional_object)
: additional_object_(&additional_object){}
//! \brief Delete an object and the additional one.
template<class T1>
void operator()(T1* pt)
{
delete pt;
delete additional_object_;
}
private:
T* additional_object_;
};
}
#endif

View File

@ -47,36 +47,12 @@
#include <opm/core/utility/ErrorMacros.hpp>
#include <opm/core/utility/Exceptions.hpp>
#include <opm/autodiff/AdditionalObjectDeleter.hpp>
#include <opm/autodiff/ParallelRestrictedAdditiveSchwarz.hh>
namespace Opm
{
namespace
{
//! \brief A custom deleter for the parallel preconditioners.
//!
//! In dune-istl they hold a reference to the sequential preconditioner.
//! In CPRPreconditioner we use unique_ptr for the memory management.
//! Ergo we need to construct the sequential preconditioner with new and
//! make sure that it gets deleted together with the enclosing parallel
//! preconditioner. Therefore this deleter stores a pointer to it and deletes
//! it during destruction.
template<class PREC>
class ParallelPreconditionerDeleter
{
public:
ParallelPreconditionerDeleter()
: ilu_()
{}
ParallelPreconditionerDeleter(PREC& ilu)
: ilu_(&ilu){}
template<class T>
void operator()(T* pt)
{
delete pt;
delete ilu_;
}
private:
PREC* ilu_;
};
///
/// \brief A traits class for selecting the types of the preconditioner.
///
@ -124,7 +100,7 @@ struct CPRSelector<M,X,Y,Dune::OwnerOverlapCopyCommunication<I1,I2> >
EllipticPreconditioner;
/// \brief The type of the unique pointer to the preconditioner of the elliptic part.
typedef std::unique_ptr<EllipticPreconditioner,
ParallelPreconditionerDeleter<Dune::SeqILU0<M,X,X> > >
AdditionalObjectDeleter<Dune::SeqILU0<M,X,X> > >
EllipticPreconditionerPointer;
typedef EllipticPreconditioner Smoother;
@ -146,11 +122,11 @@ struct CPRSelector<M,X,Y,Dune::OwnerOverlapCopyCommunication<I1,I2> >
//! \param ilu A reference to the wrapped preconditioner
//! \param p The parallel information for template parameter deduction.
template<class ILU, class I1, class I2>
ParallelPreconditionerDeleter<ILU>
AdditionalObjectDeleter<ILU>
createParallelDeleter(ILU& ilu, const Dune::OwnerOverlapCopyCommunication<I1,I2>& p)
{
(void) p;
return ParallelPreconditionerDeleter<ILU>(ilu);
return AdditionalObjectDeleter<ILU>(ilu);
}
#endif

View File

@ -153,8 +153,10 @@ namespace Opm
const ParallelISTLInformation& info =
boost::any_cast<const ParallelISTLInformation&>( parallelInformation_);
Comm istlComm(info.communicator());
// As we use a dune-istl with block size np the number of components
// per parallel is only one.
info.copyValuesTo(istlComm.indexSet(), istlComm.remoteIndices(),
size, np);
size, 1);
// Construct operator, scalar product and vectors needed.
typedef Dune::OverlappingSchwarzOperator<Mat,Vector,Vector,Comm> Operator;
Operator opA(istlA, istlComm);

View File

@ -26,6 +26,7 @@
#include <opm/autodiff/NewtonIterationBlackoilInterface.hpp>
#include <opm/autodiff/AdditionalObjectDeleter.hpp>
#include <opm/core/utility/parameters/ParameterGroup.hpp>
#include <opm/core/linalg/ParallelIstlInformation.hpp>
@ -107,17 +108,18 @@ namespace Opm
parallelInformation_arg.copyOwnerToAll(istlb, istlb);
// Solve.
solve(opA, x, istlb, *sp, precond, result);
solve(opA, x, istlb, *sp, *precond, result);
}
typedef Dune::SeqILU0<Mat, Vector, Vector> SeqPreconditioner;
template <class Operator>
SeqPreconditioner constructPrecond(Operator& opA, const Dune::Amg::SequentialInformation&) const
std::unique_ptr<SeqPreconditioner> constructPrecond(Operator& opA, const Dune::Amg::SequentialInformation&) const
{
const double relax = 1.0;
SeqPreconditioner precond(opA.getmat(), relax);
std::unique_ptr<SeqPreconditioner>
precond(new SeqPreconditioner(opA.getmat(), relax));
return precond;
}
@ -126,11 +128,17 @@ namespace Opm
typedef Dune::BlockPreconditioner<Vector, Vector, Comm, SeqPreconditioner> ParPreconditioner;
template <class Operator>
ParPreconditioner constructPrecond(Operator& opA, const Comm& comm) const
std::unique_ptr<ParPreconditioner,
AdditionalObjectDeleter<SeqPreconditioner> >
constructPrecond(Operator& opA, const Comm& comm) const
{
const double relax = 1.0;
SeqPreconditioner seq_precond(opA.getmat(), relax);
ParPreconditioner precond(seq_precond, comm);
SeqPreconditioner* seq_precond= new SeqPreconditioner(opA.getmat(),
relax);
typedef AdditionalObjectDeleter<SeqPreconditioner> Deleter;
std::unique_ptr<ParPreconditioner, Deleter>
precond(new ParPreconditioner(*seq_precond, comm),
Deleter(*seq_precond));
return precond;
}
#endif