24#ifndef DUMUX_DISCRETIZATION_WALL_DISTANCE_HH
25#define DUMUX_DISCRETIZATION_WALL_DISTANCE_HH
33#include <dune/common/parallel/mpihelper.hh>
34#include <dune/common/shared_ptr.hh>
35#include <dune/common/reservedvector.hh>
36#include <dune/grid/common/partitionset.hh>
50template<
class Gr
idGeometry,
template<
class>
class DistanceField = AABBDistanceField>
53 using GridView =
typename GridGeometry::GridView;
55 using SubControlVolumeFace =
typename GridGeometry::SubControlVolumeFace;
56 using FVElementGeometry =
typename GridGeometry::LocalView;
57 using Element =
typename GridGeometry::GridView::template Codim<0>::Entity;
58 using Scalar =
typename GridView::Grid::ctype;
59 using GlobalPosition =
typename SubControlVolumeFace::GlobalPosition;
61 static constexpr int dim = GridView::dimension;
62 static constexpr int dimWorld = GridView::dimensionworld;
63 static_assert(dim == dimWorld,
"Wall distances cannot be computed for embedded surface or network domains.");
65 using CornerStorage = Dune::ReservedVector<GlobalPosition, (1<<(GridView::dimension-1))>;
72 SimpleGeometry() =
default;
73 SimpleGeometry(CornerStorage&& corners)
74 : corners_(std::move(corners))
77 for (
int i = 0; i < corners_.size(); ++i)
78 center_ += corners_[i];
79 center_ /= corners_.size();
82 using GlobalCoordinate = GlobalPosition;
83 using ctype =
typename GlobalCoordinate::value_type;
84 static constexpr int coorddimension = GridView::dimensionworld;
85 static constexpr int mydimension = GridView::dimension-1;
87 std::size_t corners()
const
88 {
return corners_.size(); }
90 const auto& corner(
int i)
const
91 {
return corners_[i]; }
93 const auto& center()
const
97 CornerStorage corners_;
98 GlobalCoordinate center_;
104 GridIndexType scvfIdx;
105 GlobalPosition scvfOuterNormal;
109 struct ElementCenters {};
110 struct VertexCenters {};
123 template<
class LocationTag,
class ScvfSelectionFunctor>
124 WallDistance(std::shared_ptr<const GridGeometry> gridGeometry, LocationTag tag,
const ScvfSelectionFunctor& select)
125 : gridGeometry_(gridGeometry)
127 initializeWallDistance_(select, tag);
136 template<
class LocationTag>
137 WallDistance(std::shared_ptr<const GridGeometry> gridGeometry, LocationTag tag)
138 :
WallDistance(gridGeometry, tag, [](const FVElementGeometry& fvGeometry, const SubControlVolumeFace& scvf) {
return true; }) {}
141 template<
class LocationTag,
class ScvfSelectionFunctor>
142 WallDistance(
const GridGeometry& gridGeometry, LocationTag tag,
const ScvfSelectionFunctor& select)
143 :
WallDistance(
Dune::stackobject_to_shared_ptr(gridGeometry), tag, select) {}
146 template<
class LocationTag>
156 {
return distance_; }
164 {
return wallData_; }
173 template<
class Cons
iderFaceFunction,
class LocationTag>
174 void initializeWallDistance_(
const ConsiderFaceFunction& considerFace, LocationTag loc)
177 ? gridGeometry_->gridView().size(0)
178 : gridGeometry_->gridView().size(dim);
180 wallData_.resize(numSamplingPoints);
181 distance_.resize(numSamplingPoints, std::numeric_limits<Scalar>::max());
183 std::vector<SimpleGeometry> wallGeometries;
184 wallGeometries.reserve(gridGeometry_->numBoundaryScvf());
186 std::vector<WallData> tempWallData;
187 tempWallData.reserve(gridGeometry_->numBoundaryScvf());
190 auto fvGeometry =
localView(*gridGeometry_);
191 for (
const auto& element : elements(gridGeometry_->gridView(), Dune::Partitions::interior))
193 fvGeometry.bindElement(element);
194 if (!fvGeometry.hasBoundaryScvf())
197 const auto eIdx = gridGeometry_->elementMapper().index(element);
199 for (
const auto& scvf : scvfs(fvGeometry))
201 if (scvf.boundary() && considerFace(fvGeometry, scvf))
203 const auto& geo = scvf.geometry();
204 CornerStorage corners;
205 for (
int i = 0; i < geo.corners(); ++i)
206 corners.push_back(geo.corner(i));
208 wallGeometries.emplace_back(std::move(corners));
210 eIdx, scvf.index(), scvf.unitOuterNormal(), gridGeometry_->gridView().comm().rank()
219 const bool isParallel = gridGeometry_->gridView().comm().size() > 1;
220 std::vector<SimpleGeometry> globalWallGeometries;
221 std::vector<WallData> globalTempWallData;
222 const auto distanceField = [&]
226 const auto& communication = gridGeometry_->gridView().comm();
227 const int totalNumberOfBoundaryGeometries = communication.sum(wallGeometries.size());
228 globalWallGeometries.resize(totalNumberOfBoundaryGeometries);
229 globalTempWallData.resize(totalNumberOfBoundaryGeometries);
232 std::vector<int> numGeosPerProcLocal{
static_cast<int>(wallGeometries.size())};
233 std::vector<int> numGeosPerProcGlobal(communication.size());
234 communication.allgather(numGeosPerProcLocal.data(), 1, numGeosPerProcGlobal.data());
236 std::vector<int> disp(communication.size(), 0);
237 disp[1] = numGeosPerProcGlobal[0];
238 for (
int i = 2; i < numGeosPerProcGlobal.size(); ++i)
239 disp[i] = disp[i-1] + numGeosPerProcGlobal[i-1];
242 communication.allgatherv(
243 wallGeometries.data(),
244 wallGeometries.size(),
245 globalWallGeometries.data(),
246 numGeosPerProcGlobal.data(),
250 communication.allgatherv(
253 globalTempWallData.data(),
254 numGeosPerProcGlobal.data(),
259 return DistanceField<SimpleGeometry>(globalWallGeometries);
262 return DistanceField<SimpleGeometry>(wallGeometries);
265 const DistanceField<SimpleGeometry> distanceField(wallGeometries);
269 std::vector<GlobalPosition> points(numSamplingPoints);
271 for (
const auto& element : elements(gridGeometry_->gridView()))
272 points[gridGeometry_->elementMapper().index(element)] =
element.geometry().center();
274 for (
const auto& vertex : vertices(gridGeometry_->gridView()))
275 points[gridGeometry_->vertexMapper().index(vertex)] =
vertex.geometry().corner(0);
280 const auto kernel = [&](std::size_t eIdx){
281 const auto [d, idx] = distanceField.distanceAndIndex(points[eIdx]);
284 wallData_[eIdx] = isParallel ? globalTempWallData[idx] : tempWallData[idx];
286 wallData_[eIdx] = tempWallData[idx];
290 runKernel_(numSamplingPoints,
kernel);
294 const auto kernel = [&](std::size_t vIdx){
295 const auto [d, idx] = distanceField.distanceAndIndex(points[vIdx]);
298 wallData_[vIdx] = isParallel ? globalTempWallData[idx] : tempWallData[idx];
300 wallData_[vIdx] = tempWallData[idx];
304 runKernel_(numSamplingPoints,
kernel);
308 template<
class Kernel>
309 void runKernel_(std::size_t size,
const Kernel&
kernel)
314 tbb::parallel_for(std::size_t(0), size, [&](std::size_t i){
kernel(i); });
316 for (std::size_t i = 0; i < size; ++i)
kernel(i);
319 for (std::size_t i = 0; i < size; ++i)
kernel(i);
323 std::vector<Scalar> distance_;
324 std::vector<WallData> wallData_;
325 std::shared_ptr<const GridGeometry> gridGeometry_;
Defines the index types used for grid and local indices.
Helper class to create (named and comparable) tagged types.
AABBDistanceField< Geometry > DistanceField
Class to calculate the closest distance from a point to a given set of geometries describing the doma...
Definition: distancefield.hh:129
GridCache::LocalView localView(const GridCache &gridCache)
Free function to get the local view of a grid cache object.
Definition: localview.hh:38
Definition: common/pdesolver.hh:36
constexpr Kernel kernel
Definition: couplingmanager1d3d_kernel.hh:50
typename GridView::IndexSet::IndexType GridIndex
Definition: indextraits.hh:39
Helper class to create (named and comparable) tagged types Tags any given type. The tagged type is eq...
Definition: tag.hh:42
Class to calculate the wall distance at every element or vertex of a grid.
Definition: walldistance.hh:52
static constexpr auto atVertexCenters
Definition: walldistance.hh:114
const std::vector< Scalar > & wallDistance() const
Returns a vector storing the distance from each DOF location to the nearest wall. For the atElementCe...
Definition: walldistance.hh:155
WallDistance(std::shared_ptr< const GridGeometry > gridGeometry, LocationTag tag)
Constructs a new wall distance object.
Definition: walldistance.hh:137
WallDistance(const GridGeometry &gridGeometry, LocationTag tag, const ScvfSelectionFunctor &select)
caller has to make sure the lifetime of grid geometry exceeds the lifetime of wall distance
Definition: walldistance.hh:142
WallDataImpl WallData
Definition: walldistance.hh:115
static constexpr auto atElementCenters
Definition: walldistance.hh:113
WallDistance(std::shared_ptr< const GridGeometry > gridGeometry, LocationTag tag, const ScvfSelectionFunctor &select)
Constructs a new wall distance object.
Definition: walldistance.hh:124
const std::vector< WallData > & wallData() const
Returns a vector storing additional information about the nearest scvf on the wall (element index and...
Definition: walldistance.hh:163
WallDistance(const GridGeometry &gridGeometry, LocationTag tag)
caller has to make sure the lifetime of grid geometry exceeds the lifetime of wall distance
Definition: walldistance.hh:147