96 static_assert(numSD == 2,
"More than two subdomains not implemented!");
97 static_assert(isFcStaggered<0>() && isCCTpfa<1>(),
"Only coupling between fcstaggered and cctpfa implemented!");
100 std::cout <<
"Initializing the coupling map..." << std::endl;
102 for (std::size_t domIdx = 0; domIdx < numSD; ++domIdx)
103 stencils_[domIdx].clear();
105 std::get<CouplingManager::freeFlowMomentumIndex>(scvfInfo_).clear();
106 std::get<CouplingManager::porousMediumIndex>(scvfInfo_).clear();
108 const auto& freeFlowMomentumProblem = couplingManager.
problem(CouplingManager::freeFlowMomentumIndex);
109 const auto& porousMediumProblem = couplingManager.
problem(CouplingManager::porousMediumIndex);
110 const auto& freeFlowMomentumGG = freeFlowMomentumProblem.gridGeometry();
111 const auto& porousMediumGG = porousMediumProblem.gridGeometry();
113 isCoupledFFDof_.resize(freeFlowMomentumGG.numScvf(),
false);
114 isCoupledFFElement_.resize(freeFlowMomentumGG.gridView().size(0),
false);
115 isCoupledScvf_[CouplingManager::freeFlowMomentumIndex].resize(freeFlowMomentumGG.numScvf(),
false);
116 isCoupledScvf_[CouplingManager::porousMediumIndex].resize(porousMediumGG.numScvf(),
false);
118 auto pmFvGeometry =
localView(porousMediumGG);
119 auto ffFvGeometry =
localView(freeFlowMomentumGG);
121 for (
const auto& pmElement : elements(porousMediumGG.gridView()))
123 pmFvGeometry.bindElement(pmElement);
125 for (
const auto& pmScvf : scvfs(pmFvGeometry))
128 if (!pmScvf.boundary())
133 const auto eps = (pmScvf.ipGlobal() - pmScvf.geometry().corner(0)).two_norm()*1e-8;
134 auto globalPos = pmScvf.ipGlobal(); globalPos.axpy(eps, pmScvf.unitOuterNormal());
142 if (indices.size() > 1)
143 DUNE_THROW(Dune::InvalidStateException,
"Are you sure your sub-domain grids are conformingly discretized on the common interface?");
146 const auto pmElemIdx = porousMediumGG.elementMapper().index(pmElement);
147 const auto ffElemIdx = indices[0];
148 const auto& ffElement = freeFlowMomentumGG.element(ffElemIdx);
149 ffFvGeometry.bindElement(ffElement);
151 for (
const auto& ffScvf : scvfs(ffFvGeometry))
154 if (!ffScvf.boundary() || !ffScvf.isFrontal())
157 const auto dist = (pmScvf.ipGlobal() - ffScvf.ipGlobal()).two_norm();
161 const auto& ffScv = ffFvGeometry.scv(ffScvf.insideScvIdx());
162 stencils_[CouplingManager::porousMediumIndex][pmElemIdx].push_back(ffScv.dofIndex());
163 stencils_[CouplingManager::freeFlowMomentumIndex][ffScv.dofIndex()].push_back(pmElemIdx);
166 isCoupledScvf_[CouplingManager::porousMediumIndex][pmScvf.index()] =
true;
167 isCoupledScvf_[CouplingManager::freeFlowMomentumIndex][ffScvf.index()] =
true;
170 for (
const auto& otherFfScvf : scvfs(ffFvGeometry, ffScv))
172 if (otherFfScvf.isLateral())
175 const auto& lateralOrthogonalScvf = ffFvGeometry.lateralOrthogonalScvf(otherFfScvf);
176 isCoupledLateralScvf_[lateralOrthogonalScvf.index()] =
true;
179 if (!otherFfScvf.boundary())
180 isCoupledLateralScvf_[otherFfScvf.index()] =
true;
184 const auto otherScvfEps = (otherFfScvf.ipGlobal() - otherFfScvf.geometry().corner(0)).two_norm()*1e-8;
185 auto otherScvfGlobalPos = otherFfScvf.center(); otherScvfGlobalPos.axpy(otherScvfEps, otherFfScvf.unitOuterNormal());
188 isCoupledLateralScvf_[otherFfScvf.index()] =
true;
192 isCoupledFFDof_[ffScv.dofIndex()] =
true;
193 isCoupledFFElement_[ffElemIdx] =
true;
195 std::get<CouplingManager::porousMediumIndex>(scvfInfo_)[pmScvf.index()] = ScvfInfoPM{ffElemIdx, ffScvf.index()};
196 std::get<CouplingManager::freeFlowMomentumIndex>(scvfInfo_)[ffScvf.index()] = ScvfInfoFF{pmElemIdx, pmScvf.index(), ffScv.dofIndex()};
201 std::cout <<
"took " << watch.elapsed() <<
" seconds." << std::endl;