version 3.11-dev
multidomain/fvassembler.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
14#ifndef DUMUX_MULTIDOMAIN_FV_ASSEMBLER_HH
15#define DUMUX_MULTIDOMAIN_FV_ASSEMBLER_HH
16
17#include <type_traits>
18#include <tuple>
19
20#include <dune/common/hybridutilities.hh>
21#include <dune/istl/matrixindexset.hh>
22
34
39#include "assemblerview.hh"
40
42#if HAVE_DUMUX_OLD_STAGGERED
43#include <dumux/multidomain/subdomainstaggeredlocalassembler.hh>
44#endif
45
46namespace Dumux {
47
48template<std::size_t id, class TypeTag, class Assembler, DiffMethod DM, bool implicit>
50
51namespace Grid::Capabilities {
52
53namespace Detail {
54// helper for multi-domain models
55template<class T, std::size_t... I>
56bool allGridsSupportsMultithreadingImpl(const T& gridGeometries, std::index_sequence<I...>)
57{
58 return (... && supportsMultithreading(std::get<I>(gridGeometries)->gridView()));
59}
60} // end namespace Detail
61
62// helper for multi-domain models (all grids have to support multithreading)
63template<class... GG>
64bool allGridsSupportsMultithreading(const std::tuple<GG...>& gridGeometries)
65{
66 return Detail::allGridsSupportsMultithreadingImpl<std::tuple<GG...>>(gridGeometries, std::make_index_sequence<sizeof...(GG)>());
67}
68
69} // end namespace Grid::Capabilities
70
71namespace Detail {
72
74template<class P>
75using SubProblemConstraintsDetector = decltype(std::declval<P>().constraints());
76
77template<class P>
78constexpr inline bool hasSubProblemGlobalConstraints()
79{ return Dune::Std::is_detected<SubProblemConstraintsDetector, P>::value; }
80
81} // end namespace Detail
82
88template<class CM>
89struct CouplingManagerSupportsMultithreadedAssembly : public std::false_type
90{};
91
101template<class MDTraits, class CMType, DiffMethod diffMethod, bool useImplicitAssembly = true>
103{
104 template<std::size_t id>
105 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
106
107public:
108 using Traits = MDTraits;
109
110 using Scalar = typename MDTraits::Scalar;
111
112 template<std::size_t id>
113 using LocalResidual = typename MDTraits::template SubDomain<id>::LocalResidual;
114
115 template<std::size_t id>
116 using GridVariables = typename MDTraits::template SubDomain<id>::GridVariables;
117
118 template<std::size_t id>
119 using GridGeometry = typename MDTraits::template SubDomain<id>::GridGeometry;
120
121 template<std::size_t id>
122 using Problem = typename MDTraits::template SubDomain<id>::Problem;
123
124 using JacobianMatrix = typename MDTraits::JacobianMatrix;
125 using SolutionVector = typename MDTraits::SolutionVector;
126 using ResidualType = typename MDTraits::ResidualVector;
127
128 using CouplingManager = CMType;
129
133 static constexpr bool isImplicit()
134 { return useImplicitAssembly; }
135
136private:
137
138 using ProblemTuple = typename MDTraits::template TupleOfSharedPtrConst<Problem>;
139 using GridGeometryTuple = typename MDTraits::template TupleOfSharedPtrConst<GridGeometry>;
140 using GridVariablesTuple = typename MDTraits::template TupleOfSharedPtr<GridVariables>;
141
143 using ThisType = MultiDomainFVAssembler<MDTraits, CouplingManager, diffMethod, isImplicit()>;
144
145 template<std::size_t id>
146 using SubDomainAssemblerView = MultiDomainAssemblerSubDomainView<ThisType, id>;
147
148 template<class DiscretizationMethod, std::size_t id>
149 struct SubDomainAssemblerType;
150
151 template<std::size_t id>
152 struct SubDomainAssemblerType<DiscretizationMethods::CCTpfa, id>
153 {
154 using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
155 };
156
157 template<std::size_t id>
158 struct SubDomainAssemblerType<DiscretizationMethods::CCMpfa, id>
159 {
160 using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
161 };
162
163 template<std::size_t id, class DM>
164 struct SubDomainAssemblerType<DiscretizationMethods::CVFE<DM>, id>
165 {
166 using type = SubDomainCVFELocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
167 };
168
169 template<std::size_t id>
170 struct SubDomainAssemblerType<DiscretizationMethods::Staggered, id>
171 {
172 using type = SubDomainStaggeredLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
173 };
174
175 template<std::size_t id>
176 struct SubDomainAssemblerType<DiscretizationMethods::FCStaggered, id>
177 {
178 using type = SubDomainFaceCenteredLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
179 };
180
181 template<std::size_t id>
182 using SubDomainAssembler = typename SubDomainAssemblerType<typename GridGeometry<id>::DiscretizationMethod, id>::type;
183
184public:
185
186
193 GridGeometryTuple gridGeometry,
194 GridVariablesTuple gridVariables,
195 std::shared_ptr<CouplingManager> couplingManager)
197 , problemTuple_(std::move(problem))
198 , gridGeometryTuple_(std::move(gridGeometry))
199 , gridVariablesTuple_(std::move(gridVariables))
200 , timeLoop_()
201 , isStationaryProblem_(true)
202 , warningIssued_(false)
203 {
204 static_assert(isImplicit(), "Explicit assembler for stationary problem doesn't make sense!");
205 std::cout << "Instantiated assembler for a stationary problem." << std::endl;
206
210 && getParam<bool>("Assembly.Multithreading", true);
211
212 maybeComputeColors_();
213 }
214
221 GridGeometryTuple gridGeometry,
222 GridVariablesTuple gridVariables,
223 std::shared_ptr<CouplingManager> couplingManager,
224 std::shared_ptr<const TimeLoop> timeLoop,
225 const SolutionVector& prevSol)
227 , problemTuple_(std::move(problem))
228 , gridGeometryTuple_(std::move(gridGeometry))
229 , gridVariablesTuple_(std::move(gridVariables))
230 , timeLoop_(timeLoop)
231 , prevSol_(&prevSol)
232 , isStationaryProblem_(false)
233 , warningIssued_(false)
234 {
235 std::cout << "Instantiated assembler for an instationary problem." << std::endl;
236
240 && getParam<bool>("Assembly.Multithreading", true);
241
242 maybeComputeColors_();
243 }
244
250 {
251 checkAssemblerState_();
252 resetJacobian_();
253 resetResidual_();
254
255 using namespace Dune::Hybrid;
256 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](const auto domainId)
257 {
258 auto& jacRow = (*jacobian_)[domainId];
259 auto& subRes = (*residual_)[domainId];
260 const auto& subSol = curSol[domainId];
261 this->assembleJacobianAndResidual_(domainId, jacRow, subRes, curSol);
262
263 const auto gridGeometry = std::get<domainId>(gridGeometryTuple_);
264 enforcePeriodicConstraints_(domainId, jacRow, subRes, *gridGeometry, subSol);
265 enforceGlobalDirichletConstraints_(domainId, jacRow, subRes, *gridGeometry, subSol);
266 });
267 }
268
271 {
272 resetResidual_();
273 assembleResidual(*residual_, curSol);
274 }
275
278 {
279 r = 0.0;
280
281 checkAssemblerState_();
282
283 // update the grid variables for the case of active caching
284 updateGridVariables(curSol);
285
286 using namespace Dune::Hybrid;
287 forEach(integralRange(Dune::Hybrid::size(r)), [&](const auto domainId)
288 {
289 auto& subRes = r[domainId];
290 this->assembleResidual_(domainId, subRes, curSol);
291 });
292 }
293
299 void setLinearSystem(std::shared_ptr<JacobianMatrix> A,
300 std::shared_ptr<ResidualType> r)
301 {
302 jacobian_ = A;
303 residual_ = r;
304
305 setJacobianBuildMode(*jacobian_);
306 setJacobianPattern_(*jacobian_);
307 setResidualSize_(*residual_);
308 }
309
315 {
316 jacobian_ = std::make_shared<JacobianMatrix>();
317 residual_ = std::make_shared<ResidualType>();
318
319 setJacobianBuildMode(*jacobian_);
320 setJacobianPattern_(*jacobian_);
321 setResidualSize_(*residual_);
322 }
323
328 {
329 using namespace Dune::Hybrid;
330 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](const auto i)
331 {
332 forEach(jac[i], [&](auto& jacBlock)
333 {
334 using BlockType = std::decay_t<decltype(jacBlock)>;
335 if (jacBlock.buildMode() == BlockType::BuildMode::unknown)
336 jacBlock.setBuildMode(BlockType::BuildMode::random);
337 else if (jacBlock.buildMode() != BlockType::BuildMode::random)
338 DUNE_THROW(Dune::NotImplemented, "Only BCRS matrices with random build mode are supported at the moment");
339 });
340 });
341 }
342
347 {
348 setJacobianPattern_(*jacobian_);
349 setResidualSize_(*residual_);
350 maybeComputeColors_();
351 }
352
357 {
358 using namespace Dune::Hybrid;
359 forEach(integralRange(Dune::Hybrid::size(gridVariablesTuple_)), [&](const auto domainId)
360 { this->gridVariables(domainId).update(curSol[domainId]); });
361 }
362
366 void resetTimeStep(const SolutionVector& curSol)
367 {
368 using namespace Dune::Hybrid;
369 forEach(integralRange(Dune::Hybrid::size(gridVariablesTuple_)), [&](const auto domainId)
370 { this->gridVariables(domainId).resetTimeStep(curSol[domainId]); });
371 }
372
374 template<std::size_t i>
375 std::size_t numDofs(Dune::index_constant<i> domainId) const
376 { return std::get<domainId>(gridGeometryTuple_)->numDofs(); }
377
379 template<std::size_t i>
380 const auto& problem(Dune::index_constant<i> domainId) const
381 { return *std::get<domainId>(problemTuple_); }
382
384 template<std::size_t i>
385 const auto& gridGeometry(Dune::index_constant<i> domainId) const
386 { return *std::get<domainId>(gridGeometryTuple_); }
387
389 template<std::size_t i>
390 const auto& gridView(Dune::index_constant<i> domainId) const
391 { return gridGeometry(domainId).gridView(); }
392
394 template<std::size_t i>
395 GridVariables<i>& gridVariables(Dune::index_constant<i> domainId)
396 { return *std::get<domainId>(gridVariablesTuple_); }
397
399 template<std::size_t i>
400 const GridVariables<i>& gridVariables(Dune::index_constant<i> domainId) const
401 { return *std::get<domainId>(gridVariablesTuple_); }
402
405 { return *couplingManager_; }
406
409 { return *jacobian_; }
410
413 { return *residual_; }
414
416 const SolutionVector& prevSol() const
417 { return *prevSol_; }
418
423 void setTimeManager(std::shared_ptr<const TimeLoop> timeLoop)
424 { timeLoop_ = timeLoop; isStationaryProblem_ = !(static_cast<bool>(timeLoop)); }
425
431 { prevSol_ = &u; }
432
437 { return isStationaryProblem_; }
438
442 template<std::size_t i>
443 LocalResidual<i> localResidual(Dune::index_constant<i> domainId) const
444 { return LocalResidual<i>(std::get<domainId>(problemTuple_).get(), timeLoop_.get()); }
445
446protected:
448 std::shared_ptr<CouplingManager> couplingManager_;
449
450private:
454 void setJacobianPattern_(JacobianMatrix& jac) const
455 {
456 using namespace Dune::Hybrid;
457 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](const auto domainI)
458 {
459 forEach(integralRange(Dune::Hybrid::size(jac[domainI])), [&](const auto domainJ)
460 {
461 const auto pattern = this->getJacobianPattern_(domainI, domainJ);
462 pattern.exportIdx(jac[domainI][domainJ]);
463 });
464 });
465 }
466
470 void setResidualSize_(ResidualType& res) const
471 {
472 using namespace Dune::Hybrid;
473 forEach(integralRange(Dune::Hybrid::size(res)), [&](const auto domainId)
474 { res[domainId].resize(this->numDofs(domainId)); });
475 }
476
477 // reset the residual vector to 0.0
478 void resetResidual_()
479 {
480 if(!residual_)
481 {
482 residual_ = std::make_shared<ResidualType>();
483 setResidualSize_(*residual_);
484 }
485
486 (*residual_) = 0.0;
487 }
488
489 // reset the jacobian vector to 0.0
490 void resetJacobian_()
491 {
492 if(!jacobian_)
493 {
494 jacobian_ = std::make_shared<JacobianMatrix>();
495 setJacobianBuildMode(*jacobian_);
496 setJacobianPattern_(*jacobian_);
497 }
498
499 (*jacobian_) = 0.0;
500 }
501
503 void maybeComputeColors_()
504 {
505 if constexpr (CouplingManagerSupportsMultithreadedAssembly<CouplingManager>::value)
506 if (enableMultithreading_)
507 couplingManager_->computeColorsForAssembly();
508 }
509
510 // check if the assembler is in a correct state for assembly
511 void checkAssemblerState_() const
512 {
513 if (!isStationaryProblem_ && !prevSol_)
514 DUNE_THROW(Dune::InvalidStateException, "Assembling instationary problem but previous solution was not set!");
515
516 if (isStationaryProblem_ && prevSol_)
517 DUNE_THROW(Dune::InvalidStateException, "Assembling stationary problem but a previous solution was set."
518 << " Did you forget to set the timeLoop to make this problem instationary?");
519 }
520
521 template<std::size_t i, class JacRow, class SubRes>
522 void assembleJacobianAndResidual_(Dune::index_constant<i> domainId, JacRow& jacRow, SubRes& subRes,
523 const SolutionVector& curSol)
524 {
525 assemble_(domainId, [&](const auto& element)
526 {
527 MultiDomainAssemblerSubDomainView view{*this, domainId};
528 SubDomainAssembler<i> subDomainAssembler(view, element, curSol, *couplingManager_);
529 subDomainAssembler.assembleJacobianAndResidual(jacRow, subRes, gridVariablesTuple_);
530 });
531 }
532
533 template<std::size_t i, class SubRes>
534 void assembleResidual_(Dune::index_constant<i> domainId, SubRes& subRes,
535 const SolutionVector& curSol)
536 {
537 assemble_(domainId, [&](const auto& element)
538 {
539 MultiDomainAssemblerSubDomainView view{*this, domainId};
540 SubDomainAssembler<i> subDomainAssembler(view, element, curSol, *couplingManager_);
541 subDomainAssembler.assembleResidual(subRes);
542 });
543 }
544
550 template<std::size_t i, class AssembleElementFunc>
551 void assemble_(Dune::index_constant<i> domainId, AssembleElementFunc&& assembleElement) const
552 {
553 // a state that will be checked on all processes
554 bool succeeded = false;
555
556 // try assembling using the local assembly function
557 try
558 {
559 if constexpr (CouplingManagerSupportsMultithreadedAssembly<CouplingManager>::value)
560 {
561 if (enableMultithreading_)
562 {
563 couplingManager_->assembleMultithreaded(
564 domainId, std::forward<AssembleElementFunc>(assembleElement)
565 );
566 return;
567 }
568 }
569
570 // fallback for coupling managers that don't support multithreaded assembly (yet)
571 // or if multithreaded assembly is disabled
572 // let the local assembler add the element contributions
573 for (const auto& element : elements(gridView(domainId)))
574 assembleElement(element);
575
576 // if we get here, everything worked well on this process
577 succeeded = true;
578 }
579 // throw exception if a problem occurred
580 catch (NumericalProblem &e)
581 {
582 std::cout << "rank " << gridView(domainId).comm().rank()
583 << " caught an exception while assembling:" << e.what()
584 << "\n";
585 succeeded = false;
586 }
587
588 // make sure everything worked well on all processes
589 if (gridView(domainId).comm().size() > 1)
590 succeeded = gridView(domainId).comm().min(succeeded);
591
592 // if not succeeded rethrow the error on all processes
593 if (!succeeded)
594 DUNE_THROW(NumericalProblem, "A process did not succeed in linearizing the system");
595 }
596
597 // get diagonal block pattern
598 template<std::size_t i, std::size_t j, typename std::enable_if_t<(i==j), int> = 0>
599 Dune::MatrixIndexSet getJacobianPattern_(Dune::index_constant<i> domainI,
600 Dune::index_constant<j> domainJ) const
601 {
602 const auto& gg = gridGeometry(domainI);
603 auto pattern = getJacobianPattern<isImplicit()>(gg);
604 couplingManager_->extendJacobianPattern(domainI, pattern);
605 return pattern;
606 }
607
608 // get coupling block pattern
609 template<std::size_t i, std::size_t j, typename std::enable_if_t<(i!=j), int> = 0>
610 Dune::MatrixIndexSet getJacobianPattern_(Dune::index_constant<i> domainI,
611 Dune::index_constant<j> domainJ) const
612 {
613 return getCouplingJacobianPattern<isImplicit()>(*couplingManager_,
614 domainI, gridGeometry(domainI),
615 domainJ, gridGeometry(domainJ));
616 }
617
618 // build periodic constraints into the system matrix
619 template<std::size_t i, class JacRow, class Res, class GG, class Sol>
620 void enforcePeriodicConstraints_(Dune::index_constant<i> domainI, JacRow& jacRow, Res& res, const GG& gridGeometry, const Sol& curSol)
621 {
622 if constexpr (Detail::hasPeriodicDofMap<GG>())
623 {
624 for (const auto& m : gridGeometry.periodicDofMap())
625 {
626 if (m.first < m.second)
627 {
628 auto& jac = jacRow[domainI];
629
630 // add the second row to the first
631 res[m.first] += res[m.second];
632
633 const auto end = jac[m.second].end();
634 for (auto it = jac[m.second].begin(); it != end; ++it)
635 jac[m.first][it.index()] += (*it);
636
637
638 // enforce the solution of the first periodic DOF to the second one
639 res[m.second] = curSol[m.second] - curSol[m.first];
640
641 // set derivatives accordingly in jacobian, i.e. id for m.second and -id for m.first
642 auto setMatrixBlock = [] (auto& matrixBlock, double diagValue)
643 {
644 for (int eIdx = 0; eIdx < matrixBlock.N(); ++eIdx)
645 matrixBlock[eIdx][eIdx] = diagValue;
646 };
647
648 for (auto it = jac[m.second].begin(); it != end; ++it)
649 {
650 auto& matrixBlock = *it;
651 matrixBlock = 0.0;
652
653 assert(matrixBlock.N() == matrixBlock.M());
654 if(it.index() == m.second)
655 setMatrixBlock(matrixBlock, 1.0);
656
657 if(it.index() == m.first)
658 setMatrixBlock(matrixBlock, -1.0);
659
660 }
661
662 using namespace Dune::Hybrid;
663 forEach(makeIncompleteIntegerSequence<JacRow::size(), domainI>(), [&](const auto couplingDomainId)
664 {
665 auto& jacCoupling = jacRow[couplingDomainId];
666
667 for (auto it = jacCoupling[m.second].begin(); it != jacCoupling[m.second].end(); ++it)
668 jacCoupling[m.first][it.index()] += (*it);
669
670 for (auto it = jacCoupling[m.second].begin(); it != jacCoupling[m.second].end(); ++it)
671 (*it) = 0.0;
672 });
673 }
674 }
675 }
676 }
677
678 // enforce global constraints into the system matrix
679 template<std::size_t i, class JacRow, class Res, class GG, class Sol>
680 void enforceGlobalDirichletConstraints_(Dune::index_constant<i> domainI, JacRow& jacRow, Res& res, const GG& gridGeometry, const Sol& curSol)
681 {
682 if constexpr (Detail::hasSubProblemGlobalConstraints<Problem<domainI>>())
683 {
684 auto& jac = jacRow[domainI];
685 auto applyDirichletConstraint = [&] (const auto& dofIdx,
686 const auto& values,
687 const auto eqIdx,
688 const auto pvIdx)
689 {
690 (res)[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
691
692 auto& row = jac[dofIdx];
693 for (auto col = row.begin(); col != row.end(); ++col)
694 row[col.index()][eqIdx] = 0.0;
695
696 jac[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
697
698 using namespace Dune::Hybrid;
699 forEach(makeIncompleteIntegerSequence<JacRow::size(), domainI>(), [&](const auto couplingDomainId)
700 {
701 auto& jacCoupling = jacRow[couplingDomainId];
702
703 auto& rowCoupling = jacCoupling[dofIdx];
704 for (auto colCoupling = rowCoupling.begin(); colCoupling != rowCoupling.end(); ++colCoupling)
705 rowCoupling[colCoupling.index()][eqIdx] = 0.0;
706 });
707
708 };
709
710 for (const auto& constraintData : this->problem(domainI).constraints())
711 {
712 const auto& constraintInfo = constraintData.constraintInfo();
713 const auto& values = constraintData.values();
714 const auto dofIdx = constraintData.dofIndex();
715 // set the constraint in residual and jacobian
716 for (int eqIdx = 0; eqIdx < constraintInfo.size(); ++eqIdx)
717 {
718 if (constraintInfo.isConstraintEquation(eqIdx))
719 {
720 const auto pvIdx = constraintInfo.eqToPriVarIndex(eqIdx);
721 assert(0 <= pvIdx && pvIdx < constraintInfo.size());
722 applyDirichletConstraint(dofIdx, values, eqIdx, pvIdx);
723 }
724 }
725 }
726 }
727 }
728
730 ProblemTuple problemTuple_;
731
733 GridGeometryTuple gridGeometryTuple_;
734
736 GridVariablesTuple gridVariablesTuple_;
737
739 std::shared_ptr<const TimeLoop> timeLoop_;
740
742 const SolutionVector* prevSol_ = nullptr;
743
745 bool isStationaryProblem_;
746
748 std::shared_ptr<JacobianMatrix> jacobian_;
749 std::shared_ptr<ResidualType> residual_;
750
752 mutable bool warningIssued_;
753
755 bool enableMultithreading_ = false;
756};
757
758} // end namespace Dumux
759
760#endif
Subdomain-specific views on multidomain assemblers.
Subdomain-specific view on a multidomain assembler. Allows retrieval of sub-domain specific objects w...
Definition: assemblerview.hh:31
A linear system assembler (residual and Jacobian) for finite volume schemes (box, tpfa,...
Definition: multidomain/fvassembler.hh:103
std::size_t numDofs(Dune::index_constant< i > domainId) const
the number of dof locations of domain i
Definition: multidomain/fvassembler.hh:375
void updateGridVariables(const SolutionVector &curSol)
Updates the grid variables with the given solution.
Definition: multidomain/fvassembler.hh:356
void updateAfterGridAdaption()
Resizes jacobian and residual and recomputes colors.
Definition: multidomain/fvassembler.hh:346
typename MDTraits::SolutionVector SolutionVector
Definition: multidomain/fvassembler.hh:125
typename MDTraits::template SubDomain< id >::Problem Problem
Definition: multidomain/fvassembler.hh:122
JacobianMatrix & jacobian()
the full Jacobian matrix
Definition: multidomain/fvassembler.hh:408
static constexpr bool isImplicit()
Returns true if the assembler considers implicit assembly.
Definition: multidomain/fvassembler.hh:133
void assembleResidual(ResidualType &r, const SolutionVector &curSol)
assemble a residual r
Definition: multidomain/fvassembler.hh:277
typename MDTraits::JacobianMatrix JacobianMatrix
Definition: multidomain/fvassembler.hh:124
CMType CouplingManager
Definition: multidomain/fvassembler.hh:128
void assembleResidual(const SolutionVector &curSol)
compute the residuals using the internal residual
Definition: multidomain/fvassembler.hh:270
void resetTimeStep(const SolutionVector &curSol)
Resets the grid variables to the last time step.
Definition: multidomain/fvassembler.hh:366
const GridVariables< i > & gridVariables(Dune::index_constant< i > domainId) const
the grid variables of domain i
Definition: multidomain/fvassembler.hh:400
void setPreviousSolution(const SolutionVector &u)
Sets the solution from which to start the time integration. Has to be called prior to assembly for ti...
Definition: multidomain/fvassembler.hh:430
typename MDTraits::template SubDomain< id >::GridVariables GridVariables
Definition: multidomain/fvassembler.hh:116
const auto & gridGeometry(Dune::index_constant< i > domainId) const
the finite volume grid geometry of domain i
Definition: multidomain/fvassembler.hh:385
void setLinearSystem()
The version without arguments uses the default constructor to create the jacobian and residual object...
Definition: multidomain/fvassembler.hh:314
const auto & gridView(Dune::index_constant< i > domainId) const
the grid view of domain i
Definition: multidomain/fvassembler.hh:390
typename MDTraits::template SubDomain< id >::GridGeometry GridGeometry
Definition: multidomain/fvassembler.hh:119
const CouplingManager & couplingManager() const
the coupling manager
Definition: multidomain/fvassembler.hh:404
void setTimeManager(std::shared_ptr< const TimeLoop > timeLoop)
Set time loop for instationary problems.
Definition: multidomain/fvassembler.hh:423
const SolutionVector & prevSol() const
the solution of the previous time step
Definition: multidomain/fvassembler.hh:416
GridVariables< i > & gridVariables(Dune::index_constant< i > domainId)
the grid variables of domain i
Definition: multidomain/fvassembler.hh:395
std::shared_ptr< CouplingManager > couplingManager_
the coupling manager coupling the sub domains
Definition: multidomain/fvassembler.hh:448
MDTraits Traits
Definition: multidomain/fvassembler.hh:108
MultiDomainFVAssembler(ProblemTuple problem, GridGeometryTuple gridGeometry, GridVariablesTuple gridVariables, std::shared_ptr< CouplingManager > couplingManager, std::shared_ptr< const TimeLoop > timeLoop, const SolutionVector &prevSol)
The constructor for instationary problems.
Definition: multidomain/fvassembler.hh:220
void setJacobianBuildMode(JacobianMatrix &jac) const
Sets the jacobian build mode.
Definition: multidomain/fvassembler.hh:327
typename MDTraits::template SubDomain< id >::LocalResidual LocalResidual
Definition: multidomain/fvassembler.hh:113
LocalResidual< i > localResidual(Dune::index_constant< i > domainId) const
Create a local residual object (used by the local assembler)
Definition: multidomain/fvassembler.hh:443
const auto & problem(Dune::index_constant< i > domainId) const
the problem of domain i
Definition: multidomain/fvassembler.hh:380
typename MDTraits::ResidualVector ResidualType
Definition: multidomain/fvassembler.hh:126
MultiDomainFVAssembler(ProblemTuple problem, GridGeometryTuple gridGeometry, GridVariablesTuple gridVariables, std::shared_ptr< CouplingManager > couplingManager)
The constructor for stationary problems.
Definition: multidomain/fvassembler.hh:192
void assembleJacobianAndResidual(const SolutionVector &curSol)
Assembles the global Jacobian of the residual and the residual for the current solution.
Definition: multidomain/fvassembler.hh:249
bool isStationaryProblem() const
Whether we are assembling a stationary or instationary problem.
Definition: multidomain/fvassembler.hh:436
typename MDTraits::Scalar Scalar
Definition: multidomain/fvassembler.hh:110
ResidualType & residual()
the full residual vector
Definition: multidomain/fvassembler.hh:412
void setLinearSystem(std::shared_ptr< JacobianMatrix > A, std::shared_ptr< ResidualType > r)
Tells the assembler which jacobian and residual to use. This also resizes the containers to the requi...
Definition: multidomain/fvassembler.hh:299
The cell-centered scheme multidomain local assembler.
Definition: multidomain/subdomaincclocalassembler.hh:270
Definition: multidomain/fvassembler.hh:49
The default time loop for instationary simulations.
Definition: common/timeloop.hh:139
Defines all properties used in Dumux.
Manages the handling of time dependent problems.
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
dune-grid capabilities compatibility layer
constexpr bool isSerial()
Checking whether the backend is serial.
Definition: multithreading.hh:45
Helper function to generate Jacobian pattern for different discretization methods.
The available discretization methods 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...
Multithreading in Dumux.
decltype(std::declval< P >().constraints()) SubProblemConstraintsDetector
helper struct detecting if sub-problem has a constraints() function
Definition: multidomain/fvassembler.hh:75
constexpr bool hasSubProblemGlobalConstraints()
Definition: multidomain/fvassembler.hh:78
bool allGridsSupportsMultithreadingImpl(const T &gridGeometries, std::index_sequence< I... >)
Definition: multistagemultidomainfvassembler.hh:52
bool allGridsSupportsMultithreading(const std::tuple< GG... > &gridGeometries)
Definition: multistagemultidomainfvassembler.hh:60
bool supportsMultithreading(const GridView &gridView)
Definition: gridcapabilities.hh:34
Definition: adapt.hh:17
typename Detail::ConcatSeq< decltype(std::make_index_sequence< e >{}), e+1, decltype(std::make_index_sequence<(n > e) ?(n - e - 1) :0 >{})>::type makeIncompleteIntegerSequence
Definition: utility.hh:59
Provides a helper class for nonoverlapping decomposition.
Type traits to detect periodicity support.
Type trait that is specialized for coupling manager supporting multithreaded assembly.
Definition: multistagemultidomainfvassembler.hh:78
An assembler for Jacobian and residual contribution per element (face-centered staggered methods) for...
Utilities for template meta programming.