[bugfix] Make sequential preconditioner live as long as the parallel one.

It holds a reference to the sequential code. Previously this reference
point to a temporary object that was deleted upon exit of
constructPrecond.

With this commit use a unique_ptr to store the parallel
preconditioner. It also gets a custom deleter that will delete the
nested sequential iterator during destruction.
This commit is contained in:
Markus Blatt 2015-09-04 21:52:50 +02:00
parent 6890e8db71
commit 0adde744bf

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