version 3.11-dev
Loading...
Searching...
No Matches
multidomain/assembler.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_ASSEMBLER_HH
15#define DUMUX_MULTIDOMAIN_ASSEMBLER_HH
16
17#include <algorithm>
18#include <cassert>
19#include <iostream>
20#include <type_traits>
21#include <tuple>
22
23#include <dune/common/hybridutilities.hh>
24#include <dune/istl/matrixindexset.hh>
25
34#include <dumux/common/concepts/variables_.hh>
39
42#include "subdomaincvfelocalassembler_.hh"
45#include "assemblerview.hh"
46#include "assemblytraits.hh"
47
49#if HAVE_DUMUX_OLD_STAGGERED
50#include <dumux/multidomain/subdomainstaggeredlocalassembler.hh>
51#endif
52
53namespace Dumux::Experimental {
54
64template<class MDTraits, class CMType, DiffMethod diffMethod, bool useImplicitAssembly = true>
66{
67 template<std::size_t id>
68 using SubDomainTypeTag = typename MDTraits::template SubDomain<id>::TypeTag;
69
70public:
71 using Traits = MDTraits;
72
73 using Scalar = typename MDTraits::Scalar;
74
75 template<std::size_t id>
76 using LocalResidual = typename MDTraits::template SubDomain<id>::LocalResidual;
77
78 template<std::size_t id>
79 using GridVariables = typename MDTraits::template SubDomain<id>::GridVariables;
80
81 template<std::size_t id>
82 using GridDiscretization = GetPropType<SubDomainTypeTag<id>, Properties::GridGeometry>;
83
84 template<std::size_t id>
85 using Problem = typename MDTraits::template SubDomain<id>::Problem;
86
87 using JacobianMatrix = typename MDTraits::JacobianMatrix;
88 using SolutionVector = typename MDTraits::SolutionVector;
89 using ResidualType = typename MDTraits::ResidualVector;
90
91 using CouplingManager = CMType;
92
96 static constexpr bool isImplicit()
97 { return useImplicitAssembly; }
98
99private:
100
101 using ProblemTuple = typename MDTraits::template TupleOfSharedPtrConst<Problem>;
102 using GridDiscretizationTuple = typename MDTraits::template TupleOfSharedPtrConst<GridDiscretization>;
103 using GridVariablesTuple = typename MDTraits::template TupleOfSharedPtr<GridVariables>;
104
106 using ThisType = MultiDomainAssembler<MDTraits, CouplingManager, diffMethod, isImplicit()>;
107
108 template<std::size_t id>
109 using SubDomainAssemblerView = MultiDomainAssemblerSubDomainView<ThisType, id>;
110
111 template<class DiscretizationMethod, std::size_t id>
112 struct SubDomainAssemblerType;
113
114 template<std::size_t id>
115 struct SubDomainAssemblerType<DiscretizationMethods::CCTpfa, id>
116 {
117 using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
118 };
119
120 template<std::size_t id>
121 struct SubDomainAssemblerType<DiscretizationMethods::CCMpfa, id>
122 {
123 using type = SubDomainCCLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
124 };
125
126 template<std::size_t id, class DM>
127 struct SubDomainAssemblerType<DiscretizationMethods::CVFE<DM>, id>
128 {
129 private:
130 using GV = GridVariables<id>;
131 static constexpr bool usesGeneralGridVariables =
132 Dumux::Concept::GridVariables<GV> && !Dumux::Concept::FVGridVariables<GV>;
133 public:
134 using type = std::conditional_t<usesGeneralGridVariables,
136 Dumux::SubDomainCVFELocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>>;
137 };
138
139#if HAVE_DUMUX_OLD_STAGGERED
140 template<std::size_t id>
141 struct SubDomainAssemblerType<DiscretizationMethods::Staggered, id>
142 {
143 using type = SubDomainStaggeredLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
144 };
145#endif
146
147 template<std::size_t id>
148 struct SubDomainAssemblerType<DiscretizationMethods::FCStaggered, id>
149 {
150 using type = SubDomainFaceCenteredLocalAssembler<id, SubDomainTypeTag<id>, SubDomainAssemblerView<id>, diffMethod, isImplicit()>;
151 };
152
153 template<std::size_t id>
154 using SubDomainAssembler = typename SubDomainAssemblerType<typename GridDiscretization<id>::DiscretizationMethod, id>::type;
155
156public:
157
164 GridDiscretizationTuple gridDiscretization,
165 GridVariablesTuple gridVariables,
166 std::shared_ptr<CouplingManager> couplingManager)
168 , problemTuple_(std::move(problem))
169 , gridDiscretizationTuple_(std::move(gridDiscretization))
170 , gridVariablesTuple_(std::move(gridVariables))
171 , timeLoop_()
172 , isStationaryProblem_(true)
173 , warningIssued_(false)
174 {
175 static_assert(isImplicit(), "Explicit assembler for stationary problem doesn't make sense!");
176 std::cout << "Instantiated assembler for a stationary problem." << std::endl;
177
179 && Grid::Capabilities::allGridsSupportsMultithreading(gridDiscretizationTuple_)
181 && getParam<bool>("Assembly.Multithreading", true);
182
183 maybeComputeColors_();
184 }
185
192 GridDiscretizationTuple gridDiscretization,
193 GridVariablesTuple gridVariables,
194 std::shared_ptr<CouplingManager> couplingManager,
195 std::shared_ptr<const TimeLoop> timeLoop,
196 const SolutionVector& prevSol)
198 , problemTuple_(std::move(problem))
199 , gridDiscretizationTuple_(std::move(gridDiscretization))
200 , gridVariablesTuple_(std::move(gridVariables))
201 , timeLoop_(timeLoop)
202 , prevSol_(&prevSol)
203 , isStationaryProblem_(false)
204 , warningIssued_(false)
205 {
206 std::cout << "Instantiated assembler for an instationary problem." << std::endl;
207
209 && Grid::Capabilities::allGridsSupportsMultithreading(gridDiscretizationTuple_)
211 && getParam<bool>("Assembly.Multithreading", true);
212
213 maybeComputeColors_();
214 }
215
221 {
222 checkAssemblerState_();
223 resetJacobian_();
224 resetResidual_();
225
226 using namespace Dune::Hybrid;
227 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](const auto domainId)
228 {
229 auto& jacRow = (*jacobian_)[domainId];
230 auto& subRes = (*residual_)[domainId];
231 const auto& subSol = curSol[domainId];
232 this->assembleJacobianAndResidual_(domainId, jacRow, subRes, curSol);
233
234 const auto gridDiscretization = std::get<domainId>(gridDiscretizationTuple_);
235 enforcePeriodicConstraints_(domainId, jacRow, subRes, *gridDiscretization, subSol);
236 enforceProblemConstraints_(domainId, jacRow, subRes, *gridDiscretization, subSol);
237 });
238 }
239
242 {
243 resetResidual_();
244 assembleResidual(*residual_, curSol);
245 }
246
249 {
250 r = 0.0;
251
252 checkAssemblerState_();
253
254 // update the grid variables for the case of active caching
255 updateGridVariables(curSol);
256
257 using namespace Dune::Hybrid;
258 forEach(integralRange(Dune::Hybrid::size(r)), [&](const auto domainId)
259 {
260 auto& subRes = r[domainId];
261 const auto& subSol = curSol[domainId];
262 this->assembleResidual_(domainId, subRes, curSol);
263
264 const auto gridDiscretization = std::get<domainId>(gridDiscretizationTuple_);
265 enforcePeriodicConstraints_(domainId, subRes, *gridDiscretization, subSol);
266 enforceProblemConstraints_(domainId, subRes, *gridDiscretization, subSol);
267 });
268 }
269
275 void setLinearSystem(std::shared_ptr<JacobianMatrix> A,
276 std::shared_ptr<ResidualType> r)
277 {
278 jacobian_ = A;
279 residual_ = r;
280
281 setJacobianBuildMode(*jacobian_);
282 setJacobianPattern_(*jacobian_);
283 setResidualSize_(*residual_);
284 }
285
291 {
292 jacobian_ = std::make_shared<JacobianMatrix>();
293 residual_ = std::make_shared<ResidualType>();
294
295 setJacobianBuildMode(*jacobian_);
296 setJacobianPattern_(*jacobian_);
297 setResidualSize_(*residual_);
298 }
299
304 {
305 using namespace Dune::Hybrid;
306 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](const auto i)
307 {
308 forEach(jac[i], [&](auto& jacBlock)
309 {
310 using BlockType = std::decay_t<decltype(jacBlock)>;
311 if (jacBlock.buildMode() == BlockType::BuildMode::unknown)
312 jacBlock.setBuildMode(BlockType::BuildMode::random);
313 else if (jacBlock.buildMode() != BlockType::BuildMode::random)
314 DUNE_THROW(Dune::NotImplemented, "Only BCRS matrices with random build mode are supported at the moment");
315 });
316 });
317 }
318
323 {
324 setJacobianPattern_(*jacobian_);
325 setResidualSize_(*residual_);
326 maybeComputeColors_();
327 }
328
333 {
334 using namespace Dune::Hybrid;
335 forEach(integralRange(Dune::Hybrid::size(gridVariablesTuple_)), [&](const auto domainId)
336 { this->gridVariables(domainId).update(curSol[domainId]); });
337 }
338
342 void resetTimeStep(const SolutionVector& curSol)
343 {
344 using namespace Dune::Hybrid;
345 forEach(integralRange(Dune::Hybrid::size(gridVariablesTuple_)), [&](const auto domainId)
346 { this->gridVariables(domainId).resetTimeStep(curSol[domainId]); });
347 }
348
350 template<std::size_t i>
351 std::size_t numDofs(Dune::index_constant<i> domainId) const
352 { return std::get<domainId>(gridDiscretizationTuple_)->numDofs(); }
353
355 template<std::size_t i>
356 const auto& problem(Dune::index_constant<i> domainId) const
357 { return *std::get<domainId>(problemTuple_); }
358
360 template<std::size_t i>
361 const auto& gridDiscretization(Dune::index_constant<i> domainId) const
362 { return *std::get<domainId>(gridDiscretizationTuple_); }
363
365 template<std::size_t i>
366 const auto& gridView(Dune::index_constant<i> domainId) const
367 { return gridDiscretization(domainId).gridView(); }
368
370 template<std::size_t i>
371 GridVariables<i>& gridVariables(Dune::index_constant<i> domainId)
372 { return *std::get<domainId>(gridVariablesTuple_); }
373
375 template<std::size_t i>
376 const GridVariables<i>& gridVariables(Dune::index_constant<i> domainId) const
377 { return *std::get<domainId>(gridVariablesTuple_); }
378
381 { return *couplingManager_; }
382
385 { return *jacobian_; }
386
389 { return *residual_; }
390
392 const SolutionVector& prevSol() const
393 { return *prevSol_; }
394
399 void setTimeManager(std::shared_ptr<const TimeLoop> timeLoop)
400 { timeLoop_ = timeLoop; isStationaryProblem_ = !(static_cast<bool>(timeLoop)); }
401
407 { prevSol_ = &u; }
408
413 { return isStationaryProblem_; }
414
418 template<std::size_t i>
419 LocalResidual<i> localResidual(Dune::index_constant<i> domainId) const
420 { return LocalResidual<i>(std::get<domainId>(problemTuple_).get(), timeLoop_.get()); }
421
422protected:
424 std::shared_ptr<CouplingManager> couplingManager_;
425
426private:
430 void setJacobianPattern_(JacobianMatrix& jac) const
431 {
432 using namespace Dune::Hybrid;
433 forEach(std::make_index_sequence<JacobianMatrix::N()>(), [&](const auto domainI)
434 {
435 forEach(integralRange(Dune::Hybrid::size(jac[domainI])), [&](const auto domainJ)
436 {
437 const auto pattern = this->getJacobianPattern_(domainI, domainJ);
438 pattern.exportIdx(jac[domainI][domainJ]);
439 });
440 });
441 }
442
446 void setResidualSize_(ResidualType& res) const
447 {
448 using namespace Dune::Hybrid;
449 forEach(integralRange(Dune::Hybrid::size(res)), [&](const auto domainId)
450 { res[domainId].resize(this->numDofs(domainId)); });
451 }
452
453 // reset the residual vector to 0.0
454 void resetResidual_()
455 {
456 if(!residual_)
457 {
458 residual_ = std::make_shared<ResidualType>();
459 setResidualSize_(*residual_);
460 }
461
462 (*residual_) = 0.0;
463 }
464
465 // reset the jacobian vector to 0.0
466 void resetJacobian_()
467 {
468 if(!jacobian_)
469 {
470 jacobian_ = std::make_shared<JacobianMatrix>();
471 setJacobianBuildMode(*jacobian_);
472 setJacobianPattern_(*jacobian_);
473 }
474
475 (*jacobian_) = 0.0;
476 }
477
479 void maybeComputeColors_()
480 {
481 if constexpr (CouplingManagerSupportsMultithreadedAssembly<CouplingManager>::value)
482 if (enableMultithreading_)
483 couplingManager_->computeColorsForAssembly();
484 }
485
486 // check if the assembler is in a correct state for assembly
487 void checkAssemblerState_() const
488 {
489 if (!isStationaryProblem_ && !prevSol_)
490 DUNE_THROW(Dune::InvalidStateException, "Assembling instationary problem but previous solution was not set!");
491
492 if (isStationaryProblem_ && prevSol_)
493 DUNE_THROW(Dune::InvalidStateException, "Assembling stationary problem but a previous solution was set."
494 << " Did you forget to set the timeLoop to make this problem instationary?");
495 }
496
497 template<std::size_t i, class JacRow, class SubRes>
498 void assembleJacobianAndResidual_(Dune::index_constant<i> domainId, JacRow& jacRow, SubRes& subRes,
499 const SolutionVector& curSol)
500 {
501 assemble_(domainId, [&](const auto& element)
502 {
503 MultiDomainAssemblerSubDomainView view{*this, domainId};
504 SubDomainAssembler<i> subDomainAssembler(view, element, curSol, *couplingManager_);
505 subDomainAssembler.assembleJacobianAndResidual(jacRow, subRes, gridVariablesTuple_);
506 });
507 }
508
509 template<std::size_t i, class SubRes>
510 void assembleResidual_(Dune::index_constant<i> domainId, SubRes& subRes,
511 const SolutionVector& curSol)
512 {
513 assemble_(domainId, [&](const auto& element)
514 {
515 MultiDomainAssemblerSubDomainView view{*this, domainId};
516 SubDomainAssembler<i> subDomainAssembler(view, element, curSol, *couplingManager_);
517 subDomainAssembler.assembleResidual(subRes);
518 });
519 }
520
526 template<std::size_t i, class AssembleElementFunc>
527 void assemble_(Dune::index_constant<i> domainId, AssembleElementFunc&& assembleElement) const
528 {
529 // a state that will be checked on all processes
530 bool succeeded = false;
531
532 // try assembling using the local assembly function
533 try
534 {
535 if constexpr (CouplingManagerSupportsMultithreadedAssembly<CouplingManager>::value)
536 {
537 if (enableMultithreading_)
538 {
539 couplingManager_->assembleMultithreaded(
540 domainId, std::forward<AssembleElementFunc>(assembleElement)
541 );
542 return;
543 }
544 }
545
546 // fallback for coupling managers that don't support multithreaded assembly (yet)
547 // or if multithreaded assembly is disabled
548 // let the local assembler add the element contributions
549 for (const auto& element : elements(gridView(domainId)))
550 assembleElement(element);
551
552 // if we get here, everything worked well on this process
553 succeeded = true;
554 }
555 // throw exception if a problem occurred
556 catch (NumericalProblem &e)
557 {
558 std::cout << "rank " << gridView(domainId).comm().rank()
559 << " caught an exception while assembling:" << e.what()
560 << "\n";
561 succeeded = false;
562 }
563
564 // make sure everything worked well on all processes
565 if (gridView(domainId).comm().size() > 1)
566 succeeded = gridView(domainId).comm().min(succeeded);
567
568 // if not succeeded rethrow the error on all processes
569 if (!succeeded)
570 DUNE_THROW(NumericalProblem, "A process did not succeed in linearizing the system");
571 }
572
573 // get diagonal block pattern
574 template<std::size_t i, std::size_t j, typename std::enable_if_t<(i==j), int> = 0>
575 Dune::MatrixIndexSet getJacobianPattern_(Dune::index_constant<i> domainI,
576 Dune::index_constant<j> domainJ) const
577 {
578 const auto& gg = gridDiscretization(domainI);
579 auto pattern = getJacobianPattern<isImplicit()>(gg);
580 couplingManager_->extendJacobianPattern(domainI, pattern);
581 return pattern;
582 }
583
584 // get coupling block pattern
585 template<std::size_t i, std::size_t j, typename std::enable_if_t<(i!=j), int> = 0>
586 Dune::MatrixIndexSet getJacobianPattern_(Dune::index_constant<i> domainI,
587 Dune::index_constant<j> domainJ) const
588 {
590 domainI, gridDiscretization(domainI),
591 domainJ, gridDiscretization(domainJ));
592 }
593
594 // build periodic constraints into the system matrix
595 template<std::size_t i, class JacRow, class Res, class GG, class Sol>
596 void enforcePeriodicConstraints_(Dune::index_constant<i> domainI, JacRow& jacRow, Res& res, const GG& gridDiscretization, const Sol& curSol) const
597 {
599 {
600 for (const auto& m : gridDiscretization.periodicDofMap())
601 {
602 const auto& periodicallyMappedDofs = Dumux::Deprecated::ensureRangeOfPeriodicDofs(m.second);
603 if (std::ranges::all_of(periodicallyMappedDofs, [&](auto second){ return m.first < second; }))
604 {
605 for (const auto& second : periodicallyMappedDofs)
606 {
607 auto& jac = jacRow[domainI];
608
609 // add the second row to the first
610 res[m.first] += res[second];
611
612 const auto end = jac[second].end();
613 for (auto it = jac[second].begin(); it != end; ++it)
614 jac[m.first][it.index()] += (*it);
615
616
617 // enforce the solution of the first periodic DOF to the second one
618 res[second] = curSol[second] - curSol[m.first];
619
620 // set derivatives accordingly in jacobian, i.e. id for second and -id for m.first
621 auto setMatrixBlock = [] (auto& matrixBlock, double diagValue)
622 {
623 for (int eIdx = 0; eIdx < matrixBlock.N(); ++eIdx)
624 matrixBlock[eIdx][eIdx] = diagValue;
625 };
626
627 for (auto it = jac[second].begin(); it != end; ++it)
628 {
629 auto& matrixBlock = *it;
630 matrixBlock = 0.0;
631
632 assert(matrixBlock.N() == matrixBlock.M());
633 if(it.index() == second)
634 setMatrixBlock(matrixBlock, 1.0);
635
636 if(it.index() == m.first)
637 setMatrixBlock(matrixBlock, -1.0);
638
639 }
640
641 using namespace Dune::Hybrid;
642 forEach(makeIncompleteIntegerSequence<JacRow::size(), domainI>(), [&](const auto couplingDomainId)
643 {
644 auto& jacCoupling = jacRow[couplingDomainId];
645
646 for (auto it = jacCoupling[second].begin(); it != jacCoupling[second].end(); ++it)
647 jacCoupling[m.first][it.index()] += (*it);
648
649 for (auto it = jacCoupling[second].begin(); it != jacCoupling[second].end(); ++it)
650 (*it) = 0.0;
651 });
652 }
653 }
654 }
655 }
656 }
657
658 // enforce global constraints into the system matrix
659 template<std::size_t i, class JacRow, class Res, class GG, class Sol>
660 void enforceProblemConstraints_(Dune::index_constant<i> domainI, JacRow& jacRow, Res& res, const GG& gridDiscretization, const Sol& curSol) const
661 {
663 {
664 auto& jac = jacRow[domainI];
665 auto applyDirichletConstraint = [&] (const auto& dofIdx,
666 const auto& values,
667 const auto eqIdx,
668 const auto pvIdx)
669 {
670 (res)[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
671
672 auto& row = jac[dofIdx];
673 for (auto col = row.begin(); col != row.end(); ++col)
674 row[col.index()][eqIdx] = 0.0;
675
676 jac[dofIdx][dofIdx][eqIdx][pvIdx] = 1.0;
677
678 using namespace Dune::Hybrid;
679 forEach(makeIncompleteIntegerSequence<JacRow::size(), domainI>(), [&](const auto couplingDomainId)
680 {
681 auto& jacCoupling = jacRow[couplingDomainId];
682
683 auto& rowCoupling = jacCoupling[dofIdx];
684 for (auto colCoupling = rowCoupling.begin(); colCoupling != rowCoupling.end(); ++colCoupling)
685 rowCoupling[colCoupling.index()][eqIdx] = 0.0;
686 });
687
688 };
689
690 for (const auto& constraintData : this->problem(domainI).constraints())
691 {
692 const auto& constraintInfo = constraintData.constraintInfo();
693 const auto& values = constraintData.values();
694 const auto dofIdx = constraintData.dofIndex();
695 // set the constraint in residual and jacobian
696 for (int eqIdx = 0; eqIdx < constraintInfo.size(); ++eqIdx)
697 {
698 if (constraintInfo.isConstraintEquation(eqIdx))
699 {
700 const auto pvIdx = constraintInfo.eqToPriVarIndex(eqIdx);
701 assert(0 <= pvIdx && pvIdx < constraintInfo.size());
702 applyDirichletConstraint(dofIdx, values, eqIdx, pvIdx);
703 }
704 }
705 }
706 }
707 }
708
709 // build periodic constraints in residual only
710 template<std::size_t i, class Res, class GG, class Sol>
711 void enforcePeriodicConstraints_(Dune::index_constant<i> domainI, Res& res, const GG& gridDiscretization, const Sol& curSol) const
712 {
714 {
715 for (const auto& m : gridDiscretization.periodicDofMap())
716 {
717 const auto& periodicallyMappedDofs = Dumux::Deprecated::ensureRangeOfPeriodicDofs(m.second);
718 if (std::ranges::all_of(periodicallyMappedDofs, [&](auto second){ return m.first < second; }))
719 {
720 for (const auto& second : periodicallyMappedDofs)
721 {
722 // add the second row to the first
723 res[m.first] += res[second];
724
725 // enforce the solution of the first periodic DOF to the second one
726 res[second] = curSol[second] - curSol[m.first];
727 }
728 }
729 }
730 }
731 }
732
733 // enforce global constraints in residual only
734 template<std::size_t i, class Res, class GG, class Sol>
735 void enforceProblemConstraints_(Dune::index_constant<i> domainI, Res& res, const GG& gridDiscretization, const Sol& curSol) const
736 {
738 {
739 for (const auto& constraintData : this->problem(domainI).constraints())
740 {
741 const auto& constraintInfo = constraintData.constraintInfo();
742 const auto& values = constraintData.values();
743 const auto dofIdx = constraintData.dofIndex();
744 for (int eqIdx = 0; eqIdx < constraintInfo.size(); ++eqIdx)
745 {
746 if (constraintInfo.isConstraintEquation(eqIdx))
747 {
748 const auto pvIdx = constraintInfo.eqToPriVarIndex(eqIdx);
749 assert(0 <= pvIdx && pvIdx < constraintInfo.size());
750 res[dofIdx][eqIdx] = curSol[dofIdx][pvIdx] - values[pvIdx];
751 }
752 }
753 }
754 }
755 }
756
758 ProblemTuple problemTuple_;
759
761 GridDiscretizationTuple gridDiscretizationTuple_;
762
764 GridVariablesTuple gridVariablesTuple_;
765
767 std::shared_ptr<const TimeLoop> timeLoop_;
768
770 const SolutionVector* prevSol_ = nullptr;
771
773 bool isStationaryProblem_;
774
776 std::shared_ptr<JacobianMatrix> jacobian_;
777 std::shared_ptr<ResidualType> residual_;
778
780 mutable bool warningIssued_;
781
783 bool enableMultithreading_ = false;
784};
785
786} // end namespace Dumux::Experimental
787
788#endif
Subdomain-specific views on multidomain assemblers.
Traits shared by the multi-domain assemblers.
The interface of the coupling manager for multi domain problems.
Definition multidomain/couplingmanager.hh:37
A linear system assembler (residual and Jacobian) for general schemes (FV, CVFE, FE,...
Definition multidomain/assembler.hh:66
typename MDTraits::ResidualVector ResidualType
Definition multidomain/assembler.hh:89
bool isStationaryProblem() const
Whether we are assembling a stationary or instationary problem.
Definition multidomain/assembler.hh:412
typename MDTraits::template SubDomain< id >::GridVariables GridVariables
Definition multidomain/assembler.hh:79
void setJacobianBuildMode(JacobianMatrix &jac) const
Sets the jacobian build mode.
Definition multidomain/assembler.hh:303
LocalResidual< i > localResidual(Dune::index_constant< i > domainId) const
Create a local residual object (used by the local assembler).
Definition multidomain/assembler.hh:419
GetPropType< SubDomainTypeTag< id >, Properties::GridGeometry > GridDiscretization
Definition multidomain/assembler.hh:82
void updateGridVariables(const SolutionVector &curSol)
Updates the grid variables with the given solution.
Definition multidomain/assembler.hh:332
ResidualType & residual()
the full residual vector
Definition multidomain/assembler.hh:388
void updateAfterGridAdaption()
Resizes jacobian and residual and recomputes colors.
Definition multidomain/assembler.hh:322
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/assembler.hh:275
const GridVariables< i > & gridVariables(Dune::index_constant< i > domainId) const
the grid variables of domain i
Definition multidomain/assembler.hh:376
std::size_t numDofs(Dune::index_constant< i > domainId) const
the number of dof locations of domain i
Definition multidomain/assembler.hh:351
void setTimeManager(std::shared_ptr< const TimeLoop > timeLoop)
Set time loop for instationary problems.
Definition multidomain/assembler.hh:399
const auto & gridView(Dune::index_constant< i > domainId) const
the grid view of domain i
Definition multidomain/assembler.hh:366
void assembleResidual(ResidualType &r, const SolutionVector &curSol)
assemble a residual r
Definition multidomain/assembler.hh:248
typename MDTraits::SolutionVector SolutionVector
Definition multidomain/assembler.hh:88
std::shared_ptr< CouplingManager > couplingManager_
Definition multidomain/assembler.hh:424
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/assembler.hh:406
JacobianMatrix & jacobian()
the full Jacobian matrix
Definition multidomain/assembler.hh:384
typename MDTraits::Scalar Scalar
Definition multidomain/assembler.hh:73
const auto & gridDiscretization(Dune::index_constant< i > domainId) const
Definition multidomain/assembler.hh:361
MDTraits Traits
Definition multidomain/assembler.hh:71
typename MDTraits::JacobianMatrix JacobianMatrix
Definition multidomain/assembler.hh:87
void setLinearSystem()
The version without arguments uses the default constructor to create the jacobian and residual object...
Definition multidomain/assembler.hh:290
GridVariables< i > & gridVariables(Dune::index_constant< i > domainId)
Definition multidomain/assembler.hh:371
static constexpr bool isImplicit()
Returns true if the assembler considers implicit assembly.
Definition multidomain/assembler.hh:96
const SolutionVector & prevSol() const
Definition multidomain/assembler.hh:392
typename MDTraits::template SubDomain< id >::LocalResidual LocalResidual
Definition multidomain/assembler.hh:76
MultiDomainAssembler(ProblemTuple problem, GridDiscretizationTuple gridDiscretization, GridVariablesTuple gridVariables, std::shared_ptr< CouplingManager > couplingManager)
The constructor for stationary problems.
Definition multidomain/assembler.hh:163
CMType CouplingManager
Definition multidomain/assembler.hh:91
void resetTimeStep(const SolutionVector &curSol)
Resets the grid variables to the last time step.
Definition multidomain/assembler.hh:342
const auto & problem(Dune::index_constant< i > domainId) const
Definition multidomain/assembler.hh:356
const CouplingManager & couplingManager() const
Definition multidomain/assembler.hh:380
void assembleResidual(const SolutionVector &curSol)
compute the residuals using the internal residual
Definition multidomain/assembler.hh:241
typename MDTraits::template SubDomain< id >::Problem Problem
Definition multidomain/assembler.hh:85
MultiDomainAssembler(ProblemTuple problem, GridDiscretizationTuple gridDiscretization, GridVariablesTuple gridVariables, std::shared_ptr< CouplingManager > couplingManager, std::shared_ptr< const TimeLoop > timeLoop, const SolutionVector &prevSol)
The constructor for instationary problems.
Definition multidomain/assembler.hh:191
void assembleJacobianAndResidual(const SolutionVector &curSol)
Assembles the global Jacobian of the residual and the residual for the current solution.
Definition multidomain/assembler.hh:220
The cell-centered scheme multidomain local assembler.
Definition experimental/assembly/subdomaincclocalassembler.hh:195
The CVFE scheme multidomain local assembler.
Definition experimental/assembly/subdomaincvfelocalassembler.hh:207
Subdomain-specific view on a multidomain assembler. Allows retrieval of sub-domain specific objects w...
Definition assemblerview.hh:33
The cell-centered scheme multidomain local assembler.
Definition multidomain/subdomaincclocalassembler.hh:270
The CVFE scheme multidomain local assembler.
Definition multidomain/subdomaincvfelocalassembler.hh:244
Manages the handling of time dependent problems.
Definition common/timeloop.hh:84
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.
Helpers for deprecation.
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
Dune::MatrixIndexSet getJacobianPattern(const GridGeometry &gridGeometry)
Helper function to generate Jacobian pattern for cell-centered methods.
Definition jacobianpattern.hh:29
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:33
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:155
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 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.
Definition cellcentered/mpfa/elementvolumevariables.hh:24
constexpr bool hasPeriodicDofMap()
Definition periodic.hh:24
constexpr bool hasSubProblemGlobalConstraints()
Definition assemblytraits.hh:30
Definition method.hh:20
Definition assembly/assembler.hh:46
bool allGridsSupportsMultithreading(const std::tuple< GridDiscretizations... > &gridDiscretizations)
Whether the grid views of all grid discretizations support multithreading.
Definition gridcapabilities.hh:44
const Scalar PengRobinsonMixture< Scalar, StaticParameters >::u
Definition pengrobinsonmixture.hh:138
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:58
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 assemblytraits.hh:43
An assembler for Jacobian and residual contribution per element (face-centered staggered methods) for...
Utilities for template meta programming.