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>
 
  144    template<std::
size_t id>
 
  150    template<std::
size_t id, 
class DM>
 
  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
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
Experimental::MultiStageParams< Scalar > StageParams
Definition multistagemultidomainfvassembler.hh:103
std::shared_ptr< CouplingManager > couplingManager_
Definition multistagemultidomainfvassembler.hh:400
typename MDTraits::ResidualVector ResidualType
Definition multistagemultidomainfvassembler.hh:120
const CouplingManager & couplingManager() const
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
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
Definition multistagemultidomainfvassembler.hh:289
const auto & gridGeometry(Dune::index_constant< i > domainId) const
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)
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 cellcentered/mpfa/elementvolumevariables.hh:24
Definition experimental/assembly/cclocalassembler.hh:36
Definition multistagemultidomainfvassembler.hh:49
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 multistagemultidomainfvassembler.hh:78
Utilities for template meta programming.