triangulatedPatch.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2023 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "triangulatedPatch.H"
29 #include "triPointRef.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 bool Foam::triangulatedPatch::randomPoint
34 (
35  Random& rnd,
36  const scalar c,
37  point& result,
38  label& facei,
39  label& celli
40 ) const
41 {
42  result = point::min;
43  facei = -1;
44  celli = -1;
45 
46  if (triWght_.empty() || c < triWght_.front() || c > triWght_.back())
47  {
48  return false;
49  }
50 
51  // Find corresponding decomposed face triangle
52  // Note: triWght_ is sized nTri+1 (zero added at start)
53  label trii = 0;
54  for (label i = 0; i < triWght_.size() - 1; ++i)
55  {
56  if (c > triWght_[i] && c <= triWght_[i+1])
57  {
58  trii = i;
59  break;
60  }
61  }
62 
63  // Find random point in triangle
64  const pointField& points = patch_.points();
65  const face& tf = triFace_[trii];
66  const triPointRef tri(points[tf[0]], points[tf[1]], points[tf[2]]);
67 
68  result = tri.randomPoint(rnd);
69  facei = triToFace_[trii];
70  celli = patch_.faceCells()[facei];
71 
72  if (perturbTol_ > 0)
73  {
74  const polyMesh& mesh = patch_.boundaryMesh().mesh();
75  const point& cc = mesh.cellCentres()[celli];
76 
77  // Normal points out of domain => subtract correction
78  const vector& n = patch_.faceNormals()[facei];
79  result -= perturbTol_*n*mag(n & (cc - result));
80 
81  // Reset facei - point no longer resides on the face
82  facei = -1;
83  }
84 
85  return true;
86 }
87 
88 
89 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
90 
92 (
93  const polyPatch& patch,
94  const scalar perturbTol
95 )
96 :
97  patch_(patch),
98  perturbTol_(perturbTol),
99  triFace_(),
100  triToFace_(),
101  triWght_()
102 {
103  update();
104 }
105 
106 
108 (
109  const polyMesh& mesh,
110  const word& patchName,
111  const scalar perturbTol
112 )
113 :
114  triangulatedPatch(mesh.boundaryMesh()[patchName], perturbTol)
115 {}
116 
117 
118 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
119 
120 void Foam::triangulatedPatch::update()
121 {
122  const pointField& points = patch_.points();
123 
124  // Triangulate the patch faces and create addressing
125  DynamicList<label> triToFace(2*patch_.size());
126  DynamicList<face> triFace(2*patch_.size());
127  DynamicList<scalar> triWght(2*patch_.size());
128  DynamicList<face> tris(8);
129 
130  // Set zero value at the start of the tri area/weight list
131  triWght.push_back(0);
132 
133  forAll(patch_, facei)
134  {
135  const face& f = patch_[facei];
136 
137  tris.clear();
138  f.triangles(points, tris);
139 
140  for (const auto& t : tris)
141  {
142  triToFace.push_back(facei);
143  triFace.push_back(t);
144  triWght.push_back(t.mag(points));
145  }
146  }
147 
148  scalarList procSumWght(Pstream::nProcs()+1, Zero);
149  procSumWght[Pstream::myProcNo()+1] = sum(triWght);
150  Pstream::listCombineReduce(procSumWght, maxEqOp<scalar>());
151 
152  for (label i = 1; i < procSumWght.size(); ++i)
153  {
154  // Convert to cumulative
155  procSumWght[i] += procSumWght[i-1];
156  }
157 
158  const scalar offset = procSumWght[Pstream::myProcNo()];
159  forAll(triWght, i)
160  {
161  if (i)
162  {
163  // Convert to cumulative
164  triWght[i] += triWght[i-1];
165  }
166 
167  // Apply processor offset
168  triWght[i] += offset;
169  }
170 
171  // Normalise
172  const scalar sumWght = procSumWght.back();
173  for (scalar& w : triWght)
174  {
175  w /= sumWght;
176  }
177 
178  // Transfer to persistent storage
179  triFace_.transfer(triFace);
180  triToFace_.transfer(triToFace);
181  triWght_.transfer(triWght);
182 }
183 
184 
186 (
187  Random& rnd,
188  point& result,
189  label& facei,
190  label& celli
191 ) const
192 {
193  const scalar c = rnd.position<scalar>(triWght_.front(), triWght_.back());
194 
195  return randomPoint(rnd, c, result, facei, celli);
196 }
197 
198 
200 (
201  Random& rnd,
202  point& result,
203  label& facei,
204  label& celli
205 ) const
206 {
207  boolList valid(UPstream::nProcs(), false);
208  valid[UPstream::myProcNo()] = randomLocalPoint(rnd, result, facei, celli);
210 
211  forAll(valid, proci)
212  {
213  // Choose first valid processor
214  if (valid[proci])
215  {
216  return (proci == UPstream::myProcNo());
217  }
218  }
219 
220  return false;
221 }
222 
223 
224 // ************************************************************************* //
triangulatedPatch(const polyPatch &patch, const scalar perturbTol)
Constructors.
List< scalar > scalarList
List of scalar.
Definition: scalarList.H:32
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
bool empty() const noexcept
True if List is empty (ie, size() is zero)
Definition: UList.H:666
T & front()
Access first element of the list, position [0].
Definition: UListI.H:237
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface...
Definition: boundaryMesh.H:58
static List< T > listGatherValues(const T &localValue, const label communicator=worldComm)
Gather individual values into list locations.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
void push_back(const T &val)
Append an element at the end of the list.
Definition: ListI.H:227
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
const pointField & points
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundaryMesh reference.
Definition: polyPatch.C:309
const labelUList & faceCells() const
Return face-cell addressing.
Definition: polyPatch.C:365
const polyMesh & mesh() const noexcept
Return the mesh reference.
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:137
A class for handling words, derived from Foam::string.
Definition: word.H:63
bool randomLocalPoint(Random &rnd, point &result, label &facei, label &celli) const
Set a random point on the local patch.
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:65
face triFace(3)
bool randomGlobalPoint(Random &rnd, point &result, label &facei, label &celli) const
Set a global random point on the patch.
Vector< scalar > vector
Definition: vector.H:57
const Field< point_type > & points() const noexcept
Return reference to global points.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
Random number generator.
Definition: Random.H:55
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
mesh update()
labelList f(nPoints)
Performs a triangulation of a patch to return randomised point locations.
vector point
Point is a vector.
Definition: point.H:37
const dimensionedScalar c
Speed of light in a vacuum.
const std::string patch
OpenFOAM patch number as a std::string.
triangle< point, const point & > triPointRef
A triangle using referred points.
Definition: triangleFwd.H:39
T & back()
Access last element of the list, position [size()-1].
Definition: UListI.H:251
label n
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
Type position(const Type &start, const Type &end)
Return a sample on the interval [start,end].
static void listCombineReduce(List< T > &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
After completion all processors have the same data.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127