From 29065b02053e00f26f9b53ebc8e25f507831abbe Mon Sep 17 00:00:00 2001 From: Martin Kronbichler Date: Sat, 11 Jul 2015 11:59:15 +0200 Subject: [PATCH] Simplify Chebyshev preconditioner setup by using signals --- include/deal.II/lac/precondition.h | 58 +++++++---------- ...ition_chebyshev_01.with_lapack=true.output | 6 +- .../step-37.with_lapack=true.output | 63 ++++++++++++------- 3 files changed, 68 insertions(+), 59 deletions(-) diff --git a/include/deal.II/lac/precondition.h b/include/deal.II/lac/precondition.h index 3e2e003fa2..313e6539ef 100644 --- a/include/deal.II/lac/precondition.h +++ b/include/deal.II/lac/precondition.h @@ -1398,6 +1398,17 @@ namespace internal const VECTOR &diagonal_vector; }; + + struct EigenvalueTracker + { + public: + void slot(const std::vector &eigenvalues) + { + values = eigenvalues; + } + + std::vector values; + }; } } @@ -1459,15 +1470,6 @@ PreconditionChebyshev::initialize (const MATRIX &matrix, Assert (additional_data.eig_cg_n_iterations > 2, ExcMessage ("Need to set at least two iterations to find eigenvalues.")); - // attach stream to SolverCG, run it with log report for eigenvalues - std::ostream *old_stream = deallog.has_file() ? &deallog.get_file_stream() : - static_cast(0); - if (old_stream) - deallog.detach(); - - std::ostringstream log_msg; - deallog.attach(log_msg); - // set a very strict tolerance to force at least two iterations ReductionControl control (data.eig_cg_n_iterations, 1e-20, 1e-20); GrowingVectorMemory memory; @@ -1477,9 +1479,11 @@ PreconditionChebyshev::initialize (const MATRIX &matrix, dummy->reinit(data.matrix_diagonal_inverse); *rhs = 1./std::sqrt(static_cast(matrix.m())); - typename SolverCG::AdditionalData cg_data; - cg_data.compute_eigenvalues = true; - SolverCG solver (control, memory, cg_data); + internal::PreconditionChebyshev::EigenvalueTracker eigenvalue_tracker; + SolverCG solver (control, memory); + solver.connect_eigenvalues_slot(std_cxx11::bind(&internal::PreconditionChebyshev::EigenvalueTracker::slot, + &eigenvalue_tracker, + std_cxx11::_1)); internal::PreconditionChebyshev::DiagonalPreconditioner preconditioner(data.matrix_diagonal_inverse); try @@ -1495,32 +1499,14 @@ PreconditionChebyshev::initialize (const MATRIX &matrix, memory.free(dummy); memory.free(rhs); - // read the log stream: grab the first and last eigenvalue - std::string cg_message = log_msg.str(); - const std::size_t pos = cg_message.find("cg:: "); - if (pos != std::string::npos) + // read the eigenvalues from the attached eigenvalue tracker + if (eigenvalue_tracker.values.empty()) + min_eigenvalue = max_eigenvalue = 1; + else { - cg_message.erase(0, pos+5); - std::string first = cg_message; - - if (cg_message.find_first_of(" ") != std::string::npos) - first.erase(cg_message.find_first_of(" "), std::string::npos); - std::istringstream(first) >> min_eigenvalue; - - if (cg_message.find_last_of(" ") != std::string::npos) - { - cg_message.erase(0, cg_message.find_last_of(" ")+1); - std::istringstream(cg_message) >> max_eigenvalue; - } - else max_eigenvalue = min_eigenvalue; + min_eigenvalue = eigenvalue_tracker.values.front(); + max_eigenvalue = eigenvalue_tracker.values.back(); } - else - min_eigenvalue = max_eigenvalue = 1; - - // reset deal.II stream - deallog.detach(); - if (old_stream) - deallog.attach(*old_stream); // include a safety factor since the CG method will in general not be // converged diff --git a/tests/lac/precondition_chebyshev_01.with_lapack=true.output b/tests/lac/precondition_chebyshev_01.with_lapack=true.output index eede3a8880..95c8d736ec 100644 --- a/tests/lac/precondition_chebyshev_01.with_lapack=true.output +++ b/tests/lac/precondition_chebyshev_01.with_lapack=true.output @@ -1,8 +1,10 @@ - +DEAL:cg::Starting value 1.00 +DEAL:cg::Convergence step 2 value 0 DEAL::Exact inverse: 0.84 0.20 0.26 0.20 0.18 0.03 0.05 0.10 0.03 0.06 DEAL::Check vmult orig: 1.09 0.26 0.34 0.26 0.24 0.04 0.06 0.12 0.04 0.07 DEAL::Check Tvmult orig: 1.09 0.26 0.34 0.26 0.24 0.04 0.06 0.12 0.04 0.07 - +DEAL:cg::Starting value 1.00 +DEAL:cg::Failure step 8 value 0.00 DEAL::Check vmult diag: 0.82 0.26 0.33 0.21 0.15 0.02 0.03 0.09 0.03 0.07 DEAL::Check Tvmult diag: 0.82 0.26 0.33 0.21 0.15 0.02 0.03 0.09 0.03 0.07 diff --git a/tests/matrix_free/step-37.with_lapack=true.output b/tests/matrix_free/step-37.with_lapack=true.output index 6528cc9124..2ef2bd9d95 100644 --- a/tests/matrix_free/step-37.with_lapack=true.output +++ b/tests/matrix_free/step-37.with_lapack=true.output @@ -1,52 +1,73 @@ DEAL:2d::Cycle 0 DEAL:2d::Number of degrees of freedom: 81 - - - +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Convergence step 3 value 0 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0.00110 DEAL:2d:cg::Starting value 0.132 DEAL:2d:cg::Convergence step 4 value 0 DEAL:2d:: DEAL:2d::Cycle 1 DEAL:2d::Number of degrees of freedom: 289 - - - - +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Convergence step 3 value 0 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0.00110 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0.153 DEAL:2d:cg::Starting value 0.0677 DEAL:2d:cg::Convergence step 5 value 0 DEAL:2d:: DEAL:2d::Cycle 2 DEAL:2d::Number of degrees of freedom: 1089 - - - - - +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Convergence step 3 value 0 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0.00110 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 0.153 +DEAL:2d:cg::Starting value 1.00 +DEAL:2d:cg::Failure step 10 value 1.07 DEAL:2d:cg::Starting value 0.0343 DEAL:2d:cg::Convergence step 5 value 0 DEAL:2d:: DEAL:3d::Cycle 0 DEAL:3d::Number of degrees of freedom: 125 - - +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Convergence step 3 value 0 +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Failure step 10 value 0 DEAL:3d:cg::Starting value 0.125 DEAL:3d:cg::Convergence step 5 value 0 DEAL:3d:: DEAL:3d::Cycle 1 DEAL:3d::Number of degrees of freedom: 729 - - - +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Convergence step 3 value 0 +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Failure step 10 value 0 +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Failure step 10 value 0.000695 DEAL:3d:cg::Starting value 0.0479 DEAL:3d:cg::Convergence step 4 value 0 DEAL:3d:: DEAL:3d::Cycle 2 DEAL:3d::Number of degrees of freedom: 4913 - - - - +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Convergence step 3 value 0 +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Failure step 10 value 0 +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Failure step 10 value 0.000695 +DEAL:3d:cg::Starting value 1.00 +DEAL:3d:cg::Failure step 10 value 0.0952 DEAL:3d:cg::Starting value 0.0176 DEAL:3d:cg::Convergence step 4 value 0 DEAL:3d:: -- 2.39.5