83 static_assert(numSD == 2,
"More than two subdomains not implemented!");
84 static_assert(isFcStaggered<0>() && isCCTpfa<1>(),
"Only coupling between fcstaggered and cctpfa implemented!");
87 std::cout <<
"Initializing the coupling map..." << std::endl;
89 for (std::size_t domIdx = 0; domIdx < numSD; ++domIdx)
90 stencils_[domIdx].clear();
92 std::get<CouplingManager::freeFlowMomentumIndex>(scvfInfo_).clear();
93 std::get<CouplingManager::porousMediumIndex>(scvfInfo_).clear();
95 const auto& freeFlowMomentumProblem = couplingManager.
problem(CouplingManager::freeFlowMomentumIndex);
96 const auto& porousMediumProblem = couplingManager.
problem(CouplingManager::porousMediumIndex);
97 const auto& freeFlowMomentumGG = freeFlowMomentumProblem.gridGeometry();
98 const auto& porousMediumGG = porousMediumProblem.gridGeometry();
100 isCoupledFFDof_.resize(freeFlowMomentumGG.numScvf(),
false);
101 isCoupledFFElement_.resize(freeFlowMomentumGG.gridView().size(0),
false);
102 isCoupledScvf_[CouplingManager::freeFlowMomentumIndex].resize(freeFlowMomentumGG.numScvf(),
false);
103 isCoupledScvf_[CouplingManager::porousMediumIndex].resize(porousMediumGG.numScvf(),
false);
105 auto pmFvGeometry =
localView(porousMediumGG);
106 auto ffFvGeometry =
localView(freeFlowMomentumGG);
108 for (
const auto& pmElement : elements(porousMediumGG.gridView()))
110 pmFvGeometry.bindElement(pmElement);
112 for (
const auto& pmScvf : scvfs(pmFvGeometry))
115 if (!pmScvf.boundary())
120 const auto eps = (pmScvf.ipGlobal() - pmFvGeometry.geometry(pmScvf).corner(0)).two_norm()*1e-8;
121 auto globalPos = pmScvf.ipGlobal(); globalPos.axpy(eps, pmScvf.unitOuterNormal());
129 if (indices.size() > 1)
130 DUNE_THROW(Dune::InvalidStateException,
"Are you sure your sub-domain grids are conformingly discretized on the common interface?");
133 const auto pmElemIdx = porousMediumGG.elementMapper().index(pmElement);
134 const auto ffElemIdx = indices[0];
135 const auto& ffElement = freeFlowMomentumGG.element(ffElemIdx);
136 ffFvGeometry.bindElement(ffElement);
138 for (
const auto& ffScvf : scvfs(ffFvGeometry))
141 if (!ffScvf.boundary() || !ffScvf.isFrontal())
144 const auto dist = (pmScvf.ipGlobal() - ffScvf.ipGlobal()).two_norm();
148 const auto& ffScv = ffFvGeometry.scv(ffScvf.insideScvIdx());
149 stencils_[CouplingManager::porousMediumIndex][pmElemIdx].push_back(ffScv.dofIndex());
150 stencils_[CouplingManager::freeFlowMomentumIndex][ffScv.dofIndex()].push_back(pmElemIdx);
153 isCoupledScvf_[CouplingManager::porousMediumIndex][pmScvf.index()] =
true;
154 isCoupledScvf_[CouplingManager::freeFlowMomentumIndex][ffScvf.index()] =
true;
157 for (
const auto& otherFfScvf : scvfs(ffFvGeometry, ffScv))
159 if (otherFfScvf.isLateral())
162 const auto& lateralOrthogonalScvf = ffFvGeometry.lateralOrthogonalScvf(otherFfScvf);
163 isCoupledLateralScvf_[lateralOrthogonalScvf.index()] =
true;
166 if (!otherFfScvf.boundary())
167 isCoupledLateralScvf_[otherFfScvf.index()] =
true;
171 const auto otherScvfEps = (otherFfScvf.ipGlobal() - ffFvGeometry.geometry(otherFfScvf).corner(0)).two_norm()*1e-8;
172 auto otherScvfGlobalPos = otherFfScvf.center(); otherScvfGlobalPos.axpy(otherScvfEps, otherFfScvf.unitOuterNormal());
175 isCoupledLateralScvf_[otherFfScvf.index()] =
true;
179 isCoupledFFDof_[ffScv.dofIndex()] =
true;
180 isCoupledFFElement_[ffElemIdx] =
true;
182 std::get<CouplingManager::porousMediumIndex>(scvfInfo_)[pmScvf.index()] = ScvfInfoPM{ffElemIdx, ffScvf.index()};
183 std::get<CouplingManager::freeFlowMomentumIndex>(scvfInfo_)[ffScvf.index()] = ScvfInfoFF{pmElemIdx, pmScvf.index(), ffScv.dofIndex()};
188 std::cout <<
"took " << watch.elapsed() <<
" seconds." << std::endl;