diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a36b953e73d84ee57a310777d4b77c480b3e99a..fc0be3f2c0cdba9bf410a8940e8f7ee3e527eb22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ Differences Between DuMuX 3.2 and DuMuX 3.1 - __Van Genuchten__: Corrected VanGenuchten-Mualem exponent in the non-wetting saturation formula (`1/3` instead of `1/2` (or `l`, see above)) - __Van Genuchten__: Corrected VanGenuchten-Mualem implementation of `dkrn/dSw` - __AMGBackend__: The internal structure of the AMGBackend and the ParallelISTLHelper has been overhauled, as only used by the AMG, we did not make the changes backwards-compatible +- The global default parameters for linear solvers have been removed and moved to the class `LinearSolver`. +This only affects users that directly obtain this parameter via `getParam` somewhere in the code. - __Change matrix block arrangement for staggered models__: The matrix block structure has been adapted such that it complies with the literature standard, i.e., having the velocity block (C) on `M[0][0]` rather than on `M[1][1]`. This also requires re-arranging the submodels and properties in dumux-multidomain such that the face-related classes and vector entries now appear before the cell-centered ones. diff --git a/dumux/common/loggingparametertree.hh b/dumux/common/loggingparametertree.hh index 8117172a29f3ab516288032efa861ee2aca6e2c4..3716ac7b1975ed3aaeb99021b26af75c0c6caba3 100644 --- a/dumux/common/loggingparametertree.hh +++ b/dumux/common/loggingparametertree.hh @@ -101,6 +101,53 @@ public: return false; } + /** \brief obtain a vector of all full group names for a specified subgroup name + * + * Example: + * ------------ + * For the parameter tree + * + * [G1] + * MyParam1 = 1 + * [G2.G1] + * MyParam2 = 2 + * [G3.G2.G1] + * MyParam3 = 3 + * + * and groupPrefix="G3.G2" and subGroupName="G1" + * this returns a vector with the entries {"G3.G2.G1", "G2.G1", "G1"}. + * If groupPrefix = "G2", it returns {"G2.G1", "G1"}. + * If groupPrefix = "" the returned vector has size 1 (containing subGroupName), + * or size 0 if the subgroup does not exist in the parameter tree. + * + * \param subGroupName the sub group to look for + * \param groupPrefix the group prefix name (potentially prefixing the subgroup) + * \return a vector of fully qualified groups ordered by decreasing tree depth + */ + std::vector getSubGroups(const std::string& subGroupName, + std::string groupPrefix) const + { + std::vector groupNames; + + if (!groupPrefix.empty()) + { + auto compoundGroup = groupPrefix + "." + subGroupName; + for (std::string::size_type dotPos = 0; dotPos != std::string::npos; dotPos = groupPrefix.rfind(".")) + { + if (params_.hasSub(compoundGroup) || defaultParams_.hasSub(compoundGroup)) + groupNames.push_back(compoundGroup); + + groupPrefix = groupPrefix.substr(0, dotPos); + compoundGroup = groupPrefix + "." + subGroupName; + } + } + + if (params_.hasSub(subGroupName) || defaultParams_.hasSub(subGroupName)) + groupNames.push_back(subGroupName); + + return groupNames; + } + /** \brief print the hierarchical parameter tree to stream * * \param stream the output stream to print to diff --git a/dumux/common/parameters.hh b/dumux/common/parameters.hh index b01b9aa1ad706405dec6e75cc9832d540812f2e3..1e6733594ee4b69b833bb68785a360a5f13d3111 100644 --- a/dumux/common/parameters.hh +++ b/dumux/common/parameters.hh @@ -454,6 +454,14 @@ inline bool hasParam(const std::string& param) inline bool hasParamInGroup(const std::string& paramGroup, const std::string& param) { return Parameters::getTree().hasKeyInGroup(param, paramGroup); } -} // namespace Dumux +/*! + * \ingroup Common + * \brief Get a list of sub groups from the parameter tree sorted by relevance + * \return A vector of fully qualified subGroup names sorted by descending relevance. + */ +inline std::vector getParamSubGroups(const std::string& subGroupName, const std::string& paramGroup) +{ return Parameters::getTree().getSubGroups(subGroupName, paramGroup); } + +} // end namespace Dumux #endif diff --git a/dumux/linear/CMakeLists.txt b/dumux/linear/CMakeLists.txt index 6cdfe68ee25f6c55db3bfa95e9a31f04aed1ca0a..f9ffe34368a4e6ce9b1af699b784ed5c16ef4967 100644 --- a/dumux/linear/CMakeLists.txt +++ b/dumux/linear/CMakeLists.txt @@ -2,6 +2,7 @@ install(FILES amgbackend.hh amgparallelhelpers.hh amgtraits.hh +istlsolverfactorybackend.hh linearsolvertraits.hh linearsolveracceptsmultitypematrix.hh matrixconverter.hh diff --git a/dumux/linear/istlsolverfactorybackend.hh b/dumux/linear/istlsolverfactorybackend.hh new file mode 100644 index 0000000000000000000000000000000000000000..d6e7e11b89ea129d4aab9916be224b628c0ae9ab --- /dev/null +++ b/dumux/linear/istlsolverfactorybackend.hh @@ -0,0 +1,328 @@ +// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- +// vi: set et ts=4 sw=4 sts=4: +/***************************************************************************** + * See the file COPYING for full copying permissions. * + * * + * This program is free software: you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation, either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see . * + *****************************************************************************/ +/*! + * \file + * \ingroup Linear + * \brief Provides a generic linear solver based on the ISTL that chooses the + * solver and preconditioner at runtime + */ + +#ifndef DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH +#define DUMUX_LINEAR_ISTL_SOLVERFACTORYBACKEND_HH + +#include +#include +#include + +// preconditioners +#include +#include + +// solvers +#include +#include + +#include +#include + +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) + +namespace Dumux { + +/*! + * \ingroup Linear + * \brief A linear solver using the dune-istl solver factory + * to choose the solver and preconditioner at runtime. + * \note the solvers are configured via the input file + * \note requires Dune version 2.7.1 or newer + */ +template +class IstlSolverFactoryBackend : public LinearSolver +{ +public: + //! translation table for solver parameters + static std::vector> dumuxToIstlSolverParams; + + /*! + * \brief Construct the backend for the sequential case only + * + * \param paramGroup the parameter group for parameter lookup + */ + IstlSolverFactoryBackend(const std::string& paramGroup = "") + : paramGroup_(paramGroup) + , isParallel_(Dune::MPIHelper::getCollectiveCommunication().size() > 1) + { + if (isParallel_) + DUNE_THROW(Dune::InvalidStateException, "Using sequential constructor for parallel run. Use signature with gridView and dofMapper!"); + + reset(); + } + + /*! + * \brief Construct the backend for parallel or sequential runs + * + * \param gridView the grid view for parallel communication via the grid + * \param dofMapper an index mapper for dof entities + * \param paramGroup the parameter group for parameter lookup + */ + IstlSolverFactoryBackend(const typename LinearSolverTraits::GridView& gridView, + const typename LinearSolverTraits::DofMapper& dofMapper, + const std::string& paramGroup = "") + : paramGroup_(paramGroup) + , parallelHelper_(std::make_unique>(gridView, dofMapper)) + , isParallel_(Dune::MPIHelper::getCollectiveCommunication().size() > 1) + { + reset(); + } + + /*! + * \brief Solve a linear system. + * + * \param A the matrix + * \param x the seeked solution vector, containing the initial solution upon entry + * \param b the right hand side vector + */ + template + bool solve(Matrix& A, Vector& x, Vector& b) + { +#if HAVE_MPI + solveSequentialOrParallel_(A, x, b); +#else + solveSequential_(A, x, b); +#endif + firstCall_ = false; + return result_.converged; + } + + //! reset the linear solver factory + void reset() + { + firstCall_ = true; + resetDefaultParameters(); + convertParameterTree_(paramGroup_); + checkMandatoryParameters_(); + name_ = params_.get("preconditioner.type") + "-preconditioned " + params_.get("type"); + if (params_.get("verbose", 0) > 0) + std::cout << "Initialized linear solver of type: " << name_ << std::endl; + } + + //! reset some defaults for the solver parameters + void resetDefaultParameters() + { + params_["restart"] = "10"; + params_["maxit"] = "250"; + params_["reduction"] = "1e-13"; + params_["verbose"] = "0"; + params_["preconditioner.iterations"] = "1"; + params_["preconditioner.relaxation"] = "1.0"; + params_["preconditioner.verbosity"] = "0"; + } + + const Dune::InverseOperatorResult& result() const + { + return result_; + } + + const std::string& name() const + { + return name_; + } + +private: + void convertParameterTree_(const std::string& paramGroup="") + { + auto linearSolverGroups = getParamSubGroups("LinearSolver", paramGroup); + if (linearSolverGroups.empty()) // no linear solver parameters were specified + return; + + for (const auto& [dumuxKey, istlKey] : dumuxToIstlSolverParams) + { + for (const auto& group : linearSolverGroups) + { + const auto fullDumuxKey = group + "." + dumuxKey; + const auto value = getParam(fullDumuxKey, ""); + if (!value.empty()) + { + params_[istlKey] = value; + break; // skip groups with smaller depth in the tree + } + } + } + } + + void checkMandatoryParameters_() + { + if (!params_.hasKey("type")) + DUNE_THROW(Dune::InvalidStateException, "Solver factory needs \"LinearSolver.Type\" parameter to select the solver"); + + if (!params_.hasKey("preconditioner.type")) + DUNE_THROW(Dune::InvalidStateException, "Solver factory needs \"LinearSolver.Preconditioner.Type\" parameter to select the preconditioner"); + } + +#if HAVE_MPI + template + void solveSequentialOrParallel_(Matrix& A, Vector& x, Vector& b) + { + if constexpr (LinearSolverTraits::canCommunicate) + { + if (isParallel_) + { + if (LinearSolverTraits::isNonOverlapping(parallelHelper_->gridView())) + { + using PTraits = typename LinearSolverTraits::template ParallelNonoverlapping; + solveParallel_(A, x, b); + } + else + { + using PTraits = typename LinearSolverTraits::template ParallelOverlapping; + solveParallel_(A, x, b); + } + } + else + solveSequential_(A, x, b); + } + else + { + solveSequential_(A, x, b); + } + } + + template + void solveParallel_(Matrix& A, Vector& x, Vector& b) + { + using Comm = typename ParallelTraits::Comm; + using LinearOperator = typename ParallelTraits::LinearOperator; + using ScalarProduct = typename ParallelTraits::ScalarProduct; + + if (firstCall_) + { + Dune::initSolverFactories(); + parallelHelper_->initGhostsAndOwners(); + } + + std::shared_ptr comm; + std::shared_ptr linearOperator; + std::shared_ptr scalarProduct; + prepareLinearAlgebraParallel(A, b, comm, linearOperator, scalarProduct, *parallelHelper_); + + // construct solver + auto solver = getSolverFromFactory_(linearOperator); + + // solve linear system + solver->apply(x, b, result_); + } +#endif // HAVE_MPI + + template + void solveSequential_(Matrix& A, Vector& x, Vector& b) + { + // construct linear operator + using Traits = typename LinearSolverTraits::template Sequential; + using LinearOperator = typename Traits::LinearOperator; + auto linearOperator = std::make_shared(A); + + if (firstCall_) + Dune::initSolverFactories(); + + // construct solver + auto solver = getSolverFromFactory_(linearOperator); + + // solve linear system + solver->apply(x, b, result_); + } + + template + auto getSolverFromFactory_(std::shared_ptr& fop) + { + try { return Dune::getSolverFromFactory(fop, params_); } + catch(Dune::Exception& e) + { + std::cerr << "Could not create solver with factory" << std::endl; + std::cerr << e.what() << std::endl; + throw e; + } + } + + const std::string paramGroup_; + std::unique_ptr> parallelHelper_; + bool isParallel_; + bool firstCall_; + + Dune::InverseOperatorResult result_; + Dune::ParameterTree params_; + std::string name_; +}; + +//! translation table for solver parameters +template +std::vector> +IstlSolverFactoryBackend::dumuxToIstlSolverParams = +{ + // solver params + {"Verbosity", "verbose"}, + {"MaxIterations", "maxit"}, + {"ResidualReduction", "reduction"}, + {"Type", "type"}, + {"GMResRestart", "restart"}, // cycles before restarting + {"Restart", "restart"}, // cycles before restarting + {"MaxOrthogonalizationVectors", "mmax"}, + + // preconditioner params + // we expect parameters in the subgroup "Preconditioner" + // there are some legacy param names that are still supported + // subgroup parameters overwrite legacy parameters + {"PreconditionerVerbosity", "preconditioner.verbosity"}, + {"Preconditioner.Verbosity", "preconditioner.verbosity"}, + {"PreconditionerType", "preconditioner.type"}, + {"Preconditioner.Type", "preconditioner.type"}, + {"PreconditionerIterations", "preconditioner.iterations"}, + {"Preconditioner.Iterations", "preconditioner.iterations"}, + {"PreconditionerRelaxation", "preconditioner.relaxation"}, + {"Preconditioner.Relaxation", "preconditioner.relaxation"}, + {"Preconditioner.ILUOrder", "preconditioner.n"}, + {"Preconditioner.ILUResort", "preconditioner.resort"}, + {"Preconditioner.AmgSmootherRelaxation", "preconditioner.smootherRelaxation"}, + {"Preconditioner.AmgSmootherIterations", "preconditioner.smootherIterations"}, + {"Preconditioner.AmgMaxLevel", "preconditioner.maxLevel"}, + {"Preconditioner.AmgCoarsenTarget", "preconditioner.coarsenTarget"}, + {"Preconditioner.AmgMinCoarseningRate", "preconditioner.minCoarseningRate"}, + {"Preconditioner.AmgAccumulationMode", "preconditioner.accumulationMode"}, + {"Preconditioner.AmgProlongationDampingFactor", "preconditioner.prolongationDampingFactor"}, + {"Preconditioner.AmgAlpha", "preconditioner.alpha"}, + {"Preconditioner.AmgBeta", "preconditioner.beta"}, + {"Preconditioner.AmgAdditive", "preconditioner.additive"}, + {"Preconditioner.AmgGamma", "preconditioner.gamma"}, + {"Preconditioner.AmgPreSmoothingSteps", "preconditioner.preSteps"}, + {"Preconditioner.AmgPostSmoothingSteps", "preconditioner.postSteps"}, + {"Preconditioner.AmgCriterionSymmetric", "preconditioner.criterionSymmetric"}, + {"Preconditioner.AmgStrengthMeasure", "preconditioner.strengthMeasure"}, + {"Preconditioner.AmgDiagonalRowIndex", "preconditioner.diagonalRowIndex"}, + {"Preconditioner.AmgDefaultAggregationSizeMode", "preconditioner.defaultAggregationSizeMode"}, + {"Preconditioner.AmgDefaultAggregationDimension", "preconditioner.defaultAggregationDimension"}, + {"Preconditioner.AmgMaxAggregateDistance", "preconditioner.maxAggregateDistance"}, + {"Preconditioner.AmgMinAggregateSize", "preconditioner.minAggregateSize"}, + {"Preconditioner.AmgMaxAggregateSize", "preconditioner.maxAggregateSize"} +}; + +} // end namespace Dumux + +#else +#warning "Generic dune-istl solver factory backend needs dune-istl >= 2.7.1!" +#endif // DUNE version check +#endif // header guard diff --git a/dumux/linear/solver.hh b/dumux/linear/solver.hh index 328e9604e220fa8023e1bc5823ee420d21385555..93d102b4953a71538fbd76a0f3d978a6f7a53f7c 100644 --- a/dumux/linear/solver.hh +++ b/dumux/linear/solver.hh @@ -48,15 +48,17 @@ public: * - LinearSolver.ResidualReduction the residual reduction threshold, i.e. stopping criterion * - LinearSolver.PreconditionerRelaxation precondition relaxation * - LinearSolver.PreconditionerIterations the number of preconditioner iterations + * - LinearSolver.PreconditionerVerbosity the preconditioner verbosity level */ LinearSolver(const std::string& paramGroup = "") : paramGroup_(paramGroup) { - verbosity_ = getParamFromGroup(paramGroup, "LinearSolver.Verbosity"); - maxIter_ = getParamFromGroup(paramGroup, "LinearSolver.MaxIterations"); - residReduction_ = getParamFromGroup(paramGroup, "LinearSolver.ResidualReduction"); - relaxation_ = getParamFromGroup(paramGroup, "LinearSolver.PreconditionerRelaxation"); - precondIter_ = getParamFromGroup(paramGroup, "LinearSolver.PreconditionerIterations"); + verbosity_ = getParamFromGroup(paramGroup, "LinearSolver.Verbosity", 0); + maxIter_ = getParamFromGroup(paramGroup, "LinearSolver.MaxIterations", 250); + residReduction_ = getParamFromGroup(paramGroup, "LinearSolver.ResidualReduction", 1e-13); + relaxation_ = getParamFromGroup(paramGroup, "LinearSolver.PreconditionerRelaxation", 1); + precondIter_ = getParamFromGroup(paramGroup, "LinearSolver.PreconditionerIterations", 1); + precondVerbosity_ = getParamFromGroup(paramGroup, "LinearSolver.PreconditionerVerbosity", 0); } /*! @@ -117,12 +119,21 @@ public: void setPrecondIter(int i) { precondIter_ = i; } + //! the preconditioner verbosity + int precondVerbosity() const + { return precondVerbosity_; } + + //! set the preconditioner verbosity + void setPrecondVerbosity(int verbosityLevel) + { precondVerbosity_ = verbosityLevel; } + private: int verbosity_; int maxIter_; double residReduction_; double relaxation_; int precondIter_; + int precondVerbosity_; const std::string paramGroup_; }; diff --git a/test/common/parameters/test_loggingparametertree.cc b/test/common/parameters/test_loggingparametertree.cc index 044b747610fd95005146b6e083cfc04e8b12d759..65618da66a6ce8a30bbdb90a67a73fda4a88991e 100644 --- a/test/common/parameters/test_loggingparametertree.cc +++ b/test/common/parameters/test_loggingparametertree.cc @@ -45,6 +45,21 @@ int main (int argc, char *argv[]) try tEnd = getParamFromGroup("Hulk", "TimeLoop.TEnd"); if (tEnd != 1e6) DUNE_THROW(Dune::InvalidStateException, "TEnd should be 1e6!"); + auto groups = getParamSubGroups("TimeLoop", "Bulk"); + std::cout << "Found the following TimeLoop groups (group: Bulk): "; + for (const auto& g : groups) std::cout << g << " "; + std::cout << std::endl; + if (groups.size() != 2) DUNE_THROW(Dune::InvalidStateException, "Wrong number of groups with ending name TimeLoop! (" << groups.size() << ", should be 2)"); + if (groups[0] != "Bulk.TimeLoop") DUNE_THROW(Dune::InvalidStateException, "Wrong order or name of subgroups with ending name TimeLoop!"); + if (groups[1] != "TimeLoop") DUNE_THROW(Dune::InvalidStateException, "Wrong order or name of subgroups with ending name TimeLoop!"); + + groups = getParamSubGroups("TimeLoop", ""); + std::cout << "Found the following TimeLoop groups (group: empty): "; + for (const auto& g : groups) std::cout << g << " "; + std::cout << std::endl; + if (groups.size() != 1) DUNE_THROW(Dune::InvalidStateException, "Wrong number of groups with ending name TimeLoop! (" << groups.size() << ", should be 1)"); + if (groups[0] != "TimeLoop") DUNE_THROW(Dune::InvalidStateException, "Wrong order or name of subgroups with ending name TimeLoop!"); + Parameters::print(); // check the unused keys diff --git a/test/freeflow/shallowwater/dambreak/CMakeLists.txt b/test/freeflow/shallowwater/dambreak/CMakeLists.txt index 88e0ced92a1cf9c0d80dfbb556fdc6e97367f6d3..ee23f9b411a18dbe32a63ef70e4e5a2d0e49a6df 100644 --- a/test/freeflow/shallowwater/dambreak/CMakeLists.txt +++ b/test/freeflow/shallowwater/dambreak/CMakeLists.txt @@ -1,12 +1,28 @@ dune_symlink_to_source_files(FILES "params.input") -dumux_add_test(NAME test_shallowwater_dambreak - SOURCES main.cc - TIMEOUT 1500 - COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - CMD_ARGS --script fuzzy +add_executable(test_shallowwater_dambreak EXCLUDE_FROM_ALL main.cc) + +dumux_add_test(NAME test_shallowwater_dambreak_sequential + TARGET test_shallowwater_dambreak + LABELS shallowwater + TIMEOUT 1500 + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy --files ${CMAKE_SOURCE_DIR}/test/references/test_ff_shallowwater_dambreak-reference.vtu ${CMAKE_CURRENT_BINARY_DIR}/dambreak-00001.vtu --zeroThreshold {"velocityY":1e-14} --command "${CMAKE_CURRENT_BINARY_DIR}/test_shallowwater_dambreak params.input -Problem.Name dambreak") + +dumux_add_test(NAME test_shallowwater_dambreak_parallel + TARGET test_shallowwater_dambreak + LABELS shallowwater parallel + TIMEOUT 1500 + CMAKE_GUARD MPI_FOUND + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy + --files ${CMAKE_SOURCE_DIR}/test/references/test_ff_shallowwater_dambreak-reference.vtu + ${CMAKE_CURRENT_BINARY_DIR}/s0002-dambreak_parallel-00001.pvtu + --zeroThreshold {"velocityY":1e-14,"process rank":100} + --command "${MPIEXEC} -np 2 ${CMAKE_CURRENT_BINARY_DIR}/test_shallowwater_dambreak params.input + -Problem.Name dambreak_parallel") diff --git a/test/freeflow/shallowwater/dambreak/main.cc b/test/freeflow/shallowwater/dambreak/main.cc index 55cdcdc79a9b3e28f360219f0c1000c9857a0c48..18080ada723be04023372aace5d43bf8e260c2a3 100644 --- a/test/freeflow/shallowwater/dambreak/main.cc +++ b/test/freeflow/shallowwater/dambreak/main.cc @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -39,8 +40,15 @@ #include #include -#include + #include + +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) +#include +#else +#include +#endif + #include #include @@ -123,7 +131,11 @@ int main(int argc, char** argv) try auto assembler = std::make_shared(problem, gridGeometry, gridVariables, timeLoop, xOld); // the linear solver +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) + using LinearSolver = IstlSolverFactoryBackend>; +#else using LinearSolver = AMGBiCGSTABBackend>; +#endif auto linearSolver = std::make_shared(leafGridView, gridGeometry->dofMapper()); // the non-linear solver diff --git a/test/freeflow/shallowwater/dambreak/params.input b/test/freeflow/shallowwater/dambreak/params.input index 67c55fab5634049796677d8947e9c6a8380a512c..7254db45d5e6f29a5e6b862582bcfa4aa3f99128 100644 --- a/test/freeflow/shallowwater/dambreak/params.input +++ b/test/freeflow/shallowwater/dambreak/params.input @@ -15,3 +15,13 @@ Cells1 = 25 [Newton] EnablePartialReassembly = true EnableDynamicOutput = false + +[LinearSolver] +Type = bicgstabsolver +MaxIterations = 80 + +[LinearSolver.Preconditioner] +Type = ilu +Verbosity = 0 +ILUOrder = 0 +ILUResort = true diff --git a/test/freeflow/shallowwater/roughchannel/CMakeLists.txt b/test/freeflow/shallowwater/roughchannel/CMakeLists.txt index 3ae5d9a1616a3ebcf1aaebf377a4c6c490d362e3..b6d509befe6fa8f900c5d9cefd01f6bd44a47358 100644 --- a/test/freeflow/shallowwater/roughchannel/CMakeLists.txt +++ b/test/freeflow/shallowwater/roughchannel/CMakeLists.txt @@ -1,9 +1,10 @@ dune_symlink_to_source_files(FILES "params.input") dumux_add_test(NAME test_shallowwater_roughchannel - SOURCES main.cc - COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py - CMD_ARGS --script fuzzy + SOURCES main.cc + LABELS shallowwater + COMMAND ${CMAKE_SOURCE_DIR}/bin/testing/runtest.py + CMD_ARGS --script fuzzy --files ${CMAKE_SOURCE_DIR}/test/references/test_ff_shallowwater_roughchannel-reference.vtu ${CMAKE_CURRENT_BINARY_DIR}/roughchannel-00001.vtu --zeroThreshold {"velocityY":1e-14} diff --git a/test/linear/params.input b/test/linear/params.input index 2be5e3aec47f1dae272e669a488ba7120e14973d..1cdde54446e62cb993f06864c17a2e229a3c22fb 100644 --- a/test/linear/params.input +++ b/test/linear/params.input @@ -1,6 +1,15 @@ -TestSolver = CG ProblemSize = 2 -[CG.LinearSolver] +[LinearSolver] +Verbosity = 1 + +[AMGCG.LinearSolver] Type = cgsolver Preconditioner.Type = amg + +[SSORCG.LinearSolver] +Type = cgsolver +Preconditioner.Type = ssor + +[AMGBiCGSTAB.LinearSolver] +Verbosity = 1 diff --git a/test/linear/test_linearsolver.cc b/test/linear/test_linearsolver.cc index d379a47e5331076a25a173b4ff3fc84b1d20fed8..3bdccd032fb43a4c81d09eb9100661b333d5bb87 100644 --- a/test/linear/test_linearsolver.cc +++ b/test/linear/test_linearsolver.cc @@ -4,13 +4,8 @@ #include #include -#include -#include -#include -//#include -#include - #include +#include #include #include @@ -23,6 +18,15 @@ #include #include +#include +#include +#include + +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) +#include +#endif +#include + namespace Dumux::Test { struct MockGridGeometry @@ -33,6 +37,22 @@ struct MockGridGeometry static constexpr auto discMethod = DiscretizationMethod::box; }; +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) +template +void solveWithFactory(M& A, X& x, V& b, const std::string& paramGroup) +{ + std::cout << std::endl; + + using LinearSolver = IstlSolverFactoryBackend>; + LinearSolver solver(paramGroup); + + std::cout << "Solving Laplace problem with " << solver.name() << "\n"; + solver.solve(A, x, b); + if (!solver.result().converged) + DUNE_THROW(Dune::Exception, solver.name() << " did not converge!"); +} +#endif + } // end namespace Dumux::Test int main(int argc, char* argv[]) try @@ -53,15 +73,25 @@ int main(int argc, char* argv[]) try Vector x(A.N()); Vector b(A.M()); x = 0; b = 1; - using LinearSolverTraits = Dumux::LinearSolverTraits; - using LinearSolver = AMGBiCGSTABBackend; - - const auto testSolverName = getParam("TestSolver"); - LinearSolver solver(testSolverName); - - solver.solve(A, x, b); - if (!solver.result().converged) - DUNE_THROW(Dune::Exception, testSolverName << " did not converge!"); + // AMGBiCGSTABBackend + { + std::cout << std::endl; + + const auto testSolverName = "AMGBiCGSTAB"; + using LinearSolver = AMGBiCGSTABBackend>; + LinearSolver solver(testSolverName); + + std::cout << "Solving Laplace problem with " << solver.name() << "\n"; + solver.solve(A, x, b); + if (!solver.result().converged) + DUNE_THROW(Dune::Exception, testSolverName << " did not converge!"); + } + +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) + // IstlSolverFactoryBackend + Test::solveWithFactory(A, x, b, "AMGCG"); + Test::solveWithFactory(A, x, b, "SSORCG"); +#endif return 0; } diff --git a/test/porousmediumflow/richards/implicit/lens/main.cc b/test/porousmediumflow/richards/implicit/lens/main.cc index 06ab3fc8c80e3a957bff89049351f841452d5cb3..40e3cbbb1d8230458efc0c2de8e059cb16bdad3a 100644 --- a/test/porousmediumflow/richards/implicit/lens/main.cc +++ b/test/porousmediumflow/richards/implicit/lens/main.cc @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -37,11 +38,16 @@ #include #include #include +#include -#include +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) +#include #include -#include +#else +#include +#endif +#include #include #include @@ -144,7 +150,12 @@ int main(int argc, char** argv) try auto assembler = std::make_shared(problem, gridGeometry, gridVariables, timeLoop, xOld); // the linear solver +#if DUNE_VERSION_NEWER_REV(DUNE_ISTL,2,7,1) + using LinearSolver = IstlSolverFactoryBackend>; +#else using LinearSolver = AMGBiCGSTABBackend>; +#endif + auto linearSolver = std::make_shared(leafGridView, gridGeometry->dofMapper()); // the non-linear solver diff --git a/test/porousmediumflow/richards/implicit/lens/params.input b/test/porousmediumflow/richards/implicit/lens/params.input index 89b7a2d41f943580bcf5085462907168b2912c96..72e9e5fedd8e3ab958f3ea220a40e769b8efd0b6 100644 --- a/test/porousmediumflow/richards/implicit/lens/params.input +++ b/test/porousmediumflow/richards/implicit/lens/params.input @@ -8,8 +8,16 @@ Cells = 24 16 [Problem] Name = richardslens -EnableGravity = 1 # enable gravity +EnableGravity = true # enable gravity [Newton] TargetSteps = 18 # set the "desirable" number of Newton iterations of a time step EnableChop = true # chop for better convergence + +[LinearSolver] +Type = bicgstabsolver + +[LinearSolver.Preconditioner] +Type = amg +AmgMaxLevel = 2 +AmgAccumulationMode = atOnce