From: cvs Date: Thu, 28 Oct 1999 21:12:25 +0000 (+0000) Subject: Breakdown is detected X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d63357d0d214a8066a3eed6af4a4bae5657b9348;p=dealii-svn.git Breakdown is detected git-svn-id: https://svn.dealii.org/trunk@1802 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/lac/include/lac/solver_qmrs.h b/deal.II/lac/include/lac/solver_qmrs.h index 382682343e..401675c176 100644 --- a/deal.II/lac/include/lac/solver_qmrs.h +++ b/deal.II/lac/include/lac/solver_qmrs.h @@ -46,8 +46,40 @@ class SolverQMRS : public Solver * pipe additional data to the * solver. This solver does not * need additional data. + * + * There are two possibilities to compute + * the residual: one is an estimate using + * the computed value #tau#. The other + * is exact computation using another matrix + * vector multiplication. + * + * QMRS, is susceptible to breakdowns, so + * we need a parameter telling us, which + * numbers are considered zero. */ - struct AdditionalData {}; + struct AdditionalData + { + /** + * Constructor. + * + * The default is no exact residual + * computation and breakdown + * parameter 1e-16. + */ + AdditionalData(bool exact_residual = false, + double breakdown=1.e-16) : + exact_residual(exact_residual), + breakdown(breakdown) + {} + /** + * Flag for exact computation of residual. + */ + bool exact_residual; + /** + * Breakdown threshold. + */ + double breakdown; + }; /** * Constructor. @@ -96,6 +128,10 @@ class SolverQMRS : public Solver * the square root of the #res2# value. */ long double res2; + /** + * Breakdown threshold. + */ + AdditionalData additional_data; }; @@ -107,8 +143,10 @@ class SolverQMRS : public Solver template SolverQMRS::SolverQMRS(SolverControl &cn, VectorMemory &mem, - const AdditionalData &) : - Solver(cn,mem) {}; + const AdditionalData &data) : + Solver(cn,mem), + additional_data(data) +{}; template @@ -185,9 +223,8 @@ SolverQMRS::solve (const Matrix &A, A.vmult(t,p); // Step 2 sigma = q*t; -// if (fabs(sigma) < ??) -//TODO: Breakdown criteria here and below - + if (fabs(sigma) < additional_data.breakdown) + return ReturnState(breakdown); // Step 3 alpha = rho/sigma; v.add(-alpha,t); @@ -200,11 +237,16 @@ SolverQMRS::solve (const Matrix &A, d.sadd(psi*theta_old, psi*alpha, p); x.add(d); // Step 5 - res = sqrt((it+1)*tau); + if (additional_data.exact_residual) + res = A.residual(q,x,b); + else + res = sqrt((it+1)*tau); conv = control().check(it,res); if (conv) break; + // Step 6 -// if (fabs(rho) < ??) + if (fabs(rho) < additional_data.breakdown) + return ReturnState(breakdown); // Step 7 rho_old = rho; precondition(q,v);