From: David Wells Date: Sat, 31 Mar 2018 23:13:16 +0000 (-0400) Subject: Use at least three temporary vectors for GMRES. X-Git-Tag: v9.0.0-rc1~253^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F6133%2Fhead;p=dealii.git Use at least three temporary vectors for GMRES. This prevents possible integer wrap-around that is not desired. This was found by coverity. --- diff --git a/include/deal.II/lac/solver_gmres.h b/include/deal.II/lac/solver_gmres.h index 47d51d4c34..dcdc6b6f55 100644 --- a/include/deal.II/lac/solver_gmres.h +++ b/include/deal.II/lac/solver_gmres.h @@ -197,7 +197,8 @@ public: /** * Maximum number of temporary vectors. This parameter controls the size * of the Arnoldi basis, which for historical reasons is - * #max_n_tmp_vectors-2. + * #max_n_tmp_vectors-2. SolverGMRES assumes that there are at least three + * temporary vectors, so this value must be greater than or equal to three. */ unsigned int max_n_tmp_vectors; @@ -598,7 +599,10 @@ AdditionalData (const unsigned int max_n_tmp_vectors, right_preconditioning(right_preconditioning), use_default_residual(use_default_residual), force_re_orthogonalization(force_re_orthogonalization) -{} +{ + Assert(3 <= max_n_tmp_vectors, ExcMessage("SolverGMRES needs at least three " + "temporary vectors.")); +} @@ -774,7 +778,10 @@ SolverGMRES::solve (const MatrixType &A, //TODO:[GK] Make sure the parameter in the constructor means maximum basis size LogStream::Prefix prefix("GMRES"); - const unsigned int n_tmp_vectors = additional_data.max_n_tmp_vectors; + + // extra call to std::max to placate static analyzers: coverity rightfully + // complains that data.max_n_tmp_vectors - 2 may overflow + const unsigned int n_tmp_vectors = std::max(additional_data.max_n_tmp_vectors, 3u); // Generate an object where basis vectors are stored. internal::SolverGMRESImplementation::TmpVectors tmp_vectors (n_tmp_vectors, this->memory);