From 1799e7f2d9870044cae8762b558e37e1e132d56e Mon Sep 17 00:00:00 2001 From: Uli Sack <usack@math.fu-berlin.de> Date: Fri, 20 Apr 2012 13:52:30 +0000 Subject: [PATCH] if for a semi definite Matrix normSquared(f) is negative zero i.e. e.g. -1e-16 operator() will return -nan. Now normSquared returns 0 in such a case and throws an exception for 'really' negative values [[Imported from SVN: r6070]] --- dune/solvers/norms/energynorm.hh | 35 +++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/dune/solvers/norms/energynorm.hh b/dune/solvers/norms/energynorm.hh index 7c8f1521..280e95f8 100644 --- a/dune/solvers/norms/energynorm.hh +++ b/dune/solvers/norms/energynorm.hh @@ -62,7 +62,8 @@ return sqrt(this->EnergyNorm<OperatorType,DiscFuncType>::normSquared(f)); } - //! Compute the square of the norm of the given vector + /** \brief Compute the square of the norm of the given vector + \todo This could be implemented without the temporary. */ virtual double normSquared(const DiscFuncType& f) const { if (iterationStep_ == NULL && matrix_ == NULL) @@ -76,7 +77,20 @@ tmp = 0; A.umv(f, tmp); - return f*tmp; + double ret = f*tmp; + + if (ret < 0) + { + if (ret < -1e-13) + { + char msg[1024]; + sprintf(msg, "Supplied linear operator is not positive (semi-)definite: (u,Au) = %e", ret); + DUNE_THROW(Dune::RangeError, msg); + } + ret = 0.0; + } + + return ret; } /** \brief Compute the squared norm for a given vector and matrix @@ -87,7 +101,22 @@ DiscFuncType tmp(u.size()); tmp = 0; A.umv(u, tmp); - return u*tmp; + + double ret = u*tmp; + + if (ret < 0) + { + if (ret < -1e-13) + { + char msg[1024]; + sprintf(msg, "Supplied linear operator is not positive (semi-)definite: (u,Au) = %e", ret); + DUNE_THROW(Dune::RangeError, msg); + } + ret = 0.0; + } + + return ret; + } DUNE_DEPRECATED; protected: -- GitLab