50 using GridView =
typename GridGeometry::GridView;
52 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
53 using FVElementGeometry =
typename GridGeometry::LocalView;
54 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
55 using Scalar =
typename GridView::Grid::ctype;
56 using GlobalPosition =
typename SubControlVolumeFace::GlobalPosition;
58 static constexpr int dim = GridView::dimension;
59 static constexpr int dimWorld = GridView::dimensionworld;
60 static_assert(dim == dimWorld,
"Wall distances cannot be computed for embedded surface or network domains.");
62 using CornerStorage = Dune::ReservedVector<GlobalPosition, (1<<(GridView::dimension-1))>;
69 SimpleGeometry() =
default;
70 SimpleGeometry(CornerStorage&& corners)
71 : corners_(std::move(corners))
74 for (
int i = 0; i < corners_.size(); ++i)
75 center_ += corners_[i];
76 center_ /= corners_.size();
79 using GlobalCoordinate = GlobalPosition;
80 using ctype =
typename GlobalCoordinate::value_type;
81 static constexpr int coorddimension = GridView::dimensionworld;
82 static constexpr int mydimension = GridView::dimension-1;
84 std::size_t corners()
const
85 {
return corners_.size(); }
87 const auto& corner(
int i)
const
88 {
return corners_[i]; }
94 CornerStorage corners_;
95 GlobalCoordinate center_;
101 GridIndexType scvfIdx;
102 GlobalPosition scvfOuterNormal;
106 struct ElementCenters {};
107 struct VertexCenters {};
120 template<
class LocationTag,
class ScvfSelectionFunctor>
121 WallDistance(std::shared_ptr<const GridGeometry> gridGeometry, LocationTag tag,
const ScvfSelectionFunctor& select)
122 : gridGeometry_(gridGeometry)
124 initializeWallDistance_(select, tag);
133 template<
class LocationTag>
134 WallDistance(std::shared_ptr<const GridGeometry> gridGeometry, LocationTag tag)
135 :
WallDistance(gridGeometry, tag, [](const FVElementGeometry& fvGeometry, const SubControlVolumeFace& scvf) {
return true; }) {}
138 template<
class LocationTag,
class ScvfSelectionFunctor>
140 :
WallDistance(
Dune::stackobject_to_shared_ptr(gridGeometry), tag, select) {}
143 template<
class LocationTag>
153 {
return distance_; }
161 {
return wallData_; }
170 template<
class Cons
iderFaceFunction,
class LocationTag>
171 void initializeWallDistance_(
const ConsiderFaceFunction& considerFace, LocationTag loc)
174 ? gridGeometry_->gridView().size(0)
175 : gridGeometry_->gridView().size(dim);
177 wallData_.resize(numSamplingPoints);
178 distance_.resize(numSamplingPoints, std::numeric_limits<Scalar>::max());
180 std::vector<SimpleGeometry> wallGeometries;
181 wallGeometries.reserve(gridGeometry_->numBoundaryScvf());
183 std::vector<WallData> tempWallData;
184 tempWallData.reserve(gridGeometry_->numBoundaryScvf());
187 auto fvGeometry =
localView(*gridGeometry_);
188 for (
const auto& element : elements(gridGeometry_->gridView(), Dune::Partitions::interior))
190 fvGeometry.bindElement(element);
191 if (!fvGeometry.hasBoundaryScvf())
194 const auto eIdx = gridGeometry_->elementMapper().index(element);
196 for (
const auto& scvf : scvfs(fvGeometry))
198 if (scvf.boundary() && considerFace(fvGeometry, scvf))
200 const auto& geo = fvGeometry.geometry(scvf);
201 CornerStorage corners;
202 for (
int i = 0; i < geo.corners(); ++i)
203 corners.push_back(geo.corner(i));
205 wallGeometries.emplace_back(std::move(corners));
207 eIdx, scvf.index(), scvf.unitOuterNormal(), gridGeometry_->gridView().comm().rank()
216 const bool isParallel = gridGeometry_->gridView().comm().size() > 1;
217 std::vector<SimpleGeometry> globalWallGeometries;
218 std::vector<WallData> globalTempWallData;
219 const auto distanceField = [&]
223 const auto& communication = gridGeometry_->gridView().comm();
224 const int totalNumberOfBoundaryGeometries = communication.sum(wallGeometries.size());
225 globalWallGeometries.resize(totalNumberOfBoundaryGeometries);
226 globalTempWallData.resize(totalNumberOfBoundaryGeometries);
229 std::vector<int> numGeosPerProcLocal{
static_cast<int>(wallGeometries.size())};
230 std::vector<int> numGeosPerProcGlobal(communication.size());
231 communication.allgather(numGeosPerProcLocal.data(), 1, numGeosPerProcGlobal.data());
233 std::vector<int> disp(communication.size(), 0);
234 disp[1] = numGeosPerProcGlobal[0];
235 for (
int i = 2; i < numGeosPerProcGlobal.size(); ++i)
236 disp[i] = disp[i-1] + numGeosPerProcGlobal[i-1];
239 communication.allgatherv(
240 wallGeometries.data(),
241 wallGeometries.size(),
242 globalWallGeometries.data(),
243 numGeosPerProcGlobal.data(),
247 communication.allgatherv(
250 globalTempWallData.data(),
251 numGeosPerProcGlobal.data(),
266 std::vector<GlobalPosition> points(numSamplingPoints);
268 for (
const auto& element : elements(gridGeometry_->gridView()))
269 points[gridGeometry_->elementMapper().index(element)] =
element.geometry().center();
271 for (
const auto& vertex : vertices(gridGeometry_->gridView()))
272 points[gridGeometry_->vertexMapper().index(vertex)] =
vertex.geometry().corner(0);
277 const auto kernel = [&](std::size_t eIdx){
278 const auto [d, idx] = distanceField.distanceAndIndex(points[eIdx]);
281 wallData_[eIdx] = isParallel ? globalTempWallData[idx] : tempWallData[idx];
283 wallData_[eIdx] = tempWallData[idx];
287 runKernel_(numSamplingPoints, kernel);
291 const auto kernel = [&](std::size_t vIdx){
292 const auto [d, idx] = distanceField.distanceAndIndex(points[vIdx]);
295 wallData_[vIdx] = isParallel ? globalTempWallData[idx] : tempWallData[idx];
297 wallData_[vIdx] = tempWallData[idx];
301 runKernel_(numSamplingPoints, kernel);
305 template<
class Kernel>
306 void runKernel_(std::size_t size,
const Kernel& kernel)
312 for (std::size_t i = 0; i < size; ++i)
kernel(i);
315 std::vector<Scalar> distance_;
316 std::vector<WallData> wallData_;
317 std::shared_ptr<const GridGeometry> gridGeometry_;