25#ifndef DUMUX_MULTIDOMAIN_NEWTON_SOLVER_HH
26#define DUMUX_MULTIDOMAIN_NEWTON_SOLVER_HH
34template<
class Assembler,
class Index>
37template<
class Assembler, std::
size_t i>
38using GetPVSwitchMultiDomain = Dune::Std::detected_or<int, DetectPVSwitchMultiDomain, Assembler, Dune::index_constant<i>>;
49 class Comm = Dune::CollectiveCommunication<Dune::MPIHelper::MPICommunicator> >
53 using SolutionVector =
typename Assembler::ResidualType;
55 template<std::
size_t i>
58 template<std::
size_t i>
61 template<std::
size_t i>
62 using PrivarSwitchPtr = std::unique_ptr<PrimaryVariableSwitch<i>>;
63 using PriVarSwitchPtrTuple =
typename Assembler::Traits::template Tuple<PrivarSwitchPtr>;
72 std::shared_ptr<CouplingManager> couplingManager,
73 const Comm&
comm = Dune::MPIHelper::getCollectiveCommunication(),
76 , couplingManager_(couplingManager)
78 using namespace Dune::Hybrid;
79 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
81 const int priVarSwitchVerbosity = getParamFromGroup<int>(
paramGroup,
"PrimaryVariableSwitch.Verbosity", 1);
82 using PVSwitch = PrimaryVariableSwitch<std::decay_t<
decltype(id)>::value>;
83 elementAt(priVarSwitches_,
id) = std::make_unique<PVSwitch>(priVarSwitchVerbosity);
86 priVarsSwitchedInLastIteration_.fill(
false);
95 couplingManager_->updateSolution(uCurrentIter);
109 using namespace Dune::Hybrid;
110 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
112 this->initPriVarSwitch_(u,
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
122 if (Dune::any_true(priVarsSwitchedInLastIteration_))
135 void newtonEndStep(SolutionVector &uCurrentIter,
const SolutionVector &uLastIter)
override
137 using namespace Dune::Hybrid;
138 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
140 this->invokePriVarSwitch_(uCurrentIter[
id],
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
144 couplingManager_->updateSolution(uCurrentIter);
152 template<std::
size_t i>
153 void initPriVarSwitch_(SolutionVector&, Dune::index_constant<i>
id, std::false_type) {}
158 template<std::
size_t i>
159 void initPriVarSwitch_(SolutionVector& sol, Dune::index_constant<i>
id, std::true_type)
161 using namespace Dune::Hybrid;
162 auto& priVarSwitch = *elementAt(priVarSwitches_,
id);
164 priVarSwitch.reset(sol[
id].size());
165 priVarsSwitchedInLastIteration_[i] =
false;
167 const auto& problem = this->
assembler().problem(
id);
168 const auto& gridGeometry = this->
assembler().gridGeometry(
id);
169 auto& gridVariables = this->
assembler().gridVariables(
id);
170 priVarSwitch.updateDirichletConstraints(problem, gridGeometry, gridVariables, sol[
id]);
176 template<
class SubSol, std::
size_t i>
177 void invokePriVarSwitch_(SubSol&, Dune::index_constant<i>
id, std::false_type) {}
182 template<
class SubSol, std::
size_t i>
183 void invokePriVarSwitch_(SubSol& uCurrentIter, Dune::index_constant<i>
id, std::true_type)
187 const auto& gridGeometry = this->
assembler().gridGeometry(
id);
188 const auto& problem = this->
assembler().problem(
id);
189 auto& gridVariables = this->
assembler().gridVariables(
id);
191 using namespace Dune::Hybrid;
192 auto& priVarSwitch = *elementAt(priVarSwitches_,
id);
195 priVarsSwitchedInLastIteration_[i] = priVarSwitch.update(uCurrentIter, gridVariables,
196 problem, gridGeometry);
198 if (priVarsSwitchedInLastIteration_[i])
200 for (
const auto& element : elements(gridGeometry.gridView()))
203 priVarSwitch.updateSwitchedVolVars(problem, element, gridGeometry, gridVariables, uCurrentIter);
206 priVarSwitch.updateSwitchedFluxVarsCache(problem, element, gridGeometry, gridVariables, uCurrentIter);
212 std::shared_ptr<CouplingManager> couplingManager_;
215 PriVarSwitchPtrTuple priVarSwitches_;
217 std::array<bool, Assembler::Traits::numSubDomains> priVarsSwitchedInLastIteration_;
typename Assembler::template GridVariables< Index::value >::VolumeVariables::PrimaryVariableSwitch DetectPVSwitchMultiDomain
Definition: multidomain/newtonsolver.hh:35
Dune::Std::detected_or< int, DetectPVSwitchMultiDomain, Assembler, Dune::index_constant< i > > GetPVSwitchMultiDomain
Definition: multidomain/newtonsolver.hh:38
Definition: partialreassembler.hh:43
const Assembler & assembler() const
Access the assembler.
Definition: common/pdesolver.hh:92
const LinearSolver & linearSolver() const
Access the linear solver.
Definition: common/pdesolver.hh:104
Base class for linear solvers.
Definition: solver.hh:37
Definition: multidomain/couplingmanager.hh:46
Newton sover for coupled problems.
Definition: multidomain/newtonsolver.hh:51
bool newtonConverged() const override
Returns true if the error of the solution is below the tolerance.
Definition: multidomain/newtonsolver.hh:120
void newtonEndStep(SolutionVector &uCurrentIter, const SolutionVector &uLastIter) override
Indicates that one Newton iteration was finished.
Definition: multidomain/newtonsolver.hh:135
void newtonBeginStep(const SolutionVector &uCurrentIter) override
Indicates the beginning of a Newton iteration.
Definition: multidomain/newtonsolver.hh:92
void newtonBegin(SolutionVector &u) override
Called before the Newton method is applied to an non-linear system of equations.
Definition: multidomain/newtonsolver.hh:105
MultiDomainNewtonSolver(std::shared_ptr< Assembler > assembler, std::shared_ptr< LinearSolver > linearSolver, std::shared_ptr< CouplingManager > couplingManager, const Comm &comm=Dune::MPIHelper::getCollectiveCommunication(), const std::string ¶mGroup="")
The constructor.
Definition: multidomain/newtonsolver.hh:70
An implementation of a Newton solver.
Definition: nonlinear/newtonsolver.hh:177
const std::string & paramGroup() const
Returns the parameter group.
Definition: nonlinear/newtonsolver.hh:770
virtual void newtonBeginStep(const SolutionVector &u)
Indicates the beginning of a Newton iteration.
Definition: nonlinear/newtonsolver.hh:402
virtual void newtonEndStep(SolutionVector &uCurrentIter, const SolutionVector &uLastIter)
Indicates that one Newton iteration was finished.
Definition: nonlinear/newtonsolver.hh:573
const Communication & comm() const
the communicator for parallel runs
Definition: nonlinear/newtonsolver.hh:226
virtual void newtonBegin(SolutionVector &u)
Called before the Newton method is applied to an non-linear system of equations.
Definition: nonlinear/newtonsolver.hh:352
virtual bool newtonConverged() const
Returns true if the error of the solution is below the tolerance.
Definition: nonlinear/newtonsolver.hh:614
Reference implementation of a Newton solver.