boundaryPoints.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "boundaryPoints.H"
27 #include "polyMesh.H"
29 #include "treeBoundBox.H"
30 #include "treeDataFace.H"
31 #include "Time.H"
32 #include "OBJstream.H"
33 #include "RemoteData.H"
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 namespace sampledSets
40 {
43 }
44 }
45 
46 
47 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 
49 bool Foam::sampledSets::boundaryPoints::calcSamples
50 (
51  DynamicList<point>& samplingPositions,
52  DynamicList<scalar>&,
53  DynamicList<label>& samplingSegments,
54  DynamicList<label>& samplingCells,
55  DynamicList<label>& samplingFaces
56 ) const
57 {
58  // Get the patch IDs
59  const labelHashSet patchIDs(mesh().boundary().patchSet(patches_));
60 
61  // Construct a single list of all patch faces
62  label nPatchFaces = 0;
63  forAllConstIter(labelHashSet, patchIDs, iter)
64  {
65  const polyPatch& pp = mesh().boundary()[iter.key()];
66  nPatchFaces += pp.size();
67  }
68  labelList patchFaces(nPatchFaces);
69  nPatchFaces = 0;
70  forAllConstIter(labelHashSet, patchIDs, iter)
71  {
72  const polyPatch& pp = mesh().boundary()[iter.key()];
73  forAll(pp, i)
74  {
75  patchFaces[nPatchFaces++] = pp.start()+i;
76  }
77  }
78 
79  // Construct a processor-local bound box
80  treeBoundBox patchBB(point::max, point::min);
81  forAllConstIter(labelHashSet, patchIDs, iter)
82  {
83  const polyPatch& pp = mesh().boundary()[iter.key()];
84  const boundBox patchBb(pp.points(), pp.meshPoints(), false);
85  patchBB.min() = min(patchBB.min(), patchBb.min());
86  patchBB.max() = max(patchBB.max(), patchBb.max());
87  }
88  patchBB = patchBB.extend(1e-4);
89 
90  // Create a search tree
91  indexedOctree<treeDataFace> patchTree
92  (
93  treeDataFace // all information needed to search faces
94  (
95  false, // do not cache the bound box
96  mesh(),
97  patchFaces
98  ),
99  patchBB, // overall search box
100  8, // maximum number of levels
101  10, // how many elements per leaf
102  3.0 // in how many leaves is a shape on average
103  );
104 
105  // Force calculation of face-diagonal decomposition
106  (void)mesh().tetBasePtIs();
107 
108  // Generate the nearest patch information for each sampling point
109  List<RemoteData<Tuple2<scalar, point>>> nearest(points_.size());
110  forAll(points_, sampleI)
111  {
112  const point& sample = points_[sampleI];
113 
114  const pointIndexHit pih =
115  patchFaces.size()
116  ? patchTree.findNearest(sample, sqr(maxDistance_))
117  : pointIndexHit();
118 
119  if (pih.hit())
120  {
121  nearest[sampleI].proci = Pstream::myProcNo();
122  nearest[sampleI].elementi = patchFaces[pih.index()];
123  nearest[sampleI].data.first() = magSqr(pih.hitPoint() - sample);
124  nearest[sampleI].data.second() = pih.hitPoint();
125  }
126  }
127 
128  // Reduce to get the nearest patch locations globally
130  (
131  nearest,
132  RemoteData<Tuple2<scalar, point>>::smallestFirstEqOp()
133  );
135 
136  // Dump connecting lines from the sampling points to the hit locations
137  if (debug && Pstream::master())
138  {
139  OBJstream str(mesh().time().path()/(name() + "_nearest.obj"));
140 
141  forAll(nearest, sampleI)
142  {
143  if (nearest[sampleI].proci != -1)
144  {
145  str.write
146  (
148  (
149  points_[sampleI],
150  nearest[sampleI].data.second()
151  )
152  );
153  }
154  }
155  }
156 
157  // Store the sampling locations on the nearest processor
158  forAll(nearest, sampleI)
159  {
160  if (nearest[sampleI].proci != -1)
161  {
162  if (nearest[sampleI].proci == Pstream::myProcNo())
163  {
164  const label facei = nearest[sampleI].elementi;
165 
166  samplingPositions.append(nearest[sampleI].data.second());
167  samplingSegments.append(sampleI);
168  samplingCells.append(mesh().faceOwner()[facei]);
169  samplingFaces.append(facei);
170  }
171  }
172  else
173  {
175  << "Unable to find location on patches " << patches_
176  << " for the point " << points_[sampleI]
177  << " within a distance of " << maxDistance_ << endl;
178  }
179  }
180 
181  // This set is unordered. Distances have not been created.
182  return false;
183 }
184 
185 
186 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
187 
189 (
190  const word& name,
191  const polyMesh& mesh,
192  const dictionary& dict
193 )
194 :
196  points_(dict.lookup("points")),
197  patches_(dict.lookup("patches")),
198  maxDistance_(dict.lookup<scalar>("maxDistance"))
199 {}
200 
201 
202 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
203 
205 {}
206 
207 
208 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:492
Macros for easy insertion into run-time selection tables.
static void listCombineGather(const List< commsStruct > &comms, List< T > &Value, const CombineOp &cop, const int tag, const label comm)
static void listCombineScatter(const List< commsStruct > &comms, List< T > &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:423
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
static const Form max
Definition: VectorSpace.H:120
static const Form min
Definition: VectorSpace.H:121
A list of keywords followed by any number of values (e.g. words and numbers) or sub-dictionaries.
Definition: dictionary.H:162
Motion of the mesh specified as a list of pointMeshMovers.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:78
const polyBoundaryMesh & boundary() const
Return boundary mesh.
Definition: polyMesh.H:393
const labelIOList & tetBasePtIs() const
Return the tetBasePtIs.
Definition: polyMesh.C:1064
Holds list of sampling points which is filled at construction time. Various implementations of this b...
Definition: sampledSet.H:64
const polyMesh & mesh() const
Access the mesh.
Definition: sampledSetI.H:36
const word & name() const
Access the name.
Definition: sampledSetI.H:30
Specified point samples within patches.
virtual ~boundaryPoints()
Destructor.
boundaryPoints(const word &name, const polyMesh &mesh, const dictionary &dict)
Construct from dictionary.
Set of sets to sample. Call sampledSets.write() to sample&write files.
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
#define WarningInFunction
Report a warning using Foam::Warning.
const dimensionSet time
defineTypeNameAndDebug(arcUniform, 0)
addToRunTimeSelectionTable(sampledSet, arcUniform, word)
const unitSet & lookup(const word &unitName)
Lookup and return the named unit from the table.
Definition: units.C:346
Namespace for OpenFOAM.
const doubleScalar e
Definition: doubleScalar.H:106
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
PointIndexHit< point > pointIndexHit
Definition: pointIndexHit.H:42
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
line< point, const point & > linePointRef
Line using referred points.
Definition: linePointRef.H:45
vector point
Point is a vector.
Definition: point.H:41
tmp< DimensionedField< typename outerProduct< Type, Type >::type, GeoMesh, Field >> sqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
Definition: HashSet.H:213
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
faceListList boundary(nPatches)
dictionary dict