From 98c44f941dab643328d67b8c43a418246b57ae85 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Thu, 24 Aug 2017 11:14:52 -0600 Subject: [PATCH] Update the GMRES implementations to use VectorMemory::Pointer. This facilitates automatic memory allocation cleanup. --- include/deal.II/lac/solver_gmres.h | 54 +++++++++++------------------- 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/include/deal.II/lac/solver_gmres.h b/include/deal.II/lac/solver_gmres.h index 4143379a3d..447c7089b5 100644 --- a/include/deal.II/lac/solver_gmres.h +++ b/include/deal.II/lac/solver_gmres.h @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -64,9 +66,9 @@ namespace internal VectorMemory &vmem); /** - * Delete all allocated vectors. + * Destructor. Delete all allocated vectors. */ - ~TmpVectors(); + ~TmpVectors() = default; /** * Get vector number @p i. If this vector was unused before, an error @@ -99,7 +101,7 @@ namespace internal /** * Field for storing the vectors. */ - std::vector data; + std::vector::Pointer> data; /** * Offset of the first vector. This is for later when vector rotation @@ -517,21 +519,11 @@ namespace internal VectorMemory &vmem) : mem(vmem), - data (max_size, nullptr), + data (max_size), offset(0) {} - template - inline - TmpVectors::~TmpVectors () - { - for (typename std::vector::iterator v = data.begin(); - v != data.end(); ++v) - if (*v != nullptr) - mem.free(*v); - } - template inline VectorType & @@ -545,6 +537,7 @@ namespace internal } + template inline VectorType & TmpVectors::operator() (const unsigned int i, @@ -554,13 +547,14 @@ namespace internal ExcIndexRange(i,-offset, data.size()-offset)); if (data[i-offset] == nullptr) { - data[i-offset] = mem.alloc(); + data[i-offset] = std::move(typename VectorMemory::Pointer(mem)); data[i-offset]->reinit(temp); } return *data[i-offset]; } + template unsigned int TmpVectors::size() const @@ -569,6 +563,7 @@ namespace internal } + // A comparator for better printing eigenvalues inline bool complex_less_pred(const std::complex &x, @@ -822,20 +817,19 @@ SolverGMRES::solve (const MatrixType &A, VectorType &v = tmp_vectors(0, x); VectorType &p = tmp_vectors(n_tmp_vectors-1, x); - // Following vectors are needed - // when not the default residuals - // are used as stopping criterion - VectorType *r=nullptr; - VectorType *x_=nullptr; - dealii::Vector *gamma_=nullptr; + // Following vectors are needed when we are not using the default residuals + // as stopping criterion + typename VectorMemory::Pointer r; + typename VectorMemory::Pointer x_; + std::unique_ptr > gamma_; if (!use_default_residual) { - r=this->memory.alloc(); - x_=this->memory.alloc(); + r = std::move(typename VectorMemory::Pointer(this->memory)); + x_ = std::move(typename VectorMemory::Pointer(this->memory)); r->reinit(x); x_->reinit(x); - gamma_ = new dealii::Vector (gamma.size()); + gamma_ = std_cxx14::make_unique >(gamma.size()); } bool re_orthogonalize = additional_data.force_re_orthogonalization; @@ -1038,14 +1032,6 @@ SolverGMRES::solve (const MatrixType &A, if (!krylov_space_signal.empty()) krylov_space_signal(tmp_vectors); - if (!use_default_residual) - { - this->memory.free(r); - this->memory.free(x_); - - delete gamma_; - } - deallog.pop(); // in case of failure: throw exception @@ -1186,7 +1172,7 @@ SolverFGMRES::solve (const MatrixType &A, // Iteration starts here double res = -std::numeric_limits::max(); - VectorType *aux = this->memory.alloc(); + typename VectorMemory::Pointer aux (this->memory); aux->reinit(x); do { @@ -1247,8 +1233,6 @@ SolverFGMRES::solve (const MatrixType &A, } while (iteration_state == SolverControl::iterate); - this->memory.free(aux); - deallog.pop(); // in case of failure: throw exception if (iteration_state != SolverControl::success) -- 2.39.5