From 8233791200e9174375986767176a3a6679ab42ed Mon Sep 17 00:00:00 2001 From: Kilian Weishaupt <kilian.weishaupt@iws.uni-stuttgart.de> Date: Tue, 7 Sep 2021 12:02:41 +0200 Subject: [PATCH] [md] Add periodic constraints to multidomain fvassembler --- dumux/multidomain/fvassembler.hh | 45 ++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/dumux/multidomain/fvassembler.hh b/dumux/multidomain/fvassembler.hh index 8039452e79..8f88cc3d37 100644 --- a/dumux/multidomain/fvassembler.hh +++ b/dumux/multidomain/fvassembler.hh @@ -203,6 +203,9 @@ public: auto& jacRow = (*jacobian_)[domainId]; auto& subRes = (*residual_)[domainId]; this->assembleJacobianAndResidual_(domainId, jacRow, subRes, curSol); + + const auto gridGeometry = std::get<domainId>(gridGeometryTuple_); + enforcePeriodicConstraints_(domainId, jacRow, subRes, *gridGeometry, curSol[domainId]); }); } @@ -551,6 +554,48 @@ private: domainJ, gridGeometry(domainJ)); } + // build periodic contraints into the system matrix + template<std::size_t i, class JacRow, class Sol, class GG> + void enforcePeriodicConstraints_(Dune::index_constant<i> domainI, JacRow& jacRow, Sol& res, const GG& gridGeometry, const Sol& curSol) + { + if constexpr (GG::discMethod == DiscretizationMethod::box || GG::discMethod == DiscretizationMethod::fcstaggered) + { + for (const auto& m : gridGeometry.periodicVertexMap()) + { + if (m.first < m.second) + { + auto& jac = jacRow[domainI]; + + // add the second row to the first + res[m.first] += res[m.second]; + + // enforce the solution of the first periodic DOF to the second one + res[m.second] = curSol[m.second] - curSol[m.first]; + + const auto end = jac[m.second].end(); + for (auto it = jac[m.second].begin(); it != end; ++it) + jac[m.first][it.index()] += (*it); + + // enforce constraint in second row + for (auto it = jac[m.second].begin(); it != end; ++it) + (*it) = it.index() == m.second ? 1.0 : it.index() == m.first ? -1.0 : 0.0; + + using namespace Dune::Hybrid; + forEach(makeIncompleteIntegerSequence<JacRow::size(), domainI>(), [&](const auto couplingDomainId) + { + auto& jacCoupling = jacRow[couplingDomainId]; + + for (auto it = jacCoupling[m.second].begin(); it != jacCoupling[m.second].end(); ++it) + jacCoupling[m.first][it.index()] += (*it); + + for (auto it = jacCoupling[m.second].begin(); it != jacCoupling[m.second].end(); ++it) + (*it) = 0.0; + }); + } + } + } + } + //! pointer to the problem to be solved ProblemTuple problemTuple_; -- GitLab