15#ifndef DUMUX_EXPERIMENTAL_MULTISTAGE_MULTIDOMAIN_FV_ASSEMBLER_HH
16#define DUMUX_EXPERIMENTAL_MULTISTAGE_MULTIDOMAIN_FV_ASSEMBLER_HH
23#include <dune/common/hybridutilities.hh>
24#include <dune/istl/matrixindexset.hh>
51template<
class T, std::size_t... I>
93template<
class MDTraits,
class CMType, DiffMethod diffMethod>
96 template<std::
size_t id>
97 using SubDomainTypeTag =
typename MDTraits::template SubDomain<id>::TypeTag;
102 using Scalar =
typename MDTraits::Scalar;
106 template<std::
size_t id>
109 template<std::
size_t id>
110 using GridVariables =
typename MDTraits::template SubDomain<id>::GridVariables;
112 template<std::
size_t id>
113 using GridGeometry =
typename MDTraits::template SubDomain<id>::GridGeometry;
115 template<std::
size_t id>
116 using Problem =
typename MDTraits::template SubDomain<id>::Problem;
126 using ProblemTuple =
typename MDTraits::template TupleOfSharedPtrConst<Problem>;
127 using GridGeometryTuple =
typename MDTraits::template TupleOfSharedPtrConst<GridGeometry>;
128 using GridVariablesTuple =
typename MDTraits::template TupleOfSharedPtr<GridVariables>;
132 template<std::
size_t id>
135 template<
class DiscretizationMethod, std::
size_t id>
136 struct SubDomainAssemblerType;
138 template<std::
size_t id>
139 struct SubDomainAssemblerType<DiscretizationMethods::CCTpfa, id>
144 template<std::
size_t id>
145 struct SubDomainAssemblerType<DiscretizationMethods::CCMpfa, id>
150 template<std::
size_t id,
class DM>
151 struct SubDomainAssemblerType<DiscretizationMethods::CVFE<DM>, id>
156 template<std::
size_t id>
157 using SubDomainAssembler =
typename SubDomainAssemblerType<typename GridGeometry<id>::DiscretizationMethod,
id>::type;
172 , timeSteppingMethod_(msMethod)
173 , problemTuple_(std::move(
problem))
178 std::cout <<
"Instantiated assembler for an instationary problem." << std::endl;
185 maybeComputeColors_();
197 spatialOperatorEvaluations_.back() = 0.0;
198 temporalOperatorEvaluations_.back() = 0.0;
200 if (stageParams_->size() != spatialOperatorEvaluations_.size())
201 DUNE_THROW(Dune::InvalidStateException,
"Wrong number of residuals");
203 using namespace Dune::Hybrid;
204 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](
const auto domainId)
208 auto& jacRow = (*jacobian_)[domainId];
209 auto& spatial = spatialOperatorEvaluations_.back()[domainId];
210 auto& temporal = temporalOperatorEvaluations_.back()[domainId];
212 assemble_(domainId, [&](
const auto& element)
215 SubDomainAssembler<domainId()> subDomainAssembler(view, element, curSol, *
couplingManager_);
216 subDomainAssembler.assembleJacobianAndResidual(
217 jacRow, (*residual_)[domainId],
219 *stageParams_, temporal, spatial,
220 constrainedDofs_[domainId]
225 auto constantResidualComponent = (*residual_)[domainId];
226 constantResidualComponent = 0.0;
227 for (std::size_t k = 0; k < stageParams_->size()-1; ++k)
229 if (!stageParams_->skipTemporal(k))
230 constantResidualComponent.axpy(stageParams_->temporalWeight(k), temporalOperatorEvaluations_[k][domainId]);
231 if (!stageParams_->skipSpatial(k))
232 constantResidualComponent.axpy(stageParams_->spatialWeight(k), spatialOperatorEvaluations_[k][domainId]);
236 for (std::size_t i = 0; i < constantResidualComponent.size(); ++i)
237 for (std::size_t ii = 0; ii < constantResidualComponent[i].size(); ++ii)
238 (*residual_)[domainId][i][ii] += constrainedDofs_[domainId][i][ii] > 0.5 ? 0.0 : constantResidualComponent[i][ii];
244 { DUNE_THROW(Dune::NotImplemented,
"residual"); }
252 jacobian_ = std::make_shared<JacobianMatrix>();
253 residual_ = std::make_shared<ResidualType>();
255 setJacobianBuildMode_(*jacobian_);
256 setJacobianPattern_(*jacobian_);
257 setResidualSize_(*residual_);
265 using namespace Dune::Hybrid;
266 forEach(integralRange(Dune::Hybrid::size(gridVariablesTuple_)), [&](
const auto domainId)
267 { this->
gridVariables(domainId).update(curSol[domainId]); });
275 using namespace Dune::Hybrid;
276 forEach(integralRange(Dune::Hybrid::size(gridVariablesTuple_)), [&](
const auto domainId)
277 { this->
gridVariables(domainId).resetTimeStep(curSol[domainId]); });
283 template<std::
size_t i>
284 std::size_t
numDofs(Dune::index_constant<i> domainId)
const
285 {
return std::get<domainId>(gridGeometryTuple_)->numDofs(); }
288 template<std::
size_t i>
289 const auto&
problem(Dune::index_constant<i> domainId)
const
290 {
return *std::get<domainId>(problemTuple_); }
293 template<std::
size_t i>
295 {
return *std::get<domainId>(gridGeometryTuple_); }
298 template<std::
size_t i>
299 const auto&
gridView(Dune::index_constant<i> domainId)
const
303 template<std::
size_t i>
305 {
return *std::get<domainId>(gridVariablesTuple_); }
308 template<std::
size_t i>
310 {
return *std::get<domainId>(gridVariablesTuple_); }
318 {
return *jacobian_; }
322 {
return *residual_; }
326 {
return *prevSol_; }
331 template<std::
size_t i>
333 {
return {
LocalResidual<i>{std::get<domainId>(problemTuple_).get(),
nullptr} }; }
337 spatialOperatorEvaluations_.clear();
338 temporalOperatorEvaluations_.clear();
339 stageParams_.reset();
342 template<
class StageParams>
345 stageParams_ = std::move(params);
346 const auto curStage = stageParams_->size() - 1;
352 using namespace Dune::Hybrid;
353 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](
const auto domainId)
355 setProblemTime_(*std::get<domainId>(problemTuple_), stageParams_->timeAtStage(curStage));
359 spatialOperatorEvaluations_.push_back(*residual_);
360 temporalOperatorEvaluations_.push_back(*residual_);
363 using namespace Dune::Hybrid;
364 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](
const auto domainId)
366 auto& spatial = spatialOperatorEvaluations_.back()[domainId];
367 auto& temporal = temporalOperatorEvaluations_.back()[domainId];
368 assemble_(domainId, [&](
const auto& element)
371 SubDomainAssembler<domainId()> subDomainAssembler(view, element, x, *
couplingManager_);
372 subDomainAssembler.localResidual().spatialWeight(1.0);
373 subDomainAssembler.localResidual().temporalWeight(1.0);
374 subDomainAssembler.assembleCurrentResidual(spatial, temporal);
380 using namespace Dune::Hybrid;
381 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](
const auto domainId)
383 setProblemTime_(*std::get<domainId>(problemTuple_), stageParams_->timeAtStage(curStage));
387 spatialOperatorEvaluations_.push_back(*residual_);
388 temporalOperatorEvaluations_.push_back(*residual_);
396 {
return timeSteppingMethod_->implicit(); }
408 using namespace Dune::Hybrid;
409 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](
const auto i)
411 forEach(jac[i], [&](
auto& jacBlock)
413 using BlockType = std::decay_t<
decltype(jacBlock)>;
414 if (jacBlock.buildMode() == BlockType::BuildMode::unknown)
415 jacBlock.setBuildMode(BlockType::BuildMode::random);
416 else if (jacBlock.buildMode() != BlockType::BuildMode::random)
417 DUNE_THROW(Dune::NotImplemented,
"Only BCRS matrices with random build mode are supported at the moment");
427 using namespace Dune::Hybrid;
428 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](
const auto domainI)
430 forEach(integralRange(Dune::Hybrid::size(jac[domainI])), [&](
const auto domainJ)
432 const auto pattern = this->getJacobianPattern_(domainI, domainJ);
433 pattern.exportIdx(jac[domainI][domainJ]);
443 using namespace Dune::Hybrid;
444 forEach(integralRange(Dune::Hybrid::size(res)), [&](
const auto domainId)
445 { res[domainId].resize(this->
numDofs(domainId)); });
449 void resetResidual_()
453 residual_ = std::make_shared<ResidualType>();
454 setResidualSize_(*residual_);
457 setResidualSize_(constrainedDofs_);
460 constrainedDofs_ = 0.0;
464 void resetJacobian_()
468 jacobian_ = std::make_shared<JacobianMatrix>();
469 setJacobianBuildMode_(*jacobian_);
470 setJacobianPattern_(*jacobian_);
477 void maybeComputeColors_()
479 if constexpr (CouplingManagerSupportsMultithreadedAssembly<CouplingManager>::value)
480 if (enableMultithreading_)
484 template<std::
size_t i,
class SubRes>
485 void assembleResidual_(Dune::index_constant<i> domainId, SubRes& subRes,
488 DUNE_THROW(Dune::NotImplemented,
"assembleResidual_");
496 template<std::
size_t i,
class AssembleElementFunc>
497 void assemble_(Dune::index_constant<i> domainId, AssembleElementFunc&& assembleElement)
const
500 bool succeeded =
false;
505 if constexpr (CouplingManagerSupportsMultithreadedAssembly<CouplingManager>::value)
507 if (enableMultithreading_)
510 domainId, std::forward<AssembleElementFunc>(assembleElement)
519 for (
const auto& element : elements(
gridView(domainId)))
520 assembleElement(element);
526 catch (NumericalProblem &e)
528 std::cout <<
"rank " <<
gridView(domainId).comm().rank()
529 <<
" caught an exception while assembling:" << e.what()
535 if (
gridView(domainId).comm().size() > 1)
536 succeeded =
gridView(domainId).comm().min(succeeded);
540 DUNE_THROW(NumericalProblem,
"A process did not succeed in linearizing the system");
544 template<std::
size_t i, std::
size_t j,
typename std::enable_if_t<(i==j),
int> = 0>
545 Dune::MatrixIndexSet getJacobianPattern_(Dune::index_constant<i> domainI,
546 Dune::index_constant<j> domainJ)
const
549 if (timeSteppingMethod_->implicit())
564 template<std::
size_t i, std::
size_t j,
typename std::enable_if_t<(i!=j),
int> = 0>
565 Dune::MatrixIndexSet getJacobianPattern_(Dune::index_constant<i> domainI,
566 Dune::index_constant<j> domainJ)
const
568 if (timeSteppingMethod_->implicit())
582 void setProblemTime_(
const P& p,
const Scalar t)
583 { setProblemTimeImpl_(p, t, 0); }
586 auto setProblemTimeImpl_(
const P& p,
const Scalar t,
int) ->
decltype(p.setTime(0))
590 void setProblemTimeImpl_(
const P& p,
const Scalar t,
long)
593 std::shared_ptr<const Experimental::MultiStageMethod<Scalar>> timeSteppingMethod_;
594 std::vector<ResidualType> spatialOperatorEvaluations_;
595 std::vector<ResidualType> temporalOperatorEvaluations_;
597 std::shared_ptr<const StageParams> stageParams_;
600 ProblemTuple problemTuple_;
603 GridGeometryTuple gridGeometryTuple_;
606 GridVariablesTuple gridVariablesTuple_;
612 std::shared_ptr<JacobianMatrix> jacobian_;
613 std::shared_ptr<ResidualType> residual_;
616 bool enableMultithreading_ =
false;
Subdomain-specific views on multidomain assemblers.
Definition multistagefvlocaloperator.hh:23
Abstract interface for one-step multi-stage method parameters in Shu/Osher form.
Definition multistagemethods.hh:75
A linear system assembler (residual and Jacobian) for finite volume schemes (box, tpfa,...
Definition multistagemultidomainfvassembler.hh:95
MDTraits Traits
Definition multistagemultidomainfvassembler.hh:100
typename MDTraits::SolutionVector SolutionVector
Definition multistagemultidomainfvassembler.hh:119
GetPropType< SubDomainTypeTag< id >, Properties::LocalResidual > LocalResidual
TODO get rid of this GetPropType.
Definition multistagemultidomainfvassembler.hh:107
typename MDTraits::JacobianMatrix JacobianMatrix
Definition multistagemultidomainfvassembler.hh:118
typename MDTraits::Scalar Scalar
Definition multistagemultidomainfvassembler.hh:102
bool isStationaryProblem() const
TODO get rid of this (called by Newton but shouldn't be necessary)
Definition multistagemultidomainfvassembler.hh:392
void assembleJacobianAndResidual(const SolutionVector &curSol)
Assembles the global Jacobian of the residual and the residual for the current solution.
Definition multistagemultidomainfvassembler.hh:192
const GridVariables< i > & gridVariables(Dune::index_constant< i > domainId) const
the grid variables of domain i
Definition multistagemultidomainfvassembler.hh:309
typename MDTraits::template SubDomain< id >::GridGeometry GridGeometry
Definition multistagemultidomainfvassembler.hh:113
void clearStages()
Definition multistagemultidomainfvassembler.hh:335
MultiStageFVLocalOperator< LocalResidual< i > > localResidual(Dune::index_constant< i > domainId) const
Create a local residual object (used by the local assembler)
Definition multistagemultidomainfvassembler.hh:332
typename MDTraits::template SubDomain< id >::Problem Problem
Definition multistagemultidomainfvassembler.hh:116
bool isImplicit() const
Definition multistagemultidomainfvassembler.hh:395
std::shared_ptr< CouplingManager > couplingManager_
the coupling manager coupling the sub domains
Definition multistagemultidomainfvassembler.hh:400
typename MDTraits::ResidualVector ResidualType
Definition multistagemultidomainfvassembler.hh:120
const CouplingManager & couplingManager() const
the coupling manager
Definition multistagemultidomainfvassembler.hh:313
const auto & gridView(Dune::index_constant< i > domainId) const
the grid view of domain i
Definition multistagemultidomainfvassembler.hh:299
ResidualType & residual()
the full residual vector
Definition multistagemultidomainfvassembler.hh:321
const SolutionVector & prevSol() const
the solution before time integration
Definition multistagemultidomainfvassembler.hh:325
void setLinearSystem()
The version without arguments uses the default constructor to create the jacobian and residual object...
Definition multistagemultidomainfvassembler.hh:250
void resetTimeStep(const SolutionVector &curSol)
Resets the grid variables to the last time step.
Definition multistagemultidomainfvassembler.hh:273
typename MDTraits::template SubDomain< id >::GridVariables GridVariables
Definition multistagemultidomainfvassembler.hh:110
CMType CouplingManager
Definition multistagemultidomainfvassembler.hh:122
std::size_t numDofs(Dune::index_constant< i > domainId) const
the number of dof locations of domain i
Definition multistagemultidomainfvassembler.hh:284
void updateGridVariables(const SolutionVector &curSol)
Updates the grid variables with the given solution.
Definition multistagemultidomainfvassembler.hh:263
const auto & problem(Dune::index_constant< i > domainId) const
the problem of domain i
Definition multistagemultidomainfvassembler.hh:289
const auto & gridGeometry(Dune::index_constant< i > domainId) const
the finite volume grid geometry of domain i
Definition multistagemultidomainfvassembler.hh:294
void prepareStage(SolutionVector &x, StageParams params)
Definition multistagemultidomainfvassembler.hh:343
JacobianMatrix & jacobian()
the full Jacobian matrix
Definition multistagemultidomainfvassembler.hh:317
GridVariables< i > & gridVariables(Dune::index_constant< i > domainId)
the grid variables of domain i
Definition multistagemultidomainfvassembler.hh:304
MultiStageMultiDomainFVAssembler(ProblemTuple problem, GridGeometryTuple gridGeometry, GridVariablesTuple gridVariables, std::shared_ptr< CouplingManager > couplingManager, std::shared_ptr< const Experimental::MultiStageMethod< Scalar > > msMethod, const SolutionVector &prevSol)
The constructor for instationary problems.
Definition multistagemultidomainfvassembler.hh:165
void assembleResidual(const SolutionVector &curSol)
compute the residuals using the internal residual
Definition multistagemultidomainfvassembler.hh:243
Data object for the parameters of a given stage.
Definition multistagetimestepper.hh:31
The cell-centered scheme multidomain local assembler.
Definition experimental/assembly/subdomaincclocalassembler.hh:195
The CVFE scheme multidomain local assembler.
Definition experimental/assembly/subdomaincvfelocalassembler.hh:206
Subdomain-specific view on a multidomain assembler. Allows retrieval of sub-domain specific objects w...
Definition assemblerview.hh:31
Defines all properties used in Dumux.
Helper function to generate Jacobian pattern for multi domain models.
An enum class to define various differentiation methods available in order to compute the derivatives...
Some exceptions thrown in DuMux
A multidomain local assembler for Jacobian and residual contribution per element (cell-centered metho...
An assembler for Jacobian and residual contribution per element (CVFE methods) for multidomain proble...
dune-grid capabilities compatibility layer
Dune::MatrixIndexSet getJacobianPattern(const GridGeometry &gridGeometry)
Helper function to generate Jacobian pattern for cell-centered methods.
Definition jacobianpattern.hh:28
Dune::MatrixIndexSet getCouplingJacobianPattern(const CouplingManager &couplingManager, Dune::index_constant< i > domainI, const GridGeometryI &gridGeometryI, Dune::index_constant< j > domainJ, const GridGeometryJ &gridGeometryJ)
Helper function to generate coupling Jacobian pattern (off-diagonal blocks) for cell-centered schemes...
Definition couplingjacobianpattern.hh:30
constexpr bool isSerial()
Checking whether the backend is serial.
Definition multithreading.hh:45
T getParam(Args &&... args)
A free function to get a parameter from the parameter tree singleton.
Definition parameters.hh:139
typename GetProp< TypeTag, Property >::type GetPropType
get the type alias defined in the property
Definition propertysystem.hh:296
Helper function to generate Jacobian pattern for different discretization methods.
The available discretization methods in Dumux.
A local operator wrapper for multi-stage time stepping schemes.
Parameters for different multistage time stepping methods.
A time stepper performing a single time step of a transient simulation.
Definition experimental/assembly/cclocalassembler.hh:36
bool allGridsSupportsMultithreadingImpl(const T &gridGeometries, std::index_sequence< I... >)
Definition multistagemultidomainfvassembler.hh:52
Definition gridcapabilities.hh:57
bool allGridsSupportsMultithreading(const std::tuple< GG... > &gridGeometries)
Definition multistagemultidomainfvassembler.hh:60
bool supportsMultithreading(const GridView &gridView)
Definition gridcapabilities.hh:74
Provides a helper class for nonoverlapping decomposition.
Type trait that is specialized for coupling manager supporting multithreaded assembly.
Definition multidomain/fvassembler.hh:73
Utilities for template meta programming.