From d2b3344e038966b6d229ad213848c31cc4ed6b3e Mon Sep 17 00:00:00 2001 From: Max Kahnt <max.kahnt@fu-berlin.de> Date: Wed, 24 Feb 2016 16:00:16 +0100 Subject: [PATCH] Refactor test. --- dune/solvers/test/gssteptest.cc | 114 +++++++++++++++----------------- 1 file changed, 53 insertions(+), 61 deletions(-) diff --git a/dune/solvers/test/gssteptest.cc b/dune/solvers/test/gssteptest.cc index 089d7e56..ab4b5b53 100644 --- a/dune/solvers/test/gssteptest.cc +++ b/dune/solvers/test/gssteptest.cc @@ -16,34 +16,6 @@ #include "common.hh" -template <class Vector> -class Analyser { -public: - Analyser(Vector const &reference, - Norm<Vector> const &norm, - double tolerance) - : reference_(reference), norm_(norm), tolerance_(tolerance) - {} - - bool - analyse(Vector const &candidate, std::string testCase) { - const auto normDiff = norm_.diff(reference_, candidate); - const std::string s = Dune::formatString("%*s", -40, testCase.c_str()); - std::cout << "error for solver \"" << s - << "\": " << normDiff << std::endl; - if (normDiff > tolerance_) { - std::cerr << "Error too large for solver \"" << s << "\"." - << std::endl; - return false; - } - return true; - } -private: - Vector const &reference_; - Norm<Vector> const &norm_; - double const tolerance_; -}; - /** \brief test for the GSStep classes * * This test tests if the Dirichlet problem for a Laplace operator @@ -55,34 +27,24 @@ struct GSTestSuite template <class GridType> bool check(const GridType& grid) { - double stepTol = 1e-12; // termination criterion - double solveTol = 1.3e-5; // error in the solution - int maxIterations = 10000; - bool passed = true; - using Problem = - SymmetricSampleProblem<1, typename GridType::LevelGridView>; + using Problem = SymmetricSampleProblem<1, typename GridType::LevelGridView>; Problem p(grid.levelGridView(grid.maxLevel())); - const auto verbosity = Solver::REDUCED; + const auto verbosity = Solver::QUIET; const bool relativeErrors = false; using Matrix = typename Problem::Matrix; using Vector = typename Problem::Vector; - Analyser<Vector> analyser(p.u_ex, p.energyNorm, solveTol); - using LoopSolver = ::LoopSolver<Vector>; using Step = LinearIterationStep<Matrix, Vector>; - auto test = [&](Step* step, std::string name) { + auto solve = [&](Step* step, double stepTol, size_t maxIterations) { Vector u_copy = p.u; - Vector rhs_copy = p.rhs; - - step->setProblem(p.A, u_copy, rhs_copy); - typename Step::BitVector ignore(u_copy.size(), false); - step->ignoreNodes_ = &ignore; + step->setProblem(p.A, u_copy, p.rhs); + step->ignoreNodes_ = &p.ignore; LoopSolver solver(step, maxIterations, stepTol, &p.energyNorm, verbosity, relativeErrors); @@ -90,7 +52,25 @@ struct GSTestSuite solver.preprocess(); solver.solve(); - passed = passed and analyser.analyse(u_copy, name); + return u_copy; + }; + + auto analyse = [&](const Vector& v, std::string testCase, double tolerance) { + const auto normDiff = p.energyNorm.diff(p.u_ex, v); + const std::string s = Dune::formatString("%*s", -60, testCase.c_str()); + std::cout << "error for solver \"" << s + << "\": " << normDiff << std::endl; + if (normDiff > tolerance) { + std::cerr << "Error too large for solver \"" << testCase << "\"." + << std::endl; + return false; + } + return true; + }; + + auto test = [&](Step* step, std::string name) { + auto result = solve(step, 1e-12, 2000); + passed = passed and analyse(result, name, 1e-7); }; { @@ -98,14 +78,34 @@ struct GSTestSuite test(&gsStep, "BlockGS"); } + // test regularizable block GS + for(auto reg : {false, true}) { + for(auto type : {"Direct", "LDLt", "CG"}) { + Dune::ParameterTree config; + config["type"] = type; + config["regularize_diagonal"] = reg ? "1" : "0"; // for SemiDefiniteBlockGS + config["regularize_diag"] = reg ? "1e-10" : "0.0"; // for Dune::Solvers::*BlockGS + config["maxIter"] = "100"; // for Dune::Solvers::CGBlockGS + config["tol"] = "1e-10"; // for Dune::Solvers::CGBlockGS + + { + SemiDefiniteBlockGSStep<Matrix, Vector> gsStep(config); + test(&gsStep, Dune::formatString("SemiDefiniteBlockGS %s %s", + type, reg ? "regularized" : "")); + } + } + } + + // test projected block GS { size_t size = p.u.size(); using GSStep = ProjectedBlockGSStep<Matrix, Vector>; - ProjectedBlockGSStep<Matrix, Vector> gsStep; typename GSStep::HasObstacle hasObstacle(size, false); - gsStep.hasObstacle_ = &hasObstacle; - test(&gsStep, "ProjectedBlockGS w/o obstacle"); - + { + ProjectedBlockGSStep<Matrix, Vector> gsStep; + gsStep.hasObstacle_ = &hasObstacle; + test(&gsStep, "ProjectedBlockGS free"); + } hasObstacle.setAll(); std::vector<typename GSStep::Obstacle> obstacles(size); for(size_t i=0; i<size; ++i) { @@ -115,19 +115,11 @@ struct GSTestSuite obstacles[i].upper(j) = j+1; } } - gsStep.obstacles_ = &obstacles; - test(&gsStep, "ProjectedBlockGS w obstacle"); - } - - for(auto reg : {false, true}) { - for(auto type : {"direct", "ldlt", "cg"}) { - Dune::ParameterTree config; - config["type"] = type; - config["regularize_diagonal"] = reg ? "1" : "0"; - - SemiDefiniteBlockGSStep<Matrix, Vector> gsStep(config); - test(&gsStep, Dune::formatString("SemiDefiniteBlockGS %s %s", - type, reg ? "regularized" : "")); + { + ProjectedBlockGSStep<Matrix, Vector> gsStep; + gsStep.hasObstacle_ = &hasObstacle; + gsStep.obstacles_ = &obstacles; + test(&gsStep, "ProjectedBlockGS obstacle"); } } -- GitLab