From 006b17733d74e4993c0e410a463483d03dd81646 Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de> Date: Mon, 9 Apr 2018 07:00:32 +0200 Subject: [PATCH] [test][mpnc][implicit] Use NewtonSolver --- .../nonequilibrium/newtonsolver.hh | 58 +++++++++++++++++++ .../2p2ccomparison/test_mpnc_comparison_fv.cc | 34 +++-------- .../mpnc/implicit/test_boxmpnckinetic.cc | 34 +++-------- .../implicit/test_boxmpncthermalnonequil.cc | 34 +++-------- .../mpnc/implicit/test_mpnc_obstacle_fv.cc | 34 +++-------- 5 files changed, 86 insertions(+), 108 deletions(-) create mode 100644 dumux/porousmediumflow/nonequilibrium/newtonsolver.hh diff --git a/dumux/porousmediumflow/nonequilibrium/newtonsolver.hh b/dumux/porousmediumflow/nonequilibrium/newtonsolver.hh new file mode 100644 index 0000000000..f12622d634 --- /dev/null +++ b/dumux/porousmediumflow/nonequilibrium/newtonsolver.hh @@ -0,0 +1,58 @@ +// -*- 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 2 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 <http://www.gnu.org/licenses/>. * + *****************************************************************************/ +/*! + * \file + * \ingroup PorousmediumNonEquilibriumModel + * \brief A MpNc specific newton solver. + * This controller calls the velocity averaging in the model after each iteration. + */ +#ifndef DUMUX_NONEQUILIBRIUM_NEWTON_SOLVER_HH +#define DUMUX_NONEQUILIBRIUM_NEWTON_SOLVER_HH + +#include <dumux/nonlinear/newtonsolver.hh> + +namespace Dumux { +/*! + * \ingroup PorousmediumNonEquilibriumModel + * \brief A nonequilibrium specific newton solver. + * This solver calls the velocity averaging in the problem after each iteration. + */ +template <class Assembler, class LinearSolver> +class NonEquilibriumNewtonSolver : public NewtonSolver<Assembler, LinearSolver> +{ + using ParentType = NewtonSolver<Assembler, LinearSolver>; + using SolutionVector = typename Assembler::ResidualType; + +public: + using ParentType::ParentType; + + void newtonEndStep(SolutionVector &uCurrentIter, + const SolutionVector &uLastIter) final + { + ParentType::newtonEndStep(uCurrentIter, uLastIter); + + auto& gridVariables = this->assembler().gridVariables(); + // Averages the face velocities of a vertex. Implemented in the model. + // The velocities are stored in the model. + gridVariables.calcVelocityAverage(uCurrentIter); + } +}; + +} // end namespace Dumux +#endif // DUMUX_NONEQUILIBRIUM_NEWTON_SOLVER_HH diff --git a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/test_mpnc_comparison_fv.cc b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/test_mpnc_comparison_fv.cc index 6b64b18c15..4b01fdd4f9 100644 --- a/test/porousmediumflow/mpnc/implicit/2p2ccomparison/test_mpnc_comparison_fv.cc +++ b/test/porousmediumflow/mpnc/implicit/2p2ccomparison/test_mpnc_comparison_fv.cc @@ -41,8 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> +#include <dumux/nonlinear/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -135,7 +134,6 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); - const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); @@ -163,10 +161,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -174,24 +170,8 @@ int main(int argc, char** argv) try // set previous solution for storage evaluations assembler->setPreviousSolution(xOld); - // try solving the non-linear system - for (int i = 0; i < maxDivisions; ++i) - { - // linearize & solve - auto converged = nonLinearSolver.solve(x); - - if (converged) - break; - - if (!converged && i == maxDivisions-1) - DUNE_THROW(Dune::MathError, - "Newton solver didn't converge after " - << maxDivisions - << " time-step divisions. dt=" - << timeLoop->timeStepSize() - << ".\nThe solutions of the current and the previous time steps " - << "have been saved to restart files."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -206,8 +186,8 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller - timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + // set new dt as suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.cc b/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.cc index 8fd4d91754..2f6e9f2ef0 100644 --- a/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.cc +++ b/test/porousmediumflow/mpnc/implicit/test_boxmpnckinetic.cc @@ -40,8 +40,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/nonequilibrium/newtoncontroller.hh> +#include <dumux/porousmediumflow/nonequilibrium/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -134,7 +133,6 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); - const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); @@ -162,10 +160,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = NonEquilibriumNewtonController<Scalar>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NonEquilibriumNewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -173,24 +169,8 @@ int main(int argc, char** argv) try // set previous solution for storage evaluations assembler->setPreviousSolution(xOld); - // try solving the non-linear system - for (int i = 0; i < maxDivisions; ++i) - { - // linearize & solve - auto converged = nonLinearSolver.solve(x); - - if (converged) - break; - - if (!converged && i == maxDivisions-1) - DUNE_THROW(Dune::MathError, - "Newton solver didn't converge after " - << maxDivisions - << " time-step divisions. dt=" - << timeLoop->timeStepSize() - << ".\nThe solutions of the current and the previous time steps " - << "have been saved to restart files."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -205,8 +185,8 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller - timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + // set new dt as suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.cc b/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.cc index 8974eecafa..7501c698c7 100644 --- a/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.cc +++ b/test/porousmediumflow/mpnc/implicit/test_boxmpncthermalnonequil.cc @@ -40,8 +40,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/nonequilibrium/newtoncontroller.hh> +#include <dumux/porousmediumflow/nonequilibrium/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -133,7 +132,6 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); - const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); @@ -161,10 +159,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = NonEquilibriumNewtonController<Scalar>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NonEquilibriumNewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -172,24 +168,8 @@ int main(int argc, char** argv) try // set previous solution for storage evaluations assembler->setPreviousSolution(xOld); - // try solving the non-linear system - for (int i = 0; i < maxDivisions; ++i) - { - // linearize & solve - auto converged = nonLinearSolver.solve(x); - - if (converged) - break; - - if (!converged && i == maxDivisions-1) - DUNE_THROW(Dune::MathError, - "Newton solver didn't converge after " - << maxDivisions - << " time-step divisions. dt=" - << timeLoop->timeStepSize() - << ".\nThe solutions of the current and the previous time steps " - << "have been saved to restart files."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -205,8 +185,8 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller - timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + // set new dt as suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc b/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc index fc999af2a1..86bdae2d55 100644 --- a/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc +++ b/test/porousmediumflow/mpnc/implicit/test_mpnc_obstacle_fv.cc @@ -41,8 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> +#include <dumux/nonlinear/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -135,7 +134,6 @@ int main(int argc, char** argv) try // get some time loop parameters using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); const auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); - const auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); const auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); @@ -163,10 +161,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -174,24 +170,8 @@ int main(int argc, char** argv) try // set previous solution for storage evaluations assembler->setPreviousSolution(xOld); - // try solving the non-linear system - for (int i = 0; i < maxDivisions; ++i) - { - // linearize & solve - auto converged = nonLinearSolver.solve(x); - - if (converged) - break; - - if (!converged && i == maxDivisions-1) - DUNE_THROW(Dune::MathError, - "Newton solver didn't converge after " - << maxDivisions - << " time-step divisions. dt=" - << timeLoop->timeStepSize() - << ".\nThe solutions of the current and the previous time steps " - << "have been saved to restart files."); - } + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -206,8 +186,8 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller - timeLoop->setTimeStepSize(newtonController->suggestTimeStepSize(timeLoop->timeStepSize())); + // set new dt as suggested by the newton solver + timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); -- GitLab