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::Communication<Dune::MPIHelper::MPICommunicator> >
56 static constexpr bool assemblerExportsVariables = Detail::exportsVariables<Assembler>;
58 template<std::
size_t i>
61 template<std::
size_t i>
64 template<std::
size_t i>
65 using PrivarSwitchPtr = std::unique_ptr<PrimaryVariableSwitch<i>>;
66 using PriVarSwitchPtrTuple =
typename Assembler::Traits::template Tuple<PrivarSwitchPtr>;
76 std::shared_ptr<CouplingManager> couplingManager,
77 const Comm&
comm = Dune::MPIHelper::getCommunication(),
80 , couplingManager_(couplingManager)
82 using namespace Dune::Hybrid;
83 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
85 const int priVarSwitchVerbosity = getParamFromGroup<int>(
paramGroup,
"PrimaryVariableSwitch.Verbosity", 1);
86 using PVSwitch = PrimaryVariableSwitch<std::decay_t<
decltype(id)>::value>;
87 elementAt(priVarSwitches_,
id) = std::make_unique<PVSwitch>(priVarSwitchVerbosity);
90 priVarsSwitchedInLastIteration_.fill(
false);
99 couplingManager_->updateSolution(Backend::dofs(varsCurrentIter));
113 using namespace Dune::Hybrid;
114 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
116 this->initPriVarSwitch_(vars,
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
126 if (Dune::any_true(priVarsSwitchedInLastIteration_))
141 using namespace Dune::Hybrid;
142 forEach(std::make_index_sequence<Assembler::Traits::numSubDomains>{}, [&](
auto&& id)
144 auto& uCurrentIter = Backend::dofs(varsCurrentIter)[id];
145 if constexpr (!assemblerExportsVariables)
146 this->invokePriVarSwitch_(this->
assembler().gridVariables(
id),
147 uCurrentIter, id, HasPriVarsSwitch<std::decay_t<
decltype(id)>::value>{});
149 this->invokePriVarSwitch_(varsCurrentIter[
id], uCurrentIter,
id, HasPriVarsSwitch<std::decay_t<
decltype(
id)>::value>{});
153 couplingManager_->updateSolution(Backend::dofs(varsCurrentIter));
162 couplingManager_->updateSolution(uCurrentIter);
171 template<std::
size_t i>
172 void initPriVarSwitch_(
Variables&, Dune::index_constant<i>
id, std::false_type) {}
177 template<std::
size_t i>
178 void initPriVarSwitch_(
Variables& vars, Dune::index_constant<i>
id, std::true_type)
180 using namespace Dune::Hybrid;
181 auto& priVarSwitch = *elementAt(priVarSwitches_,
id);
182 auto& sol = Backend::dofs(vars)[id];
184 priVarSwitch.reset(sol.size());
185 priVarsSwitchedInLastIteration_[i] =
false;
187 const auto& problem = this->
assembler().problem(
id);
188 const auto& gridGeometry = this->
assembler().gridGeometry(
id);
189 if constexpr (!assemblerExportsVariables)
190 priVarSwitch.updateDirichletConstraints(problem, gridGeometry, this->assembler().gridVariables(
id), sol);
192 priVarSwitch.updateDirichletConstraints(problem, gridGeometry, vars[
id], sol[
id]);
198 template<
class SubVars,
class SubSol, std::
size_t i>
199 void invokePriVarSwitch_(SubVars&, SubSol&, Dune::index_constant<i>
id, std::false_type) {}
204 template<
class SubVars,
class SubSol, std::
size_t i>
205 void invokePriVarSwitch_(SubVars& subVars, SubSol& uCurrentIter, Dune::index_constant<i>
id, std::true_type)
209 const auto& gridGeometry = this->
assembler().gridGeometry(
id);
210 const auto& problem = this->
assembler().problem(
id);
212 using namespace Dune::Hybrid;
213 auto& priVarSwitch = *elementAt(priVarSwitches_,
id);
216 priVarsSwitchedInLastIteration_[i] = priVarSwitch.update(uCurrentIter, subVars, problem, gridGeometry);
218 if (priVarsSwitchedInLastIteration_[i])
220 for (
const auto& element : elements(gridGeometry.gridView()))
223 priVarSwitch.updateSwitchedVolVars(problem, element, gridGeometry, subVars, uCurrentIter);
226 priVarSwitch.updateSwitchedFluxVarsCache(problem, element, gridGeometry, subVars, uCurrentIter);
232 std::shared_ptr<CouplingManager> couplingManager_;
235 PriVarSwitchPtrTuple priVarSwitches_;
237 std::array<bool, Assembler::Traits::numSubDomains> priVarsSwitchedInLastIteration_;
typename GetPVSwitch< Variables >::type PrimaryVariableSwitch
Definition: primaryvariableswitchadapter.hh:42
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:44
Detail::AssemblerVariables< Assembler > Variables
export the type of variables that represent a numerical solution
Definition: common/pdesolver.hh:82
const LinearSolver & linearSolver() const
Access the linear solver.
Definition: common/pdesolver.hh:133
const Assembler & assembler() const
Access the assembler.
Definition: common/pdesolver.hh:121
Base class for linear solvers.
Definition: solver.hh:37
The interface of the coupling manager for multi domain problems.
Definition: multidomain/couplingmanager.hh:60
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:124
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:74
void newtonEndStep(Variables &varsCurrentIter, const SolutionVector &uLastIter) override
Indicates that one Newton iteration was finished.
Definition: multidomain/newtonsolver.hh:139
void newtonBeginStep(const Variables &varsCurrentIter) override
Indicates the beginning of a Newton iteration.
Definition: multidomain/newtonsolver.hh:96
void newtonBegin(Variables &vars) override
Called before the Newton method is applied to an non-linear system of equations.
Definition: multidomain/newtonsolver.hh:109
void solutionChanged_(Variables &vars, const SolutionVector &uCurrentIter) override
Update solution-depended quantities like grid variables after the solution has changed.
Definition: multidomain/newtonsolver.hh:160
An implementation of a Newton solver.
Definition: nonlinear/newtonsolver.hh:216
const std::string & paramGroup() const
Returns the parameter group.
Definition: nonlinear/newtonsolver.hh:841
virtual void newtonBegin(Variables &initVars)
Called before the Newton method is applied to an non-linear system of equations.
Definition: nonlinear/newtonsolver.hh:407
virtual void newtonEndStep(Variables &vars, const SolutionVector &uLastIter)
Indicates that one Newton iteration was finished.
Definition: nonlinear/newtonsolver.hh:638
virtual void solutionChanged_(Variables &vars, const SolutionVector &uCurrentIter)
Update solution-dependent quantities like grid variables after the solution has changed.
Definition: nonlinear/newtonsolver.hh:875
virtual void newtonBeginStep(const Variables &vars)
Indicates the beginning of a Newton iteration.
Definition: nonlinear/newtonsolver.hh:467
typename Backend::DofVector SolutionVector
Definition: nonlinear/newtonsolver.hh:221
const Communication & comm() const
the communicator for parallel runs
Definition: nonlinear/newtonsolver.hh:270
VariablesBackend< typename ParentType::Variables > Backend
Definition: nonlinear/newtonsolver.hh:220
virtual bool newtonConverged() const
Returns true if the error of the solution is below the tolerance.
Definition: nonlinear/newtonsolver.hh:685
Reference implementation of a Newton solver.