133 const auto& bulkGridGeometry = this->
problem(bulkIdx).gridGeometry();
134 const auto& lowDimGridGeometry = this->
problem(lowDimIdx).gridGeometry();
135 const auto& bulkTree = bulkGridGeometry.boundingBoxTree();
140 std::cout <<
"Initializing the point sources..." << std::endl;
145 extendedSourceStencil_.clear();
155 const auto& lowDimProblem = this->
problem(lowDimIdx);
156 for (
const auto& is : intersections(this->
glue()))
159 const auto& lowDimElement = is.targetEntity(0);
160 const auto lowDimElementIdx = lowDimGridGeometry.elementMapper().index(lowDimElement);
163 const auto intersectionGeometry = is.geometry();
165 const auto& quad = Dune::QuadratureRules<Scalar, lowDimDim>::rule(intersectionGeometry.type(), order);
174 for (
auto&& qp : quad)
177 const auto globalPos = intersectionGeometry.global(qp.position());
183 if (bulkElementIndices.empty())
190 static const auto numIp =
getParam<int>(
"MixedDimension.NumCircleSegments");
191 const auto radius = lowDimProblem.spatialParams().radius(lowDimElementIdx);
192 const auto normal = intersectionGeometry.corner(1)-intersectionGeometry.corner(0);
193 const auto circleAvgWeight = 2*M_PI*
radius/numIp;
194 const auto integrationElement = intersectionGeometry.integrationElement(qp.position());
195 const auto qpweight = qp.weight();
198 std::vector<Scalar> circleIpWeight; circleIpWeight.reserve(circlePoints.size());
199 std::vector<GridIndex<bulkIdx>> circleStencil; circleStencil.reserve(circlePoints.size());
202 std::vector<const std::vector<GridIndex<bulkIdx>>*> circleCornerIndices;
203 using ShapeValues = std::vector<Dune::FieldVector<Scalar, 1> >;
204 std::vector<ShapeValues> circleShapeValues;
207 int insideCirclePoints = 0;
208 for (
int k = 0; k < circlePoints.size(); ++k)
211 if (circleBulkElementIndices.empty())
214 ++insideCirclePoints;
215 const auto localCircleAvgWeight = circleAvgWeight / circleBulkElementIndices.size();
216 for (
const auto bulkElementIdx : circleBulkElementIndices)
218 circleStencil.push_back(bulkElementIdx);
219 circleIpWeight.push_back(localCircleAvgWeight);
222 if constexpr (isBox<bulkIdx>())
224 const auto bulkElement = bulkGridGeometry.element(bulkElementIdx);
225 circleCornerIndices.push_back(&(this->
vertexIndices(bulkIdx, bulkElementIdx)));
228 const auto bulkGeometry = bulkElement.geometry();
229 ShapeValues shapeValues;
230 this->
getShapeValues(bulkIdx, bulkGridGeometry, bulkGeometry, circlePoints[k], shapeValues);
231 circleShapeValues.emplace_back(std::move(shapeValues));
238 if (circleStencil.empty())
242 if constexpr (isBox<bulkIdx>())
245 for (
const auto& vertices : circleCornerIndices)
248 vertices->begin(), vertices->end());
255 circleStencil.begin(), circleStencil.end());
259 const auto surfaceFraction = Scalar(insideCirclePoints)/Scalar(circlePoints.size());
262 for (
auto bulkElementIdx : bulkElementIndices)
266 this->
pointSources(bulkIdx).emplace_back(globalPos,
id, qpweight, integrationElement*surfaceFraction, bulkElementIdx);
267 this->
pointSources(bulkIdx).back().setEmbeddings(bulkElementIndices.size());
268 this->
pointSources(lowDimIdx).emplace_back(globalPos,
id, qpweight, integrationElement*surfaceFraction, lowDimElementIdx);
269 this->
pointSources(lowDimIdx).back().setEmbeddings(bulkElementIndices.size());
273 PointSourceData psData;
275 if constexpr (isBox<lowDimIdx>())
277 ShapeValues shapeValues;
278 this->
getShapeValues(lowDimIdx, lowDimGridGeometry, lowDimElement.geometry(), globalPos, shapeValues);
279 psData.addLowDimInterpolation(shapeValues, this->
vertexIndices(lowDimIdx, lowDimElementIdx), lowDimElementIdx);
283 psData.addLowDimInterpolation(lowDimElementIdx);
287 if constexpr (isBox<bulkIdx>())
289 psData.addCircleInterpolation(circleCornerIndices, circleShapeValues, circleIpWeight, circleStencil);
291 const auto bulkGeometry = bulkGridGeometry.element(bulkElementIdx).geometry();
292 ShapeValues shapeValues;
293 this->
getShapeValues(bulkIdx, bulkGridGeometry, bulkGeometry, globalPos, shapeValues);
294 psData.addBulkInterpolation(shapeValues, this->
vertexIndices(bulkIdx, bulkElementIdx), bulkElementIdx);
298 psData.addCircleInterpolation(circleIpWeight, circleStencil);
299 psData.addBulkInterpolation(bulkElementIdx);
306 const auto outsideGeometry = bulkGridGeometry.element(bulkElementIdx).geometry();
310 if constexpr (isBox<lowDimIdx>())
319 this->
couplingStencils(bulkIdx)[bulkElementIdx].push_back(lowDimElementIdx);
323 if constexpr (isBox<bulkIdx>())
326 for (
const auto& vertices : circleCornerIndices)
328 extendedSourceStencil_.stencil()[bulkElementIdx].insert(extendedSourceStencil_.stencil()[bulkElementIdx].end(),
329 vertices->begin(), vertices->end());
335 extendedSourceStencil_.stencil()[bulkElementIdx].insert(extendedSourceStencil_.stencil()[bulkElementIdx].end(),
336 circleStencil.begin(), circleStencil.end());
343 for (
auto&& stencil : extendedSourceStencil_.stencil())
345 std::sort(stencil.second.begin(), stencil.second.end());
346 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
349 if constexpr (isBox<bulkIdx>())
351 const auto& indices = this->
vertexIndices(bulkIdx, stencil.first);
352 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
353 [&](
auto i){ return std::find(indices.begin(), indices.end(), i) != indices.end(); }),
354 stencil.second.end());
359 stencil.second.erase(std::remove_if(stencil.second.begin(), stencil.second.end(),
360 [&](
auto i){ return i == stencil.first; }),
361 stencil.second.end());
366 using namespace Dune::Hybrid;
367 forEach(integralRange(Dune::index_constant<2>{}), [&](
const auto domainIdx)
371 std::sort(stencil.second.begin(), stencil.second.end());
372 stencil.second.erase(std::unique(stencil.second.begin(), stencil.second.end()), stencil.second.end());
376 std::cout <<
"took " << watch.elapsed() <<
" seconds." << std::endl;