13#ifndef DUMUX_MULTIDOMAIN_NEWTON_SOLVER_HH
14#define DUMUX_MULTIDOMAIN_NEWTON_SOLVER_HH
22template<
class Assembler,
class Index>
34 class Comm = Dune::Communication<Dune::MPIHelper::MPICommunicator> >
43 template<std::
size_t i>
44 using PrimaryVariableSwitch =
45 Dune::Std::detected_or_t<int, Detail::DetectPVSwitchMultiDomain, Assembler, Dune::index_constant<i>>;
47 template<std::
size_t i>
48 using HasPriVarsSwitch =
49 Dune::Std::is_detected<Detail::DetectPVSwitchMultiDomain, Assembler, Dune::index_constant<i>>;
51 template<std::
size_t i>
52 using PrivarSwitchPtr = std::unique_ptr<PrimaryVariableSwitch<i>>;
53 using PriVarSwitchPtrTuple =
typename Assembler::Traits::template Tuple<PrivarSwitchPtr>;
63 std::shared_ptr<CouplingManager> couplingManager,
64 const Comm&
comm = Dune::MPIHelper::getCommunication(),
67 , couplingManager_(couplingManager)
69 using namespace Dune::Hybrid;
70 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
73 using PVSwitch = PrimaryVariableSwitch<std::decay_t<
decltype(id)>::value>;
74 elementAt(priVarSwitches_,
id) = std::make_unique<PVSwitch>(priVarSwitchVerbosity);
77 priVarsSwitchedInLastIteration_.fill(
false);
86 couplingManager_->updateSolution(Backend::dofs(varsCurrentIter));
100 using namespace Dune::Hybrid;
101 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
103 this->initPriVarSwitch_(vars,
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
113 if (Dune::any_true(priVarsSwitchedInLastIteration_))
128 using namespace Dune::Hybrid;
129 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
131 auto& uCurrentIter = Backend::dofs(varsCurrentIter)[id];
132 if constexpr (!assemblerExportsVariables)
133 this->invokePriVarSwitch_(this->
assembler().gridVariables(
id),
134 uCurrentIter,
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
136 this->invokePriVarSwitch_(varsCurrentIter[
id], uCurrentIter,
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
140 couplingManager_->updateSolution(Backend::dofs(varsCurrentIter));
149 couplingManager_->updateSolution(uCurrentIter);
158 template<std::
size_t i>
159 void initPriVarSwitch_(
Variables&, Dune::index_constant<i>
id, std::false_type) {}
164 template<std::
size_t i>
165 void initPriVarSwitch_(
Variables& vars, Dune::index_constant<i>
id, std::true_type)
167 using namespace Dune::Hybrid;
168 auto& priVarSwitch = *elementAt(priVarSwitches_,
id);
169 auto& sol = Backend::dofs(vars)[id];
171 priVarSwitch.reset(sol.size());
172 priVarsSwitchedInLastIteration_[i] =
false;
174 const auto& problem = this->
assembler().problem(
id);
175 const auto& gridGeometry = this->
assembler().gridGeometry(
id);
176 if constexpr (!assemblerExportsVariables)
177 priVarSwitch.updateDirichletConstraints(problem, gridGeometry, this->assembler().gridVariables(
id), sol);
179 priVarSwitch.updateDirichletConstraints(problem, gridGeometry, vars[
id], sol[
id]);
185 template<
class SubVars,
class SubSol, std::
size_t i>
186 void invokePriVarSwitch_(SubVars&, SubSol&, Dune::index_constant<i>
id, std::false_type) {}
191 template<
class SubVars,
class SubSol, std::
size_t i>
192 void invokePriVarSwitch_(SubVars& subVars, SubSol& uCurrentIter, Dune::index_constant<i>
id, std::true_type)
196 const auto& gridGeometry = this->
assembler().gridGeometry(
id);
197 const auto& problem = this->
assembler().problem(
id);
199 using namespace Dune::Hybrid;
200 auto& priVarSwitch = *elementAt(priVarSwitches_,
id);
203 priVarsSwitchedInLastIteration_[i] = priVarSwitch.update(uCurrentIter, subVars, problem, gridGeometry);
205 if (priVarsSwitchedInLastIteration_[i])
207 for (
const auto& element : elements(gridGeometry.gridView()))
210 priVarSwitch.updateSwitchedVolVars(problem, element, gridGeometry, subVars, uCurrentIter);
213 priVarSwitch.updateSwitchedFluxVarsCache(problem, element, gridGeometry, subVars, uCurrentIter);
219 std::shared_ptr<CouplingManager> couplingManager_;
222 PriVarSwitchPtrTuple priVarSwitches_;
224 std::array<bool, Assembler::Traits::numSubDomains> priVarsSwitchedInLastIteration_;
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:48
Definition partialreassembler.hh:32
Base class for linear solvers.
Definition solver.hh:27
Newton solver for coupled problems.
Definition multidomain/newtonsolver.hh:36
bool newtonConverged() const override
Returns true if the error of the solution is below the tolerance.
Definition multidomain/newtonsolver.hh:111
MultiDomainNewtonSolver(std::shared_ptr< Assembler > assembler, std::shared_ptr< LinearSolver > linearSolver, std::shared_ptr< CouplingManager > couplingManager, const Comm &comm=Dune::MPIHelper::getCommunication(), const std::string ¶mGroup="")
The constructor.
Definition multidomain/newtonsolver.hh:61
void newtonEndStep(Variables &varsCurrentIter, const SolutionVector &uLastIter) override
Indicates that one Newton iteration was finished.
Definition multidomain/newtonsolver.hh:126
void newtonBeginStep(const Variables &varsCurrentIter) override
Indicates the beginning of a Newton iteration.
Definition multidomain/newtonsolver.hh:83
void newtonBegin(Variables &vars) override
Called before the Newton method is applied to an non-linear system of equations.
Definition multidomain/newtonsolver.hh:96
void solutionChanged_(Variables &vars, const SolutionVector &uCurrentIter) override
Update solution-depended quantities like grid variables after the solution has changed.
Definition multidomain/newtonsolver.hh:147
An implementation of a Newton solver.
Definition nonlinear/newtonsolver.hh:181
const std::string & paramGroup() const
Returns the parameter group.
Definition nonlinear/newtonsolver.hh:806
virtual void newtonBegin(Variables &initVars)
Called before the Newton method is applied to an non-linear system of equations.
Definition nonlinear/newtonsolver.hh:385
virtual void newtonEndStep(Variables &vars, const SolutionVector &uLastIter)
Indicates that one Newton iteration was finished.
Definition nonlinear/newtonsolver.hh:603
virtual void solutionChanged_(Variables &vars, const SolutionVector &uCurrentIter)
Update solution-dependent quantities like grid variables after the solution has changed.
Definition nonlinear/newtonsolver.hh:840
virtual void newtonBeginStep(const Variables &vars)
Indicates the beginning of a Newton iteration.
Definition nonlinear/newtonsolver.hh:446
typename Backend::DofVector SolutionVector
Definition nonlinear/newtonsolver.hh:186
const Communication & comm() const
the communicator for parallel runs
Definition nonlinear/newtonsolver.hh:235
VariablesBackend< typename ParentType::Variables > Backend
Definition nonlinear/newtonsolver.hh:185
virtual bool newtonConverged() const
Returns true if the error of the solution is below the tolerance.
Definition nonlinear/newtonsolver.hh:650
const LinearSolver & linearSolver() const
Definition common/pdesolver.hh:133
const Assembler & assembler() const
Definition common/pdesolver.hh:121
Detail::PDESolver::AssemblerVariables< Assembler > Variables
Definition common/pdesolver.hh:71
T getParamFromGroup(Args &&... args)
A free function to get a parameter from the parameter tree singleton with a model group.
Definition parameters.hh:149
constexpr bool assemblerExportsVariables
Definition common/pdesolver.hh:35
typename Assembler::template GridVariables< Index::value >::VolumeVariables::PrimaryVariableSwitch DetectPVSwitchMultiDomain
Definition multidomain/newtonsolver.hh:23
Reference implementation of a Newton solver.