diff --git a/dumux/nonlinear/CMakeLists.txt b/dumux/nonlinear/CMakeLists.txt index 25e858ce85f0f5ac17e31978b1e4bce7802f26f2..0bc9109ce18c7c9e323562815743f4ba860a1d37 100644 --- a/dumux/nonlinear/CMakeLists.txt +++ b/dumux/nonlinear/CMakeLists.txt @@ -1,7 +1,6 @@ #install headers install(FILES -newtoncontroller.hh newtonconvergencewriter.hh -newtonmethod.hh +newtonsolver.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/nonlinear) diff --git a/dumux/nonlinear/newtoncontroller.hh b/dumux/nonlinear/newtoncontroller.hh deleted file mode 100644 index a64002a69d5fcd5655e4ee20c968fcb34613f5ef..0000000000000000000000000000000000000000 --- a/dumux/nonlinear/newtoncontroller.hh +++ /dev/null @@ -1,651 +0,0 @@ -// -*- 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 Nonlinear - * \brief Reference implementation of a controller class for the Newton solver. - * - * Usually this controller should be sufficient. - */ -#ifndef DUMUX_NEWTON_CONTROLLER_HH -#define DUMUX_NEWTON_CONTROLLER_HH - -#include <cmath> - -#include <dune/common/exceptions.hh> -#include <dune/common/parallel/mpicollectivecommunication.hh> -#include <dune/common/parallel/mpihelper.hh> -#include <dune/istl/bvector.hh> - -#include <dumux/common/exceptions.hh> -#include <dumux/common/timeloop.hh> -#include <dune/common/deprecated.hh> - -#warning "This file is deprecated. Use NewtonSolver instead." - -namespace Dumux { - -/*! - * \ingroup Nonlinear - * \brief An implementation of a Newton controller - * \tparam Scalar the scalar type - * \tparam Comm the communication object used to communicate with all processes - * \note If you want to specialize only some methods but are happy with the - * defaults of the reference controller, derive your controller from - * this class and simply overload the required methods. - */ -template <class Scalar, - class Comm = Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> > -class DUNE_DEPRECATED_MSG("Use NewtonSolver instead.") NewtonController -{ - -public: - //! the communication type used to communicate with all processes - using Communication = Comm; - - /*! - * \brief Constructor for stationary problems - */ - NewtonController(const Communication& comm = Dune::MPIHelper::getCollectiveCommunication(), - const std::string& paramGroup = "") - : comm_(comm) - , endIterMsgStream_(std::ostringstream::out) - , paramGroup_(paramGroup) - { - initParams_(paramGroup); - } - - /*! - * \brief Constructor for instationary problems - */ - NewtonController(std::shared_ptr<TimeLoop<Scalar>> timeLoop, - const Communication& comm = Dune::MPIHelper::getCollectiveCommunication(), - const std::string& paramGroup = "") - : comm_(comm) - , timeLoop_(timeLoop) - , endIterMsgStream_(std::ostringstream::out) - , paramGroup_(paramGroup) - { - initParams_(paramGroup); - } - - //! the communicator for parallel runs - const Communication& comm() const - { return comm_; } - - /*! - * \brief Set the maximum acceptable difference of any primary variable - * between two iterations for declaring convergence. - * - * \param tolerance The maximum relative shift between two Newton - * iterations at which the scheme is considered finished - */ - void setMaxRelativeShift(Scalar tolerance) - { shiftTolerance_ = tolerance; } - - /*! - * \brief Set the maximum acceptable absolute residual for declaring convergence. - * - * \param tolerance The maximum absolute residual at which - * the scheme is considered finished - */ - void setMaxAbsoluteResidual(Scalar tolerance) - { residualTolerance_ = tolerance; } - - /*! - * \brief Set the maximum acceptable residual norm reduction. - * - * \param tolerance The maximum reduction of the residual norm - * at which the scheme is considered finished - */ - void setResidualReduction(Scalar tolerance) - { reductionTolerance_ = tolerance; } - - /*! - * \brief Set the number of iterations at which the Newton method - * should aim at. - * - * This is used to control the time-step size. The heuristic used - * is to scale the last time-step size by the deviation of the - * number of iterations used from the target steps. - * - * \param targetSteps Number of iterations which are considered "optimal" - */ - void setTargetSteps(int targetSteps) - { targetSteps_ = targetSteps; } - - /*! - * \brief Set the number of iterations after which the Newton - * method gives up. - * - * \param maxSteps Number of iterations after we give up - */ - void setMaxSteps(int maxSteps) - { maxSteps_ = maxSteps; } - - /*! - * \brief Returns true if another iteration should be done. - * - * \param uCurrentIter The solution of the current Newton iteration - * \param converged if the Newton method's convergence criterion was met in this step - */ - template<class SolutionVector> - bool newtonProceed(const SolutionVector &uCurrentIter, bool converged) - { - if (numSteps_ < 2) - return true; // we always do at least two iterations - else if (converged) { - return false; // we are below the desired tolerance - } - else if (numSteps_ >= maxSteps_) { - // We have exceeded the allowed number of steps. If the - // maximum relative shift was reduced by a factor of at least 4, - // we proceed even if we are above the maximum number of steps. - if (enableShiftCriterion_) - return shift_*4.0 < lastShift_; - else - return reduction_*4.0 < lastReduction_; - } - - return true; - } - - /*! - * \brief Returns true if the error of the solution is below the - * tolerance. - */ - bool newtonConverged() const - { - if (enableShiftCriterion_ && !enableResidualCriterion_) - { - return shift_ <= shiftTolerance_; - } - else if (!enableShiftCriterion_ && enableResidualCriterion_) - { - if(enableAbsoluteResidualCriterion_) - return residualNorm_ <= residualTolerance_; - else - return reduction_ <= reductionTolerance_; - } - else if (satisfyResidualAndShiftCriterion_) - { - if(enableAbsoluteResidualCriterion_) - return shift_ <= shiftTolerance_ - && residualNorm_ <= residualTolerance_; - else - return shift_ <= shiftTolerance_ - && reduction_ <= reductionTolerance_; - } - else - { - return shift_ <= shiftTolerance_ - || reduction_ <= reductionTolerance_ - || residualNorm_ <= residualTolerance_; - } - - return false; - } - - /*! - * \brief Called before the Newton method is applied to an - * non-linear system of equations. - * - * \param u The initial solution - */ - template<class SolutionVector> - void newtonBegin(const SolutionVector& u) - { - numSteps_ = 0; - } - - /*! - * \brief Indicates the beginning of a Newton iteration. - */ - template<class SolutionVector> - void newtonBeginStep(const SolutionVector& u) - { - lastShift_ = shift_; - if (numSteps_ == 0) - { - lastReduction_ = 1.0; - } - else - { - lastReduction_ = reduction_; - } - } - - /*! - * \brief Returns the number of steps done since newtonBegin() was - * called. - */ - int newtonNumSteps() - { return numSteps_; } - - /*! - * \brief Update the maximum relative shift of the solution compared to - * the previous iteration. - * - * \param uLastIter The current iterative solution - * \param deltaU The difference between the current and the next solution - */ - template<class SolutionVector> - void newtonUpdateShift(const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - shift_ = 0; - - for (int i = 0; i < int(uLastIter.size()); ++i) { - typename SolutionVector::block_type uNewI = uLastIter[i]; - uNewI -= deltaU[i]; - - Scalar shiftAtDof = relativeShiftAtDof_(uLastIter[i], uNewI); - using std::max; - shift_ = max(shift_, shiftAtDof); - } - - if (comm().size() > 1) - shift_ = comm().max(shift_); - } - - /*! - * \brief Assemble the linear system of equations \f$\mathbf{A}x - b = 0\f$. - * - * \param assembler The jacobian assembler - * \param uCurrentIter The current iteration's solution vector - */ - template<class JacobianAssembler, class SolutionVector> - void assembleLinearSystem(JacobianAssembler& assembler, - const SolutionVector& uCurrentIter) - { - assembler.assembleJacobianAndResidual(uCurrentIter); - } - - /*! - * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. - * - * \throws Dumux::NumericalProblem if the linear solver didn't - * converge. - * - * \param ls The linear solver to be used - * \param A The matrix of the linear system of equations - * \param x The vector which solves the linear system - * \param b The right hand side of the linear system - */ - template<class LinearSolver, class JacobianMatrix, class SolutionVector> - void solveLinearSystem(LinearSolver& ls, - JacobianMatrix& A, - SolutionVector& x, - SolutionVector& b) - { - try { - if (numSteps_ == 0) - { - Scalar norm2 = b.two_norm2(); - if (comm().size() > 1) - norm2 = comm().sum(norm2); - - using std::sqrt; - initialResidual_ = sqrt(norm2); - } - - //! Copy into a standard block vector. - //! This is necessary for all model _not_ using a FieldVector<Scalar, blockSize> as - //! primary variables vector in combination with UMFPack or SuperLU as their interfaces are hard coded - //! to this field vector type in Dune ISTL - //! Could be avoided for vectors that already have the right type using SFINAE - //! but it shouldn't impact performance too much - constexpr auto blockSize = JacobianMatrix::block_type::rows; - using BlockType = Dune::FieldVector<Scalar, blockSize>; - Dune::BlockVector<BlockType> xTmp; xTmp.resize(b.size()); - Dune::BlockVector<BlockType> bTmp(xTmp); - for (unsigned int i = 0; i < b.size(); ++i) - for (unsigned int j = 0; j < blockSize; ++j) - bTmp[i][j] = b[i][j]; - - int converged = ls.solve(A, xTmp, bTmp); - - for (unsigned int i = 0; i < x.size(); ++i) - for (unsigned int j = 0; j < blockSize; ++j) - x[i][j] = xTmp[i][j]; - - // make sure all processes converged - int convergedRemote = converged; - if (comm().size() > 1) - convergedRemote = comm().min(converged); - - if (!converged) { - DUNE_THROW(NumericalProblem, - "Linear solver did not converge"); - } - else if (!convergedRemote) { - DUNE_THROW(NumericalProblem, - "Linear solver did not converge on a remote process"); - } - } - catch (const Dune::Exception &e) { - // make sure all processes converged - int converged = 0; - if (comm().size() > 1) - converged = comm().min(converged); - - NumericalProblem p; - p.message(e.what()); - throw p; - } - } - - /*! - * \brief Update the current solution with a delta vector. - * - * The error estimates required for the newtonConverged() and - * newtonProceed() methods should be updated inside this method. - * - * Different update strategies, such as line search and chopped - * updates can be implemented. The default behavior is just to - * subtract deltaU from uLastIter, i.e. - * \f[ u^{k+1} = u^k - \Delta u^k \f] - * - * \param assembler The assembler (needed for global residual evaluation) - * \param uCurrentIter The solution vector after the current iteration - * \param uLastIter The solution vector after the last iteration - * \param deltaU The delta as calculated from solving the linear - * system of equations. This parameter also stores - * the updated solution. - */ - template<class JacobianAssembler, class SolutionVector> - void newtonUpdate(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - if (enableShiftCriterion_) - newtonUpdateShift(uLastIter, deltaU); - - if (useLineSearch_) - { - lineSearchUpdate_(assembler, uCurrentIter, uLastIter, deltaU); - } - else { - for (unsigned int i = 0; i < uLastIter.size(); ++i) { - uCurrentIter[i] = uLastIter[i]; - uCurrentIter[i] -= deltaU[i]; - } - - if (enableResidualCriterion_) - { - residualNorm_ = assembler.residualNorm(uCurrentIter); - reduction_ = residualNorm_; - reduction_ /= initialResidual_; - } - else - { - // If we get here, the convergence criterion does not require - // additional residual evalutions. Thus, the grid variables have - // not yet been updated to the new uCurrentIter. - assembler.gridVariables().update(uCurrentIter); - } - } - } - - /*! - * \brief Indicates that one Newton iteration was finished. - * - * \param assembler The jacobian assembler - * \param uCurrentIter The solution after the current Newton iteration - * \param uLastIter The solution at the beginning of the current Newton iteration - */ - template<class JacobianAssembler, class SolutionVector> - void newtonEndStep(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - ++numSteps_; - - if (verbose()) - { - std::cout << "\rNewton iteration " << numSteps_ << " done"; - if (enableShiftCriterion_) - std::cout << ", maximum relative shift = " << shift_; - if (enableResidualCriterion_ && enableAbsoluteResidualCriterion_) - std::cout << ", residual = " << residualNorm_; - else if (enableResidualCriterion_) - std::cout << ", residual reduction = " << reduction_; - std::cout << endIterMsg().str() << "\n"; - } - endIterMsgStream_.str(""); - - // When the Newton iterations are done: ask the model to check whether it makes sense - // TODO: how do we realize this? -> do this here in the newton controller - // model_().checkPlausibility(); - } - - /*! - * \brief Called if the Newton method ended - * (not known yet if we failed or succeeded) - */ - void newtonEnd() {} - - /*! - * \brief Called if the Newton method ended succcessfully - * This method is called _after_ newtonEnd() - */ - void newtonSucceed() {} - - /*! - * \brief Called if the Newton method broke down. - * This method is called _after_ newtonEnd() - */ - template<class Assembler, class SolutionVector> - void newtonFail(Assembler& assembler, SolutionVector& u) - { - if (!assembler.isStationaryProblem()) - { - // set solution to previous solution - u = assembler.prevSol(); - - // reset the grid variables to the previous solution - assembler.gridVariables().resetTimeStep(u); - - if (verbose()) - { - std::cout << "Newton solver did not converge with dt = " - << timeLoop_->timeStepSize() << " seconds. Retrying with time step of " - << timeLoop_->timeStepSize()/2 << " seconds\n"; - } - - // try again with dt = dt/2 - timeLoop_->setTimeStepSize(timeLoop_->timeStepSize()/2); - } - else - DUNE_THROW(Dune::MathError, "Newton solver did not converge"); - } - - /*! - * \brief Suggest a new time-step size based on the old time-step - * size. - * - * The default behavior is to suggest the old time-step size - * scaled by the ratio between the target iterations and the - * iterations required to actually solve the last time-step. - */ - Scalar suggestTimeStepSize(Scalar oldTimeStep) const - { - // be aggressive reducing the time-step size but - // conservative when increasing it. the rationale is - // that we want to avoid failing in the next Newton - // iteration which would require another linearization - // of the problem. - if (numSteps_ > targetSteps_) { - Scalar percent = Scalar(numSteps_ - targetSteps_)/targetSteps_; - return oldTimeStep/(1.0 + percent); - } - - Scalar percent = Scalar(targetSteps_ - numSteps_)/targetSteps_; - return oldTimeStep*(1.0 + percent/1.2); - } - - std::ostringstream &endIterMsg() - { return endIterMsgStream_; } - - /*! - * \brief Specifies if the Newton method ought to be chatty. - */ - void setVerbose(bool val) - { verbose_ = val; } - - /*! - * \brief Returns true if the Newton method ought to be chatty. - */ - bool verbose() const - { return verbose_ && comm().rank() == 0; } - - /*! - * \brief Returns the parameter group - */ - const std::string& paramGroup() const - { return paramGroup_; } - -protected: - - //! initialize the parameters by reading from the parameter tree - void initParams_(const std::string& group = "") - { - useLineSearch_ = getParamFromGroup<bool>(group, "Newton.UseLineSearch"); - enableAbsoluteResidualCriterion_ = getParamFromGroup<bool>(group, "Newton.EnableAbsoluteResidualCriterion"); - enableShiftCriterion_ = getParamFromGroup<bool>(group, "Newton.EnableShiftCriterion"); - enableResidualCriterion_ = getParamFromGroup<bool>(group, "Newton.EnableResidualCriterion") || enableAbsoluteResidualCriterion_; - satisfyResidualAndShiftCriterion_ = getParamFromGroup<bool>(group, "Newton.SatisfyResidualAndShiftCriterion"); - if (!enableShiftCriterion_ && !enableResidualCriterion_) - { - DUNE_THROW(Dune::NotImplemented, - "at least one of NewtonEnableShiftCriterion or " - << "NewtonEnableResidualCriterion has to be set to true"); - } - - setMaxRelativeShift(getParamFromGroup<Scalar>(group, "Newton.MaxRelativeShift")); - setMaxAbsoluteResidual(getParamFromGroup<Scalar>(group, "Newton.MaxAbsoluteResidual")); - setResidualReduction(getParamFromGroup<Scalar>(group, "Newton.ResidualReduction")); - setTargetSteps(getParamFromGroup<int>(group, "Newton.TargetSteps")); - setMaxSteps(getParamFromGroup<int>(group, "Newton.MaxSteps")); - - verbose_ = true; - numSteps_ = 0; - } - - template<class JacobianAssembler, class SolutionVector> - void lineSearchUpdate_(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - Scalar lambda = 1.0; - SolutionVector tmp(uLastIter); - - while (true) - { - uCurrentIter = deltaU; - uCurrentIter *= -lambda; - uCurrentIter += uLastIter; - - residualNorm_ = assembler.residualNorm(uCurrentIter); - reduction_ = residualNorm_; - reduction_ /= initialResidual_; - - if (reduction_ < lastReduction_ || lambda <= 0.125) { - endIterMsg() << ", residual reduction " << lastReduction_ << "->" << reduction_ << "@lambda=" << lambda; - return; - } - - // try with a smaller update - lambda /= 2.0; - } - } - - /*! - * \brief Returns the maximum relative shift between two vectors of - * primary variables. - * - * \param priVars1 The first vector of primary variables - * \param priVars2 The second vector of primary variables - */ - template<class PrimaryVariables> - Scalar relativeShiftAtDof_(const PrimaryVariables &priVars1, - const PrimaryVariables &priVars2) - { - Scalar result = 0.0; - using std::abs; - using std::max; - // iterate over all primary variables - for (int j = 0; j < PrimaryVariables::dimension; ++j) { - Scalar eqErr = abs(priVars1[j] - priVars2[j]); - eqErr /= max<Scalar>(1.0,abs(priVars1[j] + priVars2[j])/2); - - result = max(result, eqErr); - } - return result; - } - - //! The communication object - Communication comm_; - - //! The time loop for stationary simulations - std::shared_ptr<TimeLoop<Scalar>> timeLoop_; - - //! message stream to be displayed at the end of iterations - std::ostringstream endIterMsgStream_; - - //! switches on/off verbosity - bool verbose_; - - // shift criterion variables - Scalar shift_; - Scalar lastShift_; - Scalar shiftTolerance_; - - // residual criterion variables - Scalar reduction_; - Scalar residualNorm_; - Scalar lastReduction_; - Scalar initialResidual_; - Scalar reductionTolerance_; - Scalar residualTolerance_; - - //! optimal number of iterations we want to achieve - int targetSteps_; - //! maximum number of iterations we do before giving up - int maxSteps_; - //! actual number of steps done so far - int numSteps_; - - // further parameters - bool enablePartialReassemble_; - bool useLineSearch_; - bool enableAbsoluteResidualCriterion_; - bool enableShiftCriterion_; - bool enableResidualCriterion_; - bool satisfyResidualAndShiftCriterion_; - - //! the parameter group for getting parameters from the parameter tree - std::string paramGroup_; -}; - -} // end namespace Dumux - -#endif diff --git a/dumux/nonlinear/newtonmethod.hh b/dumux/nonlinear/newtonmethod.hh deleted file mode 100644 index 7264b3cedff741530657ae7a4a9e5a5ffae4a748..0000000000000000000000000000000000000000 --- a/dumux/nonlinear/newtonmethod.hh +++ /dev/null @@ -1,222 +0,0 @@ -// -*- 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 Nonlinear - * \brief The algorithmic part of the multi dimensional newton method. - * - * In order to use the method you need a Newtoncontroller - */ -#ifndef DUMUX_NEWTONMETHOD_HH -#define DUMUX_NEWTONMETHOD_HH - -#include <memory> -#include <iostream> - -#include <dune/common/timer.hh> -#include <dune/istl/istlexception.hh> - -#include <dumux/common/exceptions.hh> -#include <dumux/common/properties.hh> -#include <dumux/common/parameters.hh> -#include <dune/common/deprecated.hh> - -#warning "This file is deprecated. Use NewtonSolver instead." - -namespace Dumux { - -/*! - * \ingroup Newton - * \ingroup Nonlinear - * \brief The algorithmic part of the multi dimensional newton method. - * - * \tparam NewtonController the controller class is the driver implementation - * \tparam JacobianAssembler an assembler for the Jacobian and the residual - * \tparam LinearSolver the linear solver used to solve one iteration - */ -template <class NewtonController, class JacobianAssembler, class LinearSolver> -class DUNE_DEPRECATED_MSG("Use NewtonSolver instead.") NewtonMethod -{ - //! provide an interface as a form of type erasure - //! this is the minimal requirements a convergence write passed to a newton method has to fulfill - struct ConvergenceWriterInferface - { - template<class SolutionVector> - void write(const SolutionVector &uLastIter, const SolutionVector &deltaU, const SolutionVector &residual) {} - }; - -public: - NewtonMethod(std::shared_ptr<NewtonController> controller, - std::shared_ptr<JacobianAssembler> assembler, - std::shared_ptr<LinearSolver> linearSolver, - const std::string& modelParamGroup = "") - : controller_(controller) - , assembler_(assembler) - , linearSolver_(linearSolver) - { - // set the linear system (matrix & residual) in the assembler - assembler_->setLinearSystem(); - - // set a different default for the linear solver residual reduction - // within the Newton the linear solver doesn't need to solve too exact - using Scalar = typename LinearSolver::Scalar; - linearSolver_->setResidualReduction(getParamFromGroup<Scalar>(modelParamGroup, "LinearSolver.ResidualReduction", 1e-6)); - } - - /*! - * \brief Run the newton method to solve a non-linear system. - * The controller is responsible for all the strategic decisions. - */ - template<class SolutionVector, class ConvergenceWriter = ConvergenceWriterInferface> - bool solve(SolutionVector& uCurrentIter, const std::unique_ptr<ConvergenceWriter>& convWriter = nullptr) - { - try - { - // the given solution is the initial guess - SolutionVector uLastIter(uCurrentIter); - SolutionVector deltaU(uCurrentIter); - - Dune::Timer assembleTimer(false); - Dune::Timer solveTimer(false); - Dune::Timer updateTimer(false); - - // tell the controller that we begin solving - controller_->newtonBegin(uCurrentIter); - - // execute the method as long as the controller thinks - // that we should do another iteration - while (controller_->newtonProceed(uCurrentIter, controller_->newtonConverged())) - { - // notify the controller that we're about to start - // a new timestep - controller_->newtonBeginStep(uCurrentIter); - - // make the current solution to the old one - if (controller_->newtonNumSteps() > 0) - uLastIter = uCurrentIter; - - if (controller_->verbose()) { - std::cout << "Assemble: r(x^k) = dS/dt + div F - q; M = grad r"; - std::cout.flush(); - } - - /////////////// - // assemble - /////////////// - - // linearize the problem at the current solution - assembleTimer.start(); - controller_->assembleLinearSystem(*assembler_, uCurrentIter); - assembleTimer.stop(); - - /////////////// - // linear solve - /////////////// - - // Clear the current line using an ansi escape - // sequence. for an explanation see - // http://en.wikipedia.org/wiki/ANSI_escape_code - const char clearRemainingLine[] = { 0x1b, '[', 'K', 0 }; - - if (controller_->verbose()) { - std::cout << "\rSolve: M deltax^k = r"; - std::cout << clearRemainingLine; - std::cout.flush(); - } - - // solve the resulting linear equation system - solveTimer.start(); - - // set the delta vector to zero before solving the linear system! - deltaU = 0; - // ask the controller to solve the linearized system - controller_->solveLinearSystem(*linearSolver_, - assembler_->jacobian(), - deltaU, - assembler_->residual()); - solveTimer.stop(); - - /////////////// - // update - /////////////// - if (controller_->verbose()) { - std::cout << "\rUpdate: x^(k+1) = x^k - deltax^k"; - std::cout << clearRemainingLine; - std::cout.flush(); - } - - updateTimer.start(); - // update the current solution (i.e. uOld) with the delta - // (i.e. u). The result is stored in u - controller_->newtonUpdate(*assembler_, uCurrentIter, uLastIter, deltaU); - updateTimer.stop(); - - // tell the controller that we're done with this iteration - controller_->newtonEndStep(*assembler_, uCurrentIter, uLastIter); - - // if a convergence writer was specified compute residual and write output - if (convWriter) - { - assembler_->assembleResidual(uCurrentIter); - convWriter->write(uLastIter, deltaU, assembler_->residual()); - } - } - - // tell controller we are done - controller_->newtonEnd(); - - // reset state if newton failed - if (!controller_->newtonConverged()) - { - controller_->newtonFail(*assembler_, uCurrentIter); - return false; - } - - // tell controller we converged successfully - controller_->newtonSucceed(); - - if (controller_->verbose()) { - const auto elapsedTot = assembleTimer.elapsed() + solveTimer.elapsed() + updateTimer.elapsed(); - std::cout << "Assemble/solve/update time: " - << assembleTimer.elapsed() << "(" << 100*assembleTimer.elapsed()/elapsedTot << "%)/" - << solveTimer.elapsed() << "(" << 100*solveTimer.elapsed()/elapsedTot << "%)/" - << updateTimer.elapsed() << "(" << 100*updateTimer.elapsed()/elapsedTot << "%)" - << "\n"; - } - return true; - - } - catch (const NumericalProblem &e) - { - if (controller_->verbose()) - std::cout << "Newton: Caught exception: \"" << e.what() << "\"\n"; - controller_->newtonFail(*assembler_, uCurrentIter); - return false; - } - } - -private: - std::shared_ptr<NewtonController> controller_; - std::shared_ptr<JacobianAssembler> assembler_; - std::shared_ptr<LinearSolver> linearSolver_; -}; - -} // end namespace Dumux - -#endif diff --git a/dumux/nonlinear/newtonsolver.hh b/dumux/nonlinear/newtonsolver.hh index b50dbd7c63ca6454e4dbd1c36eb56bad8235b2ac..82f9eca3de8b4fe84564362b67d6c6630fe32759 100644 --- a/dumux/nonlinear/newtonsolver.hh +++ b/dumux/nonlinear/newtonsolver.hh @@ -19,9 +19,9 @@ /*! * \file * \ingroup Nonlinear - * \brief Reference implementation of a controller class for the Newton solver. + * \brief Reference implementation of the Newton solver. * - * Usually this controller should be sufficient. + * Usually this solver should be sufficient. */ #ifndef DUMUX_NEWTON_SOLVER_HH #define DUMUX_NEWTON_SOLVER_HH @@ -61,11 +61,12 @@ struct supportsPartialReassembly /*! * \ingroup Nonlinear - * \brief An implementation of a Newton controller - * \tparam Scalar the scalar type + * \brief An implementation of a Newton solver + * \tparam Assembler the assembler + * \tparam LinearSolver the linear solver * \tparam Comm the communication object used to communicate with all processes * \note If you want to specialize only some methods but are happy with the - * defaults of the reference controller, derive your controller from + * defaults of the reference solver, derive your solver from * this class and simply overload the required methods. */ template <class Assembler, class LinearSolver, @@ -214,7 +215,7 @@ public: /*! * \brief Run the newton method to solve a non-linear system. - * The controller is responsible for all the strategic decisions. + * The solver is responsible for all the strategic decisions. */ void solve(SolutionVector& uCurrentIter, const std::unique_ptr<ConvergenceWriter>& convWriter = nullptr) { @@ -471,7 +472,7 @@ public: endIterMsgStream_.str(""); // When the Newton iterations are done: ask the model to check whether it makes sense - // TODO: how do we realize this? -> do this here in the newton controller + // TODO: how do we realize this? -> do this here in the newton solver // model_().checkPlausibility(); } @@ -620,7 +621,7 @@ private: /*! * \brief Run the newton method to solve a non-linear system. - * The controller is responsible for all the strategic decisions. + * The solver is responsible for all the strategic decisions. */ bool solve_(SolutionVector& uCurrentIter, const std::unique_ptr<ConvergenceWriter>& convWriter = nullptr) { @@ -643,11 +644,11 @@ private: { newtonBegin(uCurrentIter); - // execute the method as long as the controller thinks + // execute the method as long as the solver thinks // that we should do another iteration while (newtonProceed(uCurrentIter, newtonConverged())) { - // notify the controller that we're about to start + // notify the solver that we're about to start // a new timestep newtonBeginStep(uCurrentIter); @@ -708,7 +709,7 @@ private: newtonUpdate(uCurrentIter, uLastIter, deltaU); updateTimer.stop(); - // tell the controller that we're done with this iteration + // tell the solver that we're done with this iteration newtonEndStep(uCurrentIter, uLastIter); // if a convergence writer was specified compute residual and write output @@ -719,7 +720,7 @@ private: } } - // tell controller we are done + // tell solver we are done newtonEnd(); // reset state if newton failed @@ -729,7 +730,7 @@ private: return false; } - // tell controller we converged successfully + // tell solver we converged successfully newtonSucceed(); if (verbose_) { diff --git a/dumux/nonlinear/privarswitchnewtonsolver.hh b/dumux/nonlinear/privarswitchnewtonsolver.hh index 39359fdc1ec8fd18a40e5ff8340fe9d4fbac7b25..f28bb46a38d52e0d3120049d6dc2cea037788db9 100644 --- a/dumux/nonlinear/privarswitchnewtonsolver.hh +++ b/dumux/nonlinear/privarswitchnewtonsolver.hh @@ -19,9 +19,7 @@ /*! * \file * \ingroup PorousmediumCompositional - * \brief Reference implementation of a controller class for the Newton solver. - * - * Usually this controller should be sufficient. + * \copydoc Dumux::PriVarSwitchNewtonSolver */ #ifndef DUMUX_PRIVARSWITCH_NEWTON_SOLVER_HH #define DUMUX_PRIVARSWITCH_NEWTON_SOLVER_HH @@ -37,9 +35,7 @@ namespace Dumux { /*! * \ingroup PorousmediumCompositional - * \brief A newton controller that handles primary variable switches - * \todo make this independent of TypeTag by making PrimaryVariableSwitch a template argument - * and extracting everything model specific from there + * \brief A newton solver that handles primary variable switches */ template <class Assembler, class LinearSolver, class PrimaryVariableSwitch> class PriVarSwitchNewtonSolver : public NewtonSolver<Assembler, LinearSolver> diff --git a/dumux/nonlinear/staggerednewtoncontroller.hh b/dumux/nonlinear/staggerednewtoncontroller.hh deleted file mode 100644 index bedcf6d4ad2770325dfdddf33514827b232d5b3d..0000000000000000000000000000000000000000 --- a/dumux/nonlinear/staggerednewtoncontroller.hh +++ /dev/null @@ -1,299 +0,0 @@ -// -*- 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 Nonlinear - * \ingroup StaggeredDiscretization - * \brief A newton controller for staggered finite volume schemes - */ -#ifndef DUMUX_STAGGERED_NEWTON_CONTROLLER_HH -#define DUMUX_STAGGERED_NEWTON_CONTROLLER_HH - -#include <dune/common/indices.hh> -#include <dune/common/hybridutilities.hh> -#include <dune/common/fvector.hh> -#include <dune/istl/bvector.hh> - -#include <dumux/common/exceptions.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/linear/linearsolveracceptsmultitypematrix.hh> -#include <dumux/linear/matrixconverter.hh> -#include <dune/common/deprecated.hh> - -#warning "This file is deprecated. Use NewtonSolver instead." - -namespace Dumux { - -/*! - * \ingroup Nonlinear - * \ingroup StaggeredDiscretization - * \brief A newton controller for staggered finite volume schemes - */ - -template <class Scalar, - class Comm = Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> > -class DUNE_DEPRECATED_MSG("Use NewtonSolver instead.") -StaggeredNewtonController : public NewtonController<Scalar, Comm> -{ - using ParentType = NewtonController<Scalar, Comm>; - -public: - using ParentType::ParentType; - - /*! - * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. - * - * Throws Dumux::NumericalProblem if the linear solver didn't - * converge. - * - * If the linear solver doesn't accept multitype matrices we copy the matrix - * into a 1x1 block BCRS matrix for solving. - * - * \param ls the linear solver - * \param A The matrix of the linear system of equations - * \param x The vector which solves the linear system - * \param b The right hand side of the linear system - */ - template<class LinearSolver, class JacobianMatrix, class SolutionVector> - void solveLinearSystem(LinearSolver& ls, - JacobianMatrix& A, - SolutionVector& x, - SolutionVector& b) - { - // check matrix sizes - assert(checkMatrix_(A) && "Sub blocks of MultiType matrix have wrong sizes!"); - - try - { - if (this->numSteps_ == 0) - { - Scalar norm2 = b.two_norm2(); - if (this->comm().size() > 1) - norm2 = this->comm().sum(norm2); - - using std::sqrt; - this->initialResidual_ = sqrt(norm2); - } - - // solve by calling the appropriate implementation depending on whether the linear solver - // is capable of handling MultiType matrices or not - bool converged = solveLinearSystem_(ls, A, x, b, - std::integral_constant<bool, linearSolverAcceptsMultiTypeMatrix<LinearSolver>::value>()); - - // make sure all processes converged - int convergedRemote = converged; - if (this->comm().size() > 1) - convergedRemote = this->comm().min(converged); - - if (!converged) { - DUNE_THROW(NumericalProblem, - "Linear solver did not converge"); - } - else if (!convergedRemote) { - DUNE_THROW(NumericalProblem, - "Linear solver did not converge on a remote process"); - } - } - catch (const Dune::Exception &e) { - // make sure all processes converged - int converged = 0; - if (this->comm().size() > 1) - converged = this->comm().min(converged); - - NumericalProblem p; - p.message(e.what()); - throw p; - } - } - - - - /*! - * \brief Update the current solution with a delta vector. - * - * The error estimates required for the newtonConverged() and - * newtonProceed() methods should be updated inside this method. - * - * Different update strategies, such as line search and chopped - * updates can be implemented. The default behavior is just to - * subtract deltaU from uLastIter, i.e. - * \f[ u^{k+1} = u^k - \Delta u^k \f] - * - * \param assembler The assembler for Jacobian and residual - * \param uCurrentIter The solution vector after the current iteration - * \param uLastIter The solution vector after the last iteration - * \param deltaU The delta as calculated from solving the linear - * system of equations. This parameter also stores - * the updated solution. - */ - template<class JacobianAssembler, class SolutionVector> - void newtonUpdate(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - if (this->enableShiftCriterion_) - this->newtonUpdateShift(uLastIter, deltaU); - - if (this->useLineSearch_) - { - this->lineSearchUpdate_(assembler, uCurrentIter, uLastIter, deltaU); - } - else { - using namespace Dune::Hybrid; - forEach(integralRange(Dune::Hybrid::size(uLastIter)), [&](const auto dofTypeIdx) - { - for (unsigned int i = 0; i < uLastIter[dofTypeIdx].size(); ++i) - { - uCurrentIter[dofTypeIdx][i] = uLastIter[dofTypeIdx][i]; - uCurrentIter[dofTypeIdx][i] -= deltaU[dofTypeIdx][i]; - } - }); - - if (this->enableResidualCriterion_) - { - this->residualNorm_ = assembler.residualNorm(uCurrentIter); - this->reduction_ = this->residualNorm_; - this->reduction_ /= this->initialResidual_; - } - } - - // update the variables class to the new solution - assembler.gridVariables().update(uCurrentIter); - } - - /*! - * \brief Update the maximum relative shift of the solution compared to - * the previous iteration. - * - * \param uLastIter The current iterative solution - * \param deltaU The difference between the current and the next solution - */ - template<class SolutionVector> - void newtonUpdateShift(const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - this->shift_ = 0; - - using namespace Dune::Hybrid; - forEach(integralRange(Dune::Hybrid::size(uLastIter)), [&](const auto dofTypeIdx) - { - for (int i = 0; i < int(uLastIter[dofTypeIdx].size()); ++i) - { - auto uNewI = uLastIter[dofTypeIdx][i]; - uNewI -= deltaU[dofTypeIdx][i]; - - Scalar shiftAtDof = this->relativeShiftAtDof_(uLastIter[dofTypeIdx][i], uNewI); - this->shift_ = std::max(this->shift_, shiftAtDof); - } - }); - - if (this->comm().size() > 1) - this->shift_ = this->comm().max(this->shift_); - } - -private: - /*! - * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. - * - * Throws Dumux::NumericalProblem if the linear solver didn't - * converge. - * - * Specialization for linear solvers that can handle MultiType matrices. - * - */ - template<class LinearSolver, class JacobianMatrix, class SolutionVector> - bool solveLinearSystem_(LinearSolver& ls, - JacobianMatrix& A, - SolutionVector& x, - SolutionVector& b, - std::true_type) - { - // TODO: automatically derive the precondBlockLevel - return ls.template solve</*precondBlockLevel=*/2>(A, x, b); - } - - /*! - * \brief Solve the linear system of equations \f$\mathbf{A}x - b = 0\f$. - * - * Throws Dumux::NumericalProblem if the linear solver didn't - * converge. - * - * Specialization for linear solvers that cannot handle MultiType matrices. - * We copy the matrix into a 1x1 block BCRS matrix before solving. - * - */ - template<class LinearSolver, class JacobianMatrix, class SolutionVector> - bool solveLinearSystem_(LinearSolver& ls, - JacobianMatrix& A, - SolutionVector& x, - SolutionVector& b, - std::false_type) - { - // create the bcrs matrix the IterativeSolver backend can handle - const auto M = MatrixConverter<JacobianMatrix>::multiTypeToBCRSMatrix(A); - - // get the new matrix sizes - const std::size_t numRows = M.N(); - assert(numRows == M.M()); - - // create the vector the IterativeSolver backend can handle - const auto bTmp = VectorConverter<SolutionVector>::multiTypeToBlockVector(b); - assert(bTmp.size() == numRows); - - // create a blockvector to which the linear solver writes the solution - using VectorBlock = typename Dune::FieldVector<Scalar, 1>; - using BlockVector = typename Dune::BlockVector<VectorBlock>; - BlockVector y(numRows); - - // solve - const bool converged = ls.solve(M, y, bTmp); - - // copy back the result y into x - if(converged) - VectorConverter<SolutionVector>::retrieveValues(x, y); - - return converged; - } - - //! helper method to assure the MultiType matrix's sub blocks have the correct sizes - template<class JacobianMatrix> - bool checkMatrix_(const JacobianMatrix& A) - { - bool matrixHasCorrectSize = true; - using namespace Dune::Hybrid; - using namespace Dune::Indices; - forEach(A, [&matrixHasCorrectSize](const auto& rowOfMultiTypeMatrix) - { - const auto numRowsLeftMostBlock = rowOfMultiTypeMatrix[_0].N(); - - forEach(rowOfMultiTypeMatrix, [&matrixHasCorrectSize, &numRowsLeftMostBlock](const auto& subBlock) - { - if (subBlock.N() != numRowsLeftMostBlock) - matrixHasCorrectSize = false; - }); - }); - return matrixHasCorrectSize; - } - -}; - -} // end namespace Dumux - -#endif diff --git a/dumux/porousmediumflow/2pnc/CMakeLists.txt b/dumux/porousmediumflow/2pnc/CMakeLists.txt index 612765aa72256d6bb3e314a3c613c4ce6021f072..5e3c930c89509e68756c958178cff2e748398917 100644 --- a/dumux/porousmediumflow/2pnc/CMakeLists.txt +++ b/dumux/porousmediumflow/2pnc/CMakeLists.txt @@ -3,7 +3,6 @@ install(FILES indices.hh model.hh -newtoncontroller.hh primaryvariableswitch.hh volumevariables.hh vtkoutputfields.hh diff --git a/dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh b/dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh deleted file mode 100644 index 553414dbbcfd293ea1ea8d7755b2444fd5f2ead4..0000000000000000000000000000000000000000 --- a/dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh +++ /dev/null @@ -1,220 +0,0 @@ -// -*- 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 PorousmediumCompositional - * \brief Reference implementation of a controller class for the Newton solver. - * - * Usually this controller should be sufficient. - */ -#ifndef DUMUX_PRIVARSWITCH_NEWTON_CONTROLLER_HH -#define DUMUX_PRIVARSWITCH_NEWTON_CONTROLLER_HH - -#include <memory> - -#include <dumux/common/properties.hh> -#include <dumux/common/parameters.hh> -#include <dumux/discretization/methods.hh> -#include <dumux/discretization/elementsolution.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dune/common/deprecated.hh> - -#warning "This file is deprecated. Use PriVarSwitchNewtonSolver instead." - -namespace Dumux { - -/*! - * \ingroup PorousmediumCompositional - * \brief A newton controller that handles primary variable switches - * \todo make this independent of TypeTag by making PrimaryVariableSwitch a template argument - * and extracting everything model specific from there - * \todo Implement for volume variable caching enabled - */ -template <class TypeTag> -class DUNE_DEPRECATED_MSG("Use PriVarSwitchNewtonSolver instead.") -PriVarSwitchNewtonController : public NewtonController<typename GET_PROP_TYPE(TypeTag, Scalar)> -{ - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using ParentType = NewtonController<Scalar>; - using PrimaryVariableSwitch = typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); - - static constexpr bool isBox = GET_PROP_TYPE(TypeTag, FVGridGeometry)::discMethod == DiscretizationMethod::box; - -public: - using ParentType::ParentType; - - /*! - * \brief Returns true if the error of the solution is below the - * tolerance. - */ - bool newtonConverged() const - { - if (switchedInLastIteration_) - return false; - - return ParentType::newtonConverged(); - } - - /*! - * - * \brief Called before the Newton method is applied to an - * non-linear system of equations. - * - * \param u The initial solution - */ - template<class SolutionVector> - void newtonBegin(const SolutionVector &u) - { - ParentType::newtonBegin(u); - priVarSwitch_ = std::make_unique<PrimaryVariableSwitch>(u.size()); - } - - /*! - * \brief Indicates that one Newton iteration was finished. - * - * \param assembler The jacobian assembler - * \param uCurrentIter The solution after the current Newton iteration - * \param uLastIter The solution at the beginning of the current Newton iteration - */ - template<class JacobianAssembler, class SolutionVector> - void newtonEndStep(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - ParentType::newtonEndStep(assembler, uCurrentIter, uLastIter); - - // update the variable switch (returns true if the pri vars at at least one dof were switched) - // for disabled grid variable caching - const auto& fvGridGeometry = assembler.fvGridGeometry(); - const auto& problem = assembler.problem(); - auto& gridVariables = assembler.gridVariables(); - - // invoke the primary variable switch - switchedInLastIteration_ = priVarSwitch_->update(uCurrentIter, gridVariables, - problem, fvGridGeometry); - - if(switchedInLastIteration_) - { - for (const auto& element : elements(fvGridGeometry.gridView())) - { - // if the volume variables are cached globally, we need to update those where the primary variables have been switched - updateSwitchedVolVars_(std::integral_constant<bool, GET_PROP_VALUE(TypeTag, EnableGridVolumeVariablesCache)>(), - element, assembler, uCurrentIter, uLastIter); - - // if the flux variables are cached globally, we need to update those where the primary variables have been switched - // (not needed for box discretization) - updateSwitchedFluxVarsCache_(std::integral_constant<bool, (GET_PROP_VALUE(TypeTag, EnableGridFluxVariablesCache) && !isBox)>(), - element, assembler, uCurrentIter, uLastIter); - } - } - } - - /*! - * \brief Called if the Newton method ended - * (not known yet if we failed or succeeded) - */ - void newtonEnd() - { - ParentType::newtonEnd(); - - // in any way, we have to reset the switch flag - switchedInLastIteration_ = false; - // free some memory - priVarSwitch_.release(); - } - -private: - - /*! - * \brief Update the volume variables whose primary variables were - switched. Required when volume variables are cached globally. - */ - template<class Element, class JacobianAssembler, class SolutionVector> - void updateSwitchedVolVars_(std::true_type, - const Element& element, - JacobianAssembler& assembler, - const SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - const auto& fvGridGeometry = assembler.fvGridGeometry(); - const auto& problem = assembler.problem(); - auto& gridVariables = assembler.gridVariables(); - - // make sure FVElementGeometry is bound to the element - auto fvGeometry = localView(fvGridGeometry); - fvGeometry.bindElement(element); - - // update the secondary variables if global caching is enabled - for (auto&& scv : scvs(fvGeometry)) - { - const auto dofIdxGlobal = scv.dofIndex(); - if (priVarSwitch_->wasSwitched(dofIdxGlobal)) - { - const auto elemSol = elementSolution(element, uCurrentIter, fvGridGeometry); - auto& volVars = gridVariables.curGridVolVars().volVars(scv); - volVars.update(elemSol, problem, element, scv); - } - } - } - - /*! - * \brief Update the fluxVars cache for dof whose primary variables were - switched. Required when flux variables are cached globally. - */ - template<class Element, class JacobianAssembler, class SolutionVector> - void updateSwitchedFluxVarsCache_(std::true_type, - const Element& element, - JacobianAssembler& assembler, - const SolutionVector &uCurrentIter, - const SolutionVector &uLastIter) - { - const auto& fvGridGeometry = assembler.fvGridGeometry(); - auto& gridVariables = assembler.gridVariables(); - - // update the flux variables if global caching is enabled - const auto dofIdxGlobal = fvGridGeometry.dofMapper().index(element); - - if (priVarSwitch_->wasSwitched(dofIdxGlobal)) - { - // make sure FVElementGeometry and the volume variables are bound - auto fvGeometry = localView(fvGridGeometry); - fvGeometry.bind(element); - auto curElemVolVars = localView(gridVariables.curGridVolVars()); - curElemVolVars.bind(element, fvGeometry, uCurrentIter); - gridVariables.gridFluxVarsCache().updateElement(element, fvGeometry, curElemVolVars); - } - } - - //! brief Do nothing when volume variables are not cached globally. - template <typename... Args> - void updateSwitchedVolVars_(std::false_type, Args&&... args) const {} - - //! brief Do nothing when flux variables are not cached globally. - template <typename... Args> - void updateSwitchedFluxVarsCache_(std::false_type, Args&&... args) const {} - - //! the class handling the primary variable switch - std::unique_ptr<PrimaryVariableSwitch> priVarSwitch_; - //! if we switched primary variables in the last iteration - bool switchedInLastIteration_ = false; -}; - -} // end namespace Dumux - -#endif diff --git a/dumux/porousmediumflow/nonequilibrium/CMakeLists.txt b/dumux/porousmediumflow/nonequilibrium/CMakeLists.txt index 31fa8eb04f184261a2a39e84587cba7c9357a556..09252e0484f9b439732e7a35f88ab9c56104cc24 100644 --- a/dumux/porousmediumflow/nonequilibrium/CMakeLists.txt +++ b/dumux/porousmediumflow/nonequilibrium/CMakeLists.txt @@ -4,8 +4,8 @@ install(FILES localresidual.hh gridvariables.hh indices.hh -newtoncontroller.hh volumevariables.hh vtkoutputfields.hh model.hh +newtonsolver.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dumux/porousmediumflow/nonequilibrium) diff --git a/dumux/porousmediumflow/nonequilibrium/newtoncontroller.hh b/dumux/porousmediumflow/nonequilibrium/newtonsolver.hh similarity index 58% rename from dumux/porousmediumflow/nonequilibrium/newtoncontroller.hh rename to dumux/porousmediumflow/nonequilibrium/newtonsolver.hh index b1bfec283b6bdd84b3ff7c11e2059bb879cab7df..838d2f5e1c480b20ad31f731eaf1bba2d794eada 100644 --- a/dumux/porousmediumflow/nonequilibrium/newtoncontroller.hh +++ b/dumux/porousmediumflow/nonequilibrium/newtonsolver.hh @@ -19,43 +19,35 @@ /*! * \file * \ingroup PorousmediumNonEquilibriumModel - * \brief A MpNc specific controller for the newton solver. - * This controller calls the velocity averaging in the model after each iteration. + * \brief A MpNc specific newton solver. + * This solver calls the velocity averaging in the model after each iteration. */ -#ifndef DUMUX_NONEQUILIBRIUM_NEWTON_CONTROLLER_HH -#define DUMUX_NONEQUILIBRIUM_NEWTON_CONTROLLER_HH +#ifndef DUMUX_NONEQUILIBRIUM_NEWTON_SOLVER_HH +#define DUMUX_NONEQUILIBRIUM_NEWTON_SOLVER_HH -#include <algorithm> - -#include <dumux/nonlinear/newtoncontroller.hh> +#include <dumux/nonlinear/newtonsolver.hh> namespace Dumux { /*! * \ingroup PorousmediumNonEquilibriumModel - * \brief A nonequilibrium specific controller for the newton solver. - * This controller calls the velocity averaging in the problem after each iteration. + * \brief A nonequilibrium specific newton solver. + * This solver calls the velocity averaging in the problem after each iteration. */ -template <class Scalar, - class Comm = Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> > -class NonEquilibriumNewtonController : public NewtonController<Scalar, Comm> +template <class Assembler, class LinearSolver> +class NonEquilibriumNewtonSolver : public NewtonSolver<Assembler, LinearSolver> { - using ParentType = NewtonController<Scalar, Comm>; + using ParentType = NewtonSolver<Assembler, LinearSolver>; + using SolutionVector = typename Assembler::ResidualType; public: using ParentType::ParentType; - template<class JacobianAssembler, class SolutionVector> - void newtonUpdate(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) + void newtonEndStep(SolutionVector &uCurrentIter, + const SolutionVector &uLastIter) final { - ParentType::newtonUpdate(assembler, - uCurrentIter, - uLastIter, - deltaU); + ParentType::newtonEndStep(uCurrentIter, uLastIter); - auto& gridVariables = assembler.gridVariables(); + 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); @@ -63,4 +55,4 @@ public: }; } // end namespace Dumux -#endif // DUMUX_VELO_PROB_AVERAGE_NEWTON_CONTROLLER_HH +#endif // DUMUX_NONEQUILIBRIUM_NEWTON_SOLVER_HH diff --git a/dumux/porousmediumflow/richards/CMakeLists.txt b/dumux/porousmediumflow/richards/CMakeLists.txt index 2929d226a4f0d49ebe59f30739c2c4973dfaf5cf..199fc1455f2ec91649605c0ee3ca855fedddc01e 100644 --- a/dumux/porousmediumflow/richards/CMakeLists.txt +++ b/dumux/porousmediumflow/richards/CMakeLists.txt @@ -4,7 +4,8 @@ install(FILES indices.hh localresidual.hh model.hh -newtoncontroller.hh +newtonsolver.hh +privarswitchnewtonsolver.hh primaryvariableswitch.hh volumevariables.hh vtkoutputfields.hh diff --git a/dumux/porousmediumflow/richards/newtoncontroller.hh b/dumux/porousmediumflow/richards/newtoncontroller.hh deleted file mode 100644 index e6a7cccd48230c9d34d1cdc9df2434dad029a446..0000000000000000000000000000000000000000 --- a/dumux/porousmediumflow/richards/newtoncontroller.hh +++ /dev/null @@ -1,122 +0,0 @@ -// -*- 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 RichardsModel - * \brief A Richards model specific controller for the newton solver. - */ -#ifndef DUMUX_RICHARDS_NEWTON_CONTROLLER_HH -#define DUMUX_RICHARDS_NEWTON_CONTROLLER_HH - -#include <dumux/common/properties.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/discretization/elementsolution.hh> -#include <dune/common/deprecated.hh> - -#warning "This file is deprecated. Use RichardsNewtonSolver instead." - -namespace Dumux { -/*! - * \ingroup RichardsModel - * \brief A Richards model specific controller for the newton solver. - * - * This controller 'knows' what a 'physically meaningful' solution is - * and can thus do update smarter than the plain Newton controller. - * - * \todo make this typetag independent by extracting anything model specific from assembler - * or from possible ModelTraits. - */ -template <class TypeTag> -class DUNE_DEPRECATED_MSG("Use RichardsNewtonSolver instead.") -RichardsNewtonController : public NewtonController<typename GET_PROP_TYPE(TypeTag, Scalar)> -{ - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using ParentType = NewtonController<Scalar>; - - using MaterialLaw = typename GET_PROP_TYPE(TypeTag, MaterialLaw); - using Indices = typename GET_PROP_TYPE(TypeTag, Indices); - enum { pressureIdx = Indices::pressureIdx }; - -public: - using ParentType::ParentType; - - /*! - * \brief Update the current solution of the newton method - * - * This is basically the step - * \f[ u^{k+1} = u^k - \Delta u^k \f] - * - * \param assembler The Jacobian assembler - * \param uCurrentIter The solution after the current Newton iteration \f$ u^{k+1} \f$ - * \param uLastIter The solution after the last Newton iteration \f$ u^k \f$ - * \param deltaU The vector of differences between the last - * iterative solution and the next one \f$ \Delta u^k \f$ - */ - template<class JacobianAssembler, class SolutionVector> - void newtonUpdate(JacobianAssembler& assembler, - SolutionVector &uCurrentIter, - const SolutionVector &uLastIter, - const SolutionVector &deltaU) - { - ParentType::newtonUpdate(assembler, uCurrentIter, uLastIter, deltaU); - if (!this->useLineSearch_ && getParamFromGroup<bool>(this->paramGroup(), "Newton.EnableChop")) - { - // do not clamp anything after 5 iterations - if (this->numSteps_ > 4) - return; - - // clamp saturation change to at most 20% per iteration - const auto& fvGridGeometry = assembler.fvGridGeometry(); - for (const auto& element : elements(fvGridGeometry.gridView())) - { - auto fvGeometry = localView(fvGridGeometry); - fvGeometry.bindElement(element); - - for (auto&& scv : scvs(fvGeometry)) - { - auto dofIdxGlobal = scv.dofIndex(); - - // calculate the old wetting phase saturation - const auto& spatialParams = assembler.problem().spatialParams(); - const auto elemSol = elementSolution(element, uCurrentIter, fvGridGeometry); - const auto& materialLawParams = spatialParams.materialLawParams(element, scv, elemSol); - const Scalar pcMin = MaterialLaw::pc(materialLawParams, 1.0); - const Scalar pw = uLastIter[dofIdxGlobal][pressureIdx]; - using std::max; - const Scalar pn = max(assembler.problem().nonWettingReferencePressure(), pw + pcMin); - const Scalar pcOld = pn - pw; - const Scalar SwOld = max(0.0, MaterialLaw::sw(materialLawParams, pcOld)); - - // convert into minimum and maximum wetting phase - // pressures - const Scalar pwMin = pn - MaterialLaw::pc(materialLawParams, SwOld - 0.2); - const Scalar pwMax = pn - MaterialLaw::pc(materialLawParams, SwOld + 0.2); - - // clamp the result - using std::min; using std::max; - uCurrentIter[dofIdxGlobal][pressureIdx] = max(pwMin, min(uCurrentIter[dofIdxGlobal][pressureIdx], pwMax)); - } - } - } - } -}; - -} // end namespace Dumux - -#endif diff --git a/dumux/porousmediumflow/richards/newtonsolver.hh b/dumux/porousmediumflow/richards/newtonsolver.hh index 1cd9e43786968cf36d7ea6ad787d2a19444934f6..0c89333066704885e2da39a4bb01a5b7e436f4b4 100644 --- a/dumux/porousmediumflow/richards/newtonsolver.hh +++ b/dumux/porousmediumflow/richards/newtonsolver.hh @@ -33,7 +33,7 @@ namespace Dumux { * \ingroup RichardsModel * \brief A Richards model specific newton solver. * - * This controller 'knows' what a 'physically meaningful' solution is + * This solver 'knows' what a 'physically meaningful' solution is * and can thus do update smarter than the plain Newton solver. * * \todo make this typetag independent by extracting anything model specific from assembler diff --git a/dumux/porousmediumflow/richardsnc/model.hh b/dumux/porousmediumflow/richardsnc/model.hh index 5dad8ad9cf306c896f0dd2328063dd788f8f807e..91720a3e1cf335b8c422f38e6ed20df4ac1220bb 100644 --- a/dumux/porousmediumflow/richardsnc/model.hh +++ b/dumux/porousmediumflow/richardsnc/model.hh @@ -70,7 +70,6 @@ #include <dumux/common/properties.hh> #include <dumux/porousmediumflow/compositional/localresidual.hh> -#include <dumux/porousmediumflow/richards/newtoncontroller.hh> #include <dumux/material/spatialparams/fv1p.hh> #include <dumux/material/fluidmatrixinteractions/diffusivitymillingtonquirk.hh> @@ -148,6 +147,10 @@ SET_INT_PROP(RichardsNC, ReplaceCompEqIdx, 0); //! define the VolumeVariables SET_TYPE_PROP(RichardsNC, VolumeVariables, RichardsNCVolumeVariables<TypeTag>); +//! The default richardsnc model computes no diffusion in the air phase +//! Turning this on leads to the extended Richards equation (see e.g. Vanderborght et al. 2017) +SET_BOOL_PROP(RichardsNC, EnableWaterDiffusionInAir, false); + /*! *\brief The fluid system used by the model. * diff --git a/dumux/porousmediumflow/richardsnc/volumevariables.hh b/dumux/porousmediumflow/richardsnc/volumevariables.hh index 668e212a7a8a126f9a358098bfc7ad00024317c5..cb12812843d6a462b98a67f56ee56ad73123b8fa 100644 --- a/dumux/porousmediumflow/richardsnc/volumevariables.hh +++ b/dumux/porousmediumflow/richardsnc/volumevariables.hh @@ -319,6 +319,8 @@ class RichardsNCVolumeVariables : public RichardsBaseVolumeVariables<TypeTag> using FluidSystem = typename GET_PROP_TYPE(TypeTag, FluidSystem); using Indices = typename GET_PROP_TYPE(TypeTag, Indices); + static_assert(!GET_PROP_VALUE(TypeTag, EnableWaterDiffusionInAir), "Water diffusion in air is not implement for RichardsNC"); + enum { wPhaseIdx = Indices::wPhaseIdx, diff --git a/test/porousmediumflow/1p/implicit/compressible/test_1p.cc b/test/porousmediumflow/1p/implicit/compressible/test_1p.cc index 82c70f15ca2d9fb8f5a8f182ee010447b7889cd8..0681e6b11993174f06fbe0de52d61b06ecc6a40c 100644 --- a/test/porousmediumflow/1p/implicit/compressible/test_1p.cc +++ b/test/porousmediumflow/1p/implicit/compressible/test_1p.cc @@ -41,9 +41,8 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/common/defaultusagemessage.hh> -#include <dumux/nonlinear/newtoncontroller.hh> +#include <dumux/nonlinear/newtonsolver.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> #include <dumux/assembly/fvassembler.hh> @@ -108,7 +107,6 @@ int main(int argc, char** argv) try using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); // intialize the vtk output module @@ -130,9 +128,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod<NewtonController, Assembler, LinearSolver> nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // set some check points for the time loop timeLoop->setPeriodicCheckPoint(tEnd/10.0); @@ -143,24 +140,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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -176,8 +157,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/1p/implicit/compressible/test_1p_stationary.cc b/test/porousmediumflow/1p/implicit/compressible/test_1p_stationary.cc index 9426c67764dc989e797914962751d606603d0e8c..61a955a939b6bbd8df9013b8e1ada7eb6837ac69 100644 --- a/test/porousmediumflow/1p/implicit/compressible/test_1p_stationary.cc +++ b/test/porousmediumflow/1p/implicit/compressible/test_1p_stationary.cc @@ -39,9 +39,8 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/common/defaultusagemessage.hh> -#include <dumux/nonlinear/newtoncontroller.hh> +#include <dumux/nonlinear/newtonsolver.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> #include <dumux/assembly/fvassembler.hh> @@ -115,10 +114,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); - using NewtonController = Dumux::NewtonController<Scalar>; - auto newtonController = std::make_shared<NewtonController>(); - NewtonMethod<NewtonController, Assembler, LinearSolver> nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // linearize & solve Dune::Timer timer; diff --git a/test/porousmediumflow/1p/implicit/incompressible/test_1pfv.cc b/test/porousmediumflow/1p/implicit/incompressible/test_1pfv.cc index 3691b9f81d4e21f5c29183607c7bdfa4ec1ce2c4..5380c2f0fa8c2ef2e62f062ee217b09048e3e304 100644 --- a/test/porousmediumflow/1p/implicit/incompressible/test_1pfv.cc +++ b/test/porousmediumflow/1p/implicit/incompressible/test_1pfv.cc @@ -34,7 +34,6 @@ #include <dumux/linear/seqsolverbackend.hh> #include <dumux/common/properties.hh> -#include <dumux/nonlinear/newtonmethod.hh> #include <dumux/common/parameters.hh> #include <dumux/common/valgrind.hh> #include <dumux/common/dumuxmessage.hh> diff --git a/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources.cc b/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources.cc index d15462abb62029249ff4b508f074c71eebf533d6..92abc5b34e108093d2e5e708dc9aefe59d1791fb 100644 --- a/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources.cc +++ b/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources.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> @@ -104,7 +103,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"); @@ -132,10 +130,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 @@ -143,24 +139,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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -175,8 +155,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/1p/implicit/pointsources/test_1pfv_pointsources_timedependent.cc b/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources_timedependent.cc index 077d34ad205b6a78c23886724e858218b03ae31f..f0fbf2fe90b19ae767f1c45f5d39728762de4da7 100644 --- a/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources_timedependent.cc +++ b/test/porousmediumflow/1p/implicit/pointsources/test_1pfv_pointsources_timedependent.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> @@ -104,7 +103,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"); @@ -132,10 +130,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 @@ -146,24 +142,8 @@ int main(int argc, char** argv) try // set the time in the problem for implicit Euler scheme problem->setTime(timeLoop->time() + timeLoop->timeStepSize()); - // 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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -178,8 +158,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/1p/implicit/test_1pfv.cc b/test/porousmediumflow/1p/implicit/test_1pfv.cc index 527af70e84179af3d0f8873c4a70cf19d6b70b60..20b487087d3487e380ae631a3caf3c199d9119b4 100644 --- a/test/porousmediumflow/1p/implicit/test_1pfv.cc +++ b/test/porousmediumflow/1p/implicit/test_1pfv.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> @@ -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"); @@ -167,10 +165,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 @@ -178,24 +174,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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -210,8 +190,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/1p/implicit/test_1pfv_fracture2d3d.cc b/test/porousmediumflow/1p/implicit/test_1pfv_fracture2d3d.cc index 957420d57279b02cbff94ddfd4439d3e891798e3..661a2eacd5451bde016255477413c9f10318e14b 100644 --- a/test/porousmediumflow/1p/implicit/test_1pfv_fracture2d3d.cc +++ b/test/porousmediumflow/1p/implicit/test_1pfv_fracture2d3d.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> @@ -128,7 +127,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"); @@ -156,10 +154,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 @@ -167,24 +163,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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // make the new solution the old solution xOld = x; @@ -199,8 +179,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/1p/implicit/test_1pfv_network1d3d.cc b/test/porousmediumflow/1p/implicit/test_1pfv_network1d3d.cc index 6b61ab1ce58842cf9f2f7a007ca33be90d57c5f2..8002c628157d72f13e7f9e306b962a84ddbc5497 100644 --- a/test/porousmediumflow/1p/implicit/test_1pfv_network1d3d.cc +++ b/test/porousmediumflow/1p/implicit/test_1pfv_network1d3d.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> @@ -128,7 +127,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"); @@ -156,10 +154,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 @@ -167,24 +163,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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // output l2 norm for convergence analysis problem->outputL2Norm(x); @@ -202,8 +182,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/1p/implicit/test_1pnifv.cc b/test/porousmediumflow/1p/implicit/test_1pnifv.cc index f9f83626ebb2adb65ba7436cbe30f7fee8a49c06..cda24e587c1dda4f7a2b378ef20eb4bb1b86446b 100644 --- a/test/porousmediumflow/1p/implicit/test_1pnifv.cc +++ b/test/porousmediumflow/1p/implicit/test_1pnifv.cc @@ -42,8 +42,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> @@ -130,7 +129,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 = 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 @@ -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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // compute the new analytical temperature field for the output problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -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())); if (timeLoop->timeStepIndex()==0 || timeLoop->timeStepIndex() % vtkOutputInterval == 0 || timeLoop->willBeFinished()) vtkWriter.write(timeLoop->time()); diff --git a/test/porousmediumflow/1pnc/implicit/test_1p2c_fv.cc b/test/porousmediumflow/1pnc/implicit/test_1p2c_fv.cc index 3bd306cfd80b5b3b7570a1635b4de5f8068fd409..d9bb15ae6442ab0714a135338485aa40319776de 100644 --- a/test/porousmediumflow/1pnc/implicit/test_1p2c_fv.cc +++ b/test/porousmediumflow/1pnc/implicit/test_1p2c_fv.cc @@ -152,7 +152,7 @@ // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.cc b/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.cc index 39b9bd5270c7d704441adc6224b5696974886006..d259b5725782e5ec79c47929b0a35b41e183e947 100644 --- a/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.cc +++ b/test/porousmediumflow/1pnc/implicit/test_1p2cni_conduction_fv.cc @@ -41,9 +41,8 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/common/defaultusagemessage.hh> - #include <dumux/nonlinear/newtoncontroller.hh> + #include <dumux/nonlinear/newtonsolver.hh> #include <dumux/linear/seqsolverbackend.hh> - #include <dumux/nonlinear/newtonmethod.hh> #include <dumux/assembly/fvassembler.hh> @@ -108,7 +107,6 @@ using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); // intialize the vtk output module @@ -134,9 +132,8 @@ auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod<NewtonController, Assembler, LinearSolver> nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -144,24 +141,8 @@ // 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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // update the exact time temperature problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -180,8 +161,8 @@ // 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/1pnc/implicit/test_1p2cni_convection_fv.cc b/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.cc index 2d99ef79f9e29cd0abc11d29143628809fa3353d..8bfdfd015db407ae1e8ac9c08cbff03e79ceb90f 100644 --- a/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.cc +++ b/test/porousmediumflow/1pnc/implicit/test_1p2cni_convection_fv.cc @@ -41,9 +41,8 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/common/defaultusagemessage.hh> - #include <dumux/nonlinear/newtoncontroller.hh> + #include <dumux/nonlinear/newtonsolver.hh> #include <dumux/linear/seqsolverbackend.hh> - #include <dumux/nonlinear/newtonmethod.hh> #include <dumux/assembly/fvassembler.hh> @@ -108,7 +107,6 @@ using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); // intialize the vtk output module @@ -134,9 +132,8 @@ auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod<NewtonController, Assembler, LinearSolver> nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -144,24 +141,8 @@ // 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."); - } + // linearize & solve + nonLinearSolver.solve(x, *timeLoop); // update the exact time temperature problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -180,8 +161,8 @@ // 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/1pncmin/implicit/test_1pncminni_fv.cc b/test/porousmediumflow/1pncmin/implicit/test_1pncminni_fv.cc index ad96a94b3d81d0b1e05a3b4acbcf68973f8052f6..1c2903a3fe5f399126a9e4b70a918ee2c523165e 100644 --- a/test/porousmediumflow/1pncmin/implicit/test_1pncminni_fv.cc +++ b/test/porousmediumflow/1pncmin/implicit/test_1pncminni_fv.cc @@ -30,8 +30,7 @@ #include <dumux/common/parameters.hh> #include <dumux/common/dumuxmessage.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> +#include <dumux/nonlinear/newtonsolver.hh> #include <dumux/linear/seqsolverbackend.hh> #include <dumux/assembly/fvassembler.hh> @@ -134,7 +133,6 @@ int main(int argc, char** argv) try using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); // intialize the vtk output module @@ -164,9 +162,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod<NewtonController, Assembler, LinearSolver> nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::NewtonSolver<Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -177,43 +174,27 @@ 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."); - } - - // make the new solution the old solution - xOld = x; - gridVariables->advanceTimeStep(); - - // advance to the time loop to the next step - timeLoop->advanceTimeStep(); - - // update the output fields before write - problem->updateVtkOutput(x); + // solve the non-linear system with time step control + nonLinearSolver.solve(x, *timeLoop); + + // make the new solution the old solution + xOld = x; + gridVariables->advanceTimeStep(); + + // advance to the time loop to the next step + timeLoop->advanceTimeStep(); + + // update the output fields before write + problem->updateVtkOutput(x); - // write vtk output - vtkWriter.write(timeLoop->time()); + // write vtk output + vtkWriter.write(timeLoop->time()); - // report statistics of this time step - timeLoop->reportTimeStep(); + // 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/2p/implicit/adaptive/test_2p_adaptive_fv.cc b/test/porousmediumflow/2p/implicit/adaptive/test_2p_adaptive_fv.cc index dd1c181f569597e90d454985e027eae007e0ce5a..7ef24730c3b591cc8a312b37cec2e18d4048c2b2 100644 --- a/test/porousmediumflow/2p/implicit/adaptive/test_2p_adaptive_fv.cc +++ b/test/porousmediumflow/2p/implicit/adaptive/test_2p_adaptive_fv.cc @@ -38,8 +38,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> @@ -180,7 +179,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"); @@ -208,10 +206,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 = Dumux::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 @@ -241,23 +237,8 @@ int main(int argc, char** argv) try // set previous solution for storage evaluations assembler->setPreviousSolution(xOld); - 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; @@ -272,8 +253,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/2p/implicit/fracture/test_2p_fracture_fv.cc b/test/porousmediumflow/2p/implicit/fracture/test_2p_fracture_fv.cc index d56429596de482be6b3d23b7f1452a73ab913db3..6090dc310d7054ba982bd8740ca3e91eb2aa1186 100644 --- a/test/porousmediumflow/2p/implicit/fracture/test_2p_fracture_fv.cc +++ b/test/porousmediumflow/2p/implicit/fracture/test_2p_fracture_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> @@ -117,7 +116,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"); @@ -145,10 +143,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 = Dumux::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 @@ -156,24 +152,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; @@ -188,8 +168,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/2p/implicit/nonisothermal/test_2pni_fv.cc b/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni_fv.cc index 1354069095ea056847819ea48ed8c4844015ddc8..22b8215f5ec39379dcaa08e241f8b835cd691a55 100644 --- a/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni_fv.cc +++ b/test/porousmediumflow/2p/implicit/nonisothermal/test_2pni_fv.cc @@ -38,8 +38,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/nonlinear/newtonmethod.hh> +#include <dumux/nonlinear/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> @@ -128,7 +127,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"); @@ -156,10 +154,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::NewtonController<Scalar>; - using NewtonMethod = Dumux::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 @@ -167,24 +163,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; @@ -199,8 +179,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/2p1c/implicit/test_2p1c_fv.cc b/test/porousmediumflow/2p1c/implicit/test_2p1c_fv.cc index d87098fa99b663dc78a2a9b57440d73ef4746785..f6ec0b61d786ab39e0aef9b6e4e7a04899e6badd 100644 --- a/test/porousmediumflow/2p1c/implicit/test_2p1c_fv.cc +++ b/test/porousmediumflow/2p1c/implicit/test_2p1c_fv.cc @@ -41,9 +41,8 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/common/defaultusagemessage.hh> - #include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> #include <dumux/linear/seqsolverbackend.hh> - #include <dumux/nonlinear/newtonmethod.hh> + #include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> @@ -108,7 +107,6 @@ using Scalar = typename GET_PROP_TYPE(TypeTag, Scalar); auto tEnd = getParam<Scalar>("TimeLoop.TEnd"); auto dt = getParam<Scalar>("TimeLoop.DtInitial"); - auto maxDivisions = getParam<int>("TimeLoop.MaxTimeStepDivisions"); auto maxDt = getParam<Scalar>("TimeLoop.MaxTimeStepSize"); // intialize the vtk output module @@ -130,9 +128,9 @@ auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::PriVarSwitchNewtonController<TypeTag>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod<NewtonController, Assembler, LinearSolver> nonLinearSolver(newtonController, assembler, linearSolver); + using PrimaryVariableSwitch = typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); + using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler, LinearSolver, PrimaryVariableSwitch>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -140,24 +138,8 @@ // 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; @@ -172,8 +154,8 @@ // 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/2p2c/implicit/mpnccomparison/test_2p2c_comparison_fv.cc b/test/porousmediumflow/2p2c/implicit/mpnccomparison/test_2p2c_comparison_fv.cc index e8835a9e6d45fb52696e8a450d7e4b903460f2b8..6d481bae8a91015375be13b0530b793d6c3441c8 100644 --- a/test/porousmediumflow/2p2c/implicit/mpnccomparison/test_2p2c_comparison_fv.cc +++ b/test/porousmediumflow/2p2c/implicit/mpnccomparison/test_2p2c_comparison_fv.cc @@ -38,8 +38,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -129,7 +128,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"); @@ -157,10 +155,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = PriVarSwitchNewtonSolver<Assembler, LinearSolver, + typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -168,24 +165,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; @@ -200,8 +181,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/2p2c/implicit/test_2p2c_fv.cc b/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc index c7fc2a9a98d281fe268b3a2de6e079494535c446..1b86e04ba7cc00ff355e3f9513ed3c0ede80ef9b 100644 --- a/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc +++ b/test/porousmediumflow/2p2c/implicit/test_2p2c_fv.cc @@ -153,7 +153,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); // write vtk output diff --git a/test/porousmediumflow/2pnc/implicit/test_2pnc_fv.cc b/test/porousmediumflow/2pnc/implicit/test_2pnc_fv.cc index 9b75b3116f2c9a82f31f0731bc9d44ffca2f5579..21750d4981c2680cb3fca3793e36fdd17fa8a795 100644 --- a/test/porousmediumflow/2pnc/implicit/test_2pnc_fv.cc +++ b/test/porousmediumflow/2pnc/implicit/test_2pnc_fv.cc @@ -41,8 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -128,7 +127,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"); @@ -157,10 +155,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = PriVarSwitchNewtonSolver<Assembler, LinearSolver, + typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -168,24 +165,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; @@ -203,8 +184,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/2pnc/implicit/test_cc2pnc_diffusion.cc b/test/porousmediumflow/2pnc/implicit/test_cc2pnc_diffusion.cc index 88ee0bfbbe0af2dbe61d95e6dfecece4ffa6c211..31870b972c8c13143b81ff9cbfb81d2d8e9296ea 100644 --- a/test/porousmediumflow/2pnc/implicit/test_cc2pnc_diffusion.cc +++ b/test/porousmediumflow/2pnc/implicit/test_cc2pnc_diffusion.cc @@ -41,8 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -126,7 +125,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"); @@ -154,10 +152,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = PriVarSwitchNewtonSolver<Assembler, LinearSolver, + typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -165,24 +162,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; @@ -197,8 +178,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/2pncmin/implicit/test_2pncmin_fv.cc b/test/porousmediumflow/2pncmin/implicit/test_2pncmin_fv.cc index f40e7f9e16a8677d037d2b5c75318d52752da34e..1ccc7b74a2a18bc6bca8b7b1e58e3fa2f759b190 100644 --- a/test/porousmediumflow/2pncmin/implicit/test_2pncmin_fv.cc +++ b/test/porousmediumflow/2pncmin/implicit/test_2pncmin_fv.cc @@ -41,8 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -126,7 +125,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"); @@ -158,10 +156,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = PriVarSwitchNewtonSolver<Assembler, LinearSolver, + typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -173,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; @@ -208,8 +189,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/3p/implicit/test_3p_fv.cc b/test/porousmediumflow/3p/implicit/test_3p_fv.cc index 8f7a7eda6ae38371bd2a2cd18eeb762b9cad41fa..6a17a142b3806e16db6dd03e1ccc42b79202c405 100644 --- a/test/porousmediumflow/3p/implicit/test_3p_fv.cc +++ b/test/porousmediumflow/3p/implicit/test_3p_fv.cc @@ -39,8 +39,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> @@ -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 = Dumux::NewtonController<Scalar>; - using NewtonMethod = Dumux::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 @@ -176,24 +172,8 @@ int main(int argc, char** argv) try // the boundary conditions for the implicit Euler scheme problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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())); // write vtk output vtkWriter.write(timeLoop->time()); diff --git a/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.cc b/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.cc index d57c83212ceb2fa9c65d9ba520e22f23a2413e87..7ea429bfedf02c61fa632761c3d5943c2e562df7 100644 --- a/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.cc +++ b/test/porousmediumflow/3p/implicit/test_3pni_fv_conduction.cc @@ -39,8 +39,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> @@ -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"); @@ -164,10 +162,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 = Dumux::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 @@ -175,24 +171,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); // update the exact time temperature problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -207,8 +187,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())); if (timeLoop->timeStepIndex()==0 || timeLoop->timeStepIndex() % vtkOutputInterval == 0 || timeLoop->willBeFinished()) vtkWriter.write(timeLoop->time()); diff --git a/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.cc b/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.cc index b608af5e75da70b78f3eca4ae133bd111807c9f7..dcaf2bcac876a466e0ed91a20cad72ae5a7accde 100644 --- a/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.cc +++ b/test/porousmediumflow/3p/implicit/test_3pni_fv_convection.cc @@ -39,8 +39,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> @@ -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"); @@ -164,10 +162,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 = Dumux::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 @@ -175,24 +171,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); // compute the new analytical temperature field for the output problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -207,8 +187,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())); // write vtk output if(timeLoop->timeStepIndex()==0 || timeLoop->timeStepIndex() % vtkOutputInterval == 0 || timeLoop->willBeFinished()) diff --git a/test/porousmediumflow/3p3c/implicit/test_3p3c_fv.cc b/test/porousmediumflow/3p3c/implicit/test_3p3c_fv.cc index a9d8a49efb04e8ccebf8b4cd397fb1874f12acb0..d656cad00b0712e86d79e25f0fc4f1232f8669f8 100644 --- a/test/porousmediumflow/3p3c/implicit/test_3p3c_fv.cc +++ b/test/porousmediumflow/3p3c/implicit/test_3p3c_fv.cc @@ -37,8 +37,7 @@ #include <dumux/common/timeloop.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.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"); @@ -162,10 +160,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = PriVarSwitchNewtonSolver<Assembler, LinearSolver, + typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); @@ -174,24 +171,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; @@ -208,8 +189,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())); } timeLoop->finalize(leafGridView.comm()); diff --git a/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.cc b/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.cc index fd42d373843a2e199a2c14f7c31e80d8f462b238..bbf72d26335a1ffa26e950b4122b69ca3bbd6e13 100644 --- a/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.cc +++ b/test/porousmediumflow/3pwateroil/implicit/test_box3pwateroil.cc @@ -180,7 +180,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); // write vtk output diff --git a/test/porousmediumflow/co2/implicit/test_co2_fv.cc b/test/porousmediumflow/co2/implicit/test_co2_fv.cc index 88162d0d8066da78058cf86bf451db7bb1cd766a..c9e2297ebec09eee239847eaaf193c411d45a88c 100644 --- a/test/porousmediumflow/co2/implicit/test_co2_fv.cc +++ b/test/porousmediumflow/co2/implicit/test_co2_fv.cc @@ -38,8 +38,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -103,7 +102,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"); @@ -132,10 +130,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = PriVarSwitchNewtonSolver<Assembler, LinearSolver, + typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch)>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -143,24 +140,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; @@ -172,8 +153,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())); // write vtk output vtkWriter.write(timeLoop->time()); 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 6b64b18c152a171e708da08da24478feca43baf9..4b01fdd4f908a32686c378aec52b5d744945c4a8 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 8fd4d91754c317486c639cfb00728a72a3513b7a..2f6e9f2ef03e7a99a21e99b61d24fab545df1e9f 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 8974eecafa9b25094420ca9e6084e6baa0724ebd..7501c698c7c12e55683a6e5e56d95ca81c033a5f 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 fc999af2a1320bb380d7b1b790cc8777dd23acaf..86bdae2d55617673846ec7e4dc7ff17c93c18dcc 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()); diff --git a/test/porousmediumflow/richards/implicit/test_ccrichardsanalytical.cc b/test/porousmediumflow/richards/implicit/test_ccrichardsanalytical.cc index e5c0bd42a0de3bd93cf9cd07821540b9f0a36049..8b9be9df435726b7c1f96153589fcdcd9d7eb885 100644 --- a/test/porousmediumflow/richards/implicit/test_ccrichardsanalytical.cc +++ b/test/porousmediumflow/richards/implicit/test_ccrichardsanalytical.cc @@ -41,9 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/porousmediumflow/richards/newtoncontroller.hh> +#include <dumux/porousmediumflow/richards/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> @@ -129,7 +127,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"); @@ -157,10 +154,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::RichardsNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::RichardsNewtonSolver<TypeTag, Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -169,24 +164,8 @@ int main(int argc, char** argv) try assembler->setPreviousSolution(xOld); problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -203,8 +182,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/richards/implicit/test_richardslens_fv.cc b/test/porousmediumflow/richards/implicit/test_richardslens_fv.cc index 9d260e610e4532a6cdc41a9902cce78c46d5f890..1550ec49da78fe7301c5ce8b9cdbbb6deb171409 100644 --- a/test/porousmediumflow/richards/implicit/test_richardslens_fv.cc +++ b/test/porousmediumflow/richards/implicit/test_richardslens_fv.cc @@ -179,7 +179,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/richards/implicit/test_richardsniconduction_fv.cc b/test/porousmediumflow/richards/implicit/test_richardsniconduction_fv.cc index 49a276444d79b79d33169bc0f6f612719710a844..82f3c629c1ff7fe3cec09ff145c205a5b7294605 100644 --- a/test/porousmediumflow/richards/implicit/test_richardsniconduction_fv.cc +++ b/test/porousmediumflow/richards/implicit/test_richardsniconduction_fv.cc @@ -41,9 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/porousmediumflow/richards/newtoncontroller.hh> +#include <dumux/porousmediumflow/richards/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> @@ -129,7 +127,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"); @@ -158,10 +155,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::RichardsNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::RichardsNewtonSolver<TypeTag, Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -169,24 +164,9 @@ 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); + // compute the new analytical temperature field for the output problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -203,8 +183,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/richards/implicit/test_richardsniconvection_fv.cc b/test/porousmediumflow/richards/implicit/test_richardsniconvection_fv.cc index 4b549054c9e408daa33d16c83ede5219fec8f69c..ba18b9ce986dedf404ac039b60b0934e6807aea4 100644 --- a/test/porousmediumflow/richards/implicit/test_richardsniconvection_fv.cc +++ b/test/porousmediumflow/richards/implicit/test_richardsniconvection_fv.cc @@ -41,9 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/porousmediumflow/richards/newtoncontroller.hh> +#include <dumux/porousmediumflow/richards/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> @@ -129,7 +127,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"); @@ -158,10 +155,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::RichardsNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::RichardsNewtonSolver<TypeTag, Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -169,24 +164,9 @@ 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); + // compute the new analytical temperature field for the output problem->updateExactTemperature(x, timeLoop->time()+timeLoop->timeStepSize()); @@ -203,8 +183,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/richards/implicit/test_richardsnievaporation_fv.cc b/test/porousmediumflow/richards/implicit/test_richardsnievaporation_fv.cc index bf53af86c7a712d480f61f29bda2c1684696206a..3464a371f31613bbdf685ae0bc61f7e8b2c419cb 100644 --- a/test/porousmediumflow/richards/implicit/test_richardsnievaporation_fv.cc +++ b/test/porousmediumflow/richards/implicit/test_richardsnievaporation_fv.cc @@ -147,7 +147,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller + // set new dt as suggested by the newton solver timeLoop->setTimeStepSize(nonLinearSolver.suggestTimeStepSize(timeLoop->timeStepSize())); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/richardsnc/implicit/test_richardsnc_fv.cc b/test/porousmediumflow/richardsnc/implicit/test_richardsnc_fv.cc index 8fcd51145eec108863e3fc08aa3e5c820f078b8f..22decb0f0484c57307e9089684e7a29ae2732523 100644 --- a/test/porousmediumflow/richardsnc/implicit/test_richardsnc_fv.cc +++ b/test/porousmediumflow/richardsnc/implicit/test_richardsnc_fv.cc @@ -41,9 +41,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/nonlinear/newtoncontroller.hh> -#include <dumux/porousmediumflow/richards/newtoncontroller.hh> +#include <dumux/porousmediumflow/richards/newtonsolver.hh> #include <dumux/assembly/fvassembler.hh> @@ -130,7 +128,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"); @@ -158,10 +155,8 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(); // the non-linear solver - using NewtonController = Dumux::RichardsNewtonController<TypeTag>; - using NewtonMethod = Dumux::NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using NewtonSolver = Dumux::RichardsNewtonSolver<TypeTag, Assembler, LinearSolver>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -169,24 +164,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; @@ -202,8 +181,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/tracer/1ptracer/test_cctracer.cc b/test/porousmediumflow/tracer/1ptracer/test_cctracer.cc index 9187fa02573ac558b7da740ad22f752ceebe81e9..010fa973806c4bfdd533c387f3d10841f41993ab 100644 --- a/test/porousmediumflow/tracer/1ptracer/test_cctracer.cc +++ b/test/porousmediumflow/tracer/1ptracer/test_cctracer.cc @@ -39,7 +39,6 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -286,7 +285,7 @@ int main(int argc, char** argv) try // report statistics of this time step timeLoop->reportTimeStep(); - // set new dt as suggested by newton controller + // set new dt timeLoop->setTimeStepSize(dt); } while (!timeLoop->finished()); diff --git a/test/porousmediumflow/tracer/constvel/test_tracer.cc b/test/porousmediumflow/tracer/constvel/test_tracer.cc index f75e2b5a3ab7aac04746c0dad413066b3e2947e1..b710725758a67fa11365ef8b161f5635e390f695 100644 --- a/test/porousmediumflow/tracer/constvel/test_tracer.cc +++ b/test/porousmediumflow/tracer/constvel/test_tracer.cc @@ -37,7 +37,6 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/seqsolverbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/io/vtkoutputmodule.hh> @@ -183,7 +182,7 @@ int main(int argc, char** argv) try if (timeLoop->isCheckPoint() || timeLoop->finished()) vtkWriter.write(timeLoop->time()); - // set new dt as suggested by newton controller + // set new dt timeLoop->setTimeStepSize(dt); } diff --git a/test/porousmediumflow/tracer/multicomp/test_tracer_maxwellstefan.cc b/test/porousmediumflow/tracer/multicomp/test_tracer_maxwellstefan.cc index 07d3eb609dc3a6bf818053aaf5df7e6c305ec450..a03b1a28a8ea0f57010f1c869fe4199256d67a6a 100644 --- a/test/porousmediumflow/tracer/multicomp/test_tracer_maxwellstefan.cc +++ b/test/porousmediumflow/tracer/multicomp/test_tracer_maxwellstefan.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 = Dumux::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; @@ -207,8 +187,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/tutorial/ex1/exercise1.cc b/tutorial/ex1/exercise1.cc index b7655dac87ecae2ece2ff2d22b752f3949480d42..d6bb2599a084c7f1bad7d919d712ae5984dd3015 100644 --- a/tutorial/ex1/exercise1.cc +++ b/tutorial/ex1/exercise1.cc @@ -36,8 +36,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> @@ -103,7 +102,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"); @@ -125,10 +123,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(); @@ -140,24 +136,8 @@ int main(int argc, char** argv) try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -169,8 +149,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())); // output to vtk vtkWriter.write(timeLoop->time()); diff --git a/tutorial/ex1/exercise1_2p.cc b/tutorial/ex1/exercise1_2p.cc index 9cba2e73b24ccfb432e32ef27b140bd7be5f401c..7ae3bca427fb0c6c88341a0cd7ef04937b148ea2 100644 --- a/tutorial/ex1/exercise1_2p.cc +++ b/tutorial/ex1/exercise1_2p.cc @@ -36,8 +36,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> @@ -106,7 +105,6 @@ int main(int argc, char** argv) try // of type TYPE given in the group GROUPNAME from the input file 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"); @@ -128,10 +126,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(); @@ -143,24 +139,8 @@ int main(int argc, char** argv) try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -172,8 +152,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())); // output to vtk vtkWriter.write(timeLoop->time()); diff --git a/tutorial/ex1/exercise1_2p2c.cc b/tutorial/ex1/exercise1_2p2c.cc index a0b5ebb0355f62ab47f1197d96e56c3605845448..6f7e515c043a634b3673b4fe554f22a46a8cc3e1 100644 --- a/tutorial/ex1/exercise1_2p2c.cc +++ b/tutorial/ex1/exercise1_2p2c.cc @@ -36,8 +36,7 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -106,7 +105,6 @@ int main(int argc, char** argv) try // of type TYPE given in the group GROUPNAME from the input file 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"); @@ -128,10 +126,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using PrimaryVariableSwitch = typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); + using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler, LinearSolver, PrimaryVariableSwitch>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); @@ -143,24 +140,8 @@ int main(int argc, char** argv) try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -172,8 +153,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())); // output to vtk vtkWriter.write(timeLoop->time()); diff --git a/tutorial/ex2/exercise2.cc b/tutorial/ex2/exercise2.cc index dba708fbc1d911d01f20eb28cf8edf3731489d86..d031e8753b39eba25ae4979d5cdb563ba534608e 100644 --- a/tutorial/ex2/exercise2.cc +++ b/tutorial/ex2/exercise2.cc @@ -37,8 +37,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -101,7 +100,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"); @@ -128,10 +126,9 @@ int main(int argc, char** argv)try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using PrimaryVariableSwitch = typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); + using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler, LinearSolver, PrimaryVariableSwitch>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -142,24 +139,8 @@ int main(int argc, char** argv)try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -171,8 +152,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())); vtkWriter.write(timeLoop->time()); diff --git a/tutorial/ex3/exercise3.cc b/tutorial/ex3/exercise3.cc index 7111c6a3e0144e77a8e28c78e50b46fcdc631388..4669ea7f18988da5a659b439437820b1aff4f84c 100644 --- a/tutorial/ex3/exercise3.cc +++ b/tutorial/ex3/exercise3.cc @@ -42,8 +42,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> @@ -140,7 +139,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"); @@ -167,10 +165,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 @@ -178,24 +174,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; @@ -207,8 +187,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())); // write solution and grid to vtk vtkWriter.write(timeLoop->time()); diff --git a/tutorial/solution/ex1/exercise1_2p2c.cc b/tutorial/solution/ex1/exercise1_2p2c.cc index 313486242dd1ff4880cd67647268cbf6b1c9b410..779a668a6196d5518f716d04dfd7fb43d6daa0df 100644 --- a/tutorial/solution/ex1/exercise1_2p2c.cc +++ b/tutorial/solution/ex1/exercise1_2p2c.cc @@ -36,8 +36,7 @@ #include <dumux/common/dumuxmessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -103,7 +102,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"); @@ -125,10 +123,9 @@ int main(int argc, char** argv) try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using PrimaryVariableSwitch = typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); + using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler, LinearSolver, PrimaryVariableSwitch>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); @@ -140,24 +137,8 @@ int main(int argc, char** argv) try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -169,8 +150,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())); // output to vtk vtkWriter.write(timeLoop->time()); diff --git a/tutorial/solution/ex1/exercise1_2pni_solution.cc b/tutorial/solution/ex1/exercise1_2pni_solution.cc index bd2b3e835761050c448a7aee5e1d4b1d64b0f82a..877fe41e393c4bc984133291466a52f85132f745 100644 --- a/tutorial/solution/ex1/exercise1_2pni_solution.cc +++ b/tutorial/solution/ex1/exercise1_2pni_solution.cc @@ -36,8 +36,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> @@ -103,7 +102,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"); @@ -125,10 +123,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(); @@ -140,24 +136,8 @@ int main(int argc, char** argv) try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -169,8 +149,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())); // output to vtk vtkWriter.write(timeLoop->time()); diff --git a/tutorial/solution/ex2/exercise2_solution.cc b/tutorial/solution/ex2/exercise2_solution.cc index dba708fbc1d911d01f20eb28cf8edf3731489d86..d031e8753b39eba25ae4979d5cdb563ba534608e 100644 --- a/tutorial/solution/ex2/exercise2_solution.cc +++ b/tutorial/solution/ex2/exercise2_solution.cc @@ -37,8 +37,7 @@ #include <dumux/common/defaultusagemessage.hh> #include <dumux/linear/amgbackend.hh> -#include <dumux/nonlinear/newtonmethod.hh> -#include <dumux/porousmediumflow/compositional/privarswitchnewtoncontroller.hh> +#include <dumux/nonlinear/privarswitchnewtonsolver.hh> #include <dumux/assembly/fvassembler.hh> #include <dumux/assembly/diffmethod.hh> @@ -101,7 +100,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"); @@ -128,10 +126,9 @@ int main(int argc, char** argv)try auto linearSolver = std::make_shared<LinearSolver>(leafGridView, fvGridGeometry->dofMapper()); // the non-linear solver - using NewtonController = PriVarSwitchNewtonController<TypeTag>; - using NewtonMethod = NewtonMethod<NewtonController, Assembler, LinearSolver>; - auto newtonController = std::make_shared<NewtonController>(timeLoop); - NewtonMethod nonLinearSolver(newtonController, assembler, linearSolver); + using PrimaryVariableSwitch = typename GET_PROP_TYPE(TypeTag, PrimaryVariableSwitch); + using NewtonSolver = Dumux::PriVarSwitchNewtonSolver<Assembler, LinearSolver, PrimaryVariableSwitch>; + NewtonSolver nonLinearSolver(assembler, linearSolver); // time loop timeLoop->start(); do @@ -142,24 +139,8 @@ int main(int argc, char** argv)try //set time in problem (is used in time-dependent Neumann boundary condition) problem->setTime(timeLoop->time()+timeLoop->timeStepSize()); - // 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; @@ -171,8 +152,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())); vtkWriter.write(timeLoop->time());