Loading...
Searching...
No Matches
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-2024 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
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
30// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
31
32bool Foam::triangulatedPatch::randomPoint
33(
34 Random& rnd,
35 const scalar c,
36 point& result,
37 label& facei,
38 label& celli
39) const
40{
41 result = point::min;
42 facei = -1;
43 celli = -1;
44
45 if (triWght_.empty() || c < triWght_.front() || c > triWght_.back())
46 {
47 return false;
48 }
49
50 // Find corresponding decomposed face triangle
51 // Note: triWght_ is sized nTri+1 (zero added at start)
52 //
53 // TBD: binary search with findLower(triWght_, c) ??
54 label trii = 0;
55 for (label i = 0; i < triWght_.size() - 1; ++i)
56 {
57 if (c > triWght_[i] && c <= triWght_[i+1])
58 {
59 trii = i;
60 break;
61 }
62 }
63
64 // Find random point in triangle
65 const pointField& points = patch_.points();
66
67 result = triFace_[trii].tri(points).randomPoint(rnd);
68 facei = triFace_[trii].index();
69 celli = patch_.faceCells()[facei];
70
71 if (perturbTol_ > 0)
72 {
73 const polyMesh& mesh = patch_.boundaryMesh().mesh();
74 const point& cc = mesh.cellCentres()[celli];
75
76 // Normal points out of domain => subtract correction
77 const vector& n = patch_.faceNormals()[facei];
78 result -= perturbTol_*n*mag(n & (cc - result));
79
80 // Reset facei - point no longer resides on the face
81 facei = -1;
82 }
84 return true;
85}
86
87
88// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
89
91(
92 const polyPatch& patch,
93 const scalar perturbTol
94)
95:
96 patch_(patch),
97 perturbTol_(perturbTol),
98 triFace_(),
99 triWght_()
100{
101 update();
102}
103
104
106(
107 const polyMesh& mesh,
108 const word& patchName,
109 const scalar perturbTol
110)
111:
112 triangulatedPatch(mesh.boundaryMesh()[patchName], perturbTol)
113{}
114
115
116// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
117
118void Foam::triangulatedPatch::triangulate
119(
120 const polyPatch& pp,
121 List<labelledTri>& tris
122)
123{
124 const pointField& points = pp.points();
125
126 // Triangulate the patch faces and create addressing
127 label nTris = 0;
128 for (const face& f : pp)
129 {
130 nTris += f.nTriangles();
131 }
132
133 DynamicList<labelledTri> dynTris(nTris);
134 DynamicList<face> tfaces(8); // work array
135
136 label facei = 0;
137 for (const face& f : pp)
138 {
139 tfaces.clear();
140 f.triangles(points, tfaces);
141
142 for (const auto& t : tfaces)
143 {
144 dynTris.emplace_back(t[0], t[1], t[2], facei);
145 }
146 ++facei;
147 }
148
149 tris.transfer(dynTris);
150}
151
152
153// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
154
155void Foam::triangulatedPatch::update()
156{
157 triFace_.clear();
158 triWght_.clear();
159
160 triangulate(patch_, triFace_);
161
162 const pointField& points = patch_.points();
163
164 const label myProci = UPstream::myProcNo();
165 const label numProc = UPstream::nProcs();
166
167 // Calculate the cumulative triangle weights
168 triWght_.resize_nocopy(triFace_.size()+1);
169
170 auto iter = triWght_.begin();
171
172 // Set zero value at the start of the tri area/weight list
173 scalar patchArea = 0;
174 *iter++ = patchArea;
175
176 // Calculate cumulative and total area (processor-local at this point)
177 for (const auto& t : triFace_)
178 {
179 patchArea += t.mag(points);
180 *iter++ = patchArea;
181 }
182
183 scalarList procSumArea(numProc+1);
184 procSumArea[0] = 0;
185
186 {
187 scalarList::subList slice(procSumArea, numProc, 1);
188 slice[myProci] = patchArea;
190 }
191
192 // Convert to cumulative
193 for (label i = 1; i < procSumArea.size(); ++i)
194 {
195 procSumArea[i] += procSumArea[i-1];
196 }
197
198 const scalar offset = procSumArea[myProci];
199 const scalar totalArea = procSumArea.back();
200
201 // Apply processor offset and normalise - for a global 0-1 interval
202 for (scalar& w : triWght_)
203 {
204 w = (w + offset) / totalArea;
205 }
206}
207
208
210(
211 Random& rnd,
212 point& result,
213 label& facei,
214 label& celli
215) const
216{
217 if (triWght_.empty())
218 {
219 result = point::min;
220 facei = -1;
221 celli = -1;
222 return false;
223 }
225 const scalar c = rnd.position<scalar>(triWght_.front(), triWght_.back());
226
227 return randomPoint(rnd, c, result, facei, celli);
228}
229
230
232(
233 Random& rnd,
234 point& result,
235 label& facei,
236 label& celli
237) const
238{
239 if (UPstream::parRun())
240 {
241 const scalar c = rnd.sample01<scalar>();
242 const bool ok = randomPoint(rnd, c, result, facei, celli);
243
245
246 // Select the first valid processor
247 label proci = valid.find(true);
248 Pstream::broadcast(proci);
249
250 return (proci == UPstream::myProcNo());
251 }
252 else
253 {
254 return randomLocalPoint(rnd, result, facei, celli);
255 }
256}
257
258
259// ************************************************************************* //
label n
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition List.C:347
SubList< scalar > subList
Definition List.H:129
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
Random number generator.
Definition Random.H:56
Type position(const Type &start, const Type &end)
Return a sample on the interval [start,end].
Type sample01()
Return a sample whose components lie in the range [0,1].
label find(const T &val) const
Find index of the first occurrence of the value.
Definition UList.C:160
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static List< T > listGatherValues(const T &localValue, const int communicator=UPstream::worldComm)
Gather individual values into list locations.
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:1697
@ broadcast
broadcast [MPI]
Definition UPstream.H:189
static const Form min
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
A patch is a list of labels that address the faces in the global face list.
Definition polyPatch.H:73
Performs a triangulation of a patch to return randomised point locations.
bool randomGlobalPoint(Random &rnd, point &result, label &facei, label &celli) const
Set a global random point on the patch.
triangulatedPatch(const polyPatch &patch, const scalar perturbTol)
Constructors.
bool randomLocalPoint(Random &rnd, point &result, label &facei, label &celli) const
Set a random point on the local patch.
A class for handling words, derived from Foam::string.
Definition word.H:66
mesh update()
dynamicFvMesh & mesh
const pointField & points
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
vector point
Point is a vector.
Definition point.H:37
List< bool > boolList
A List of bools.
Definition List.H:60
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
List< scalar > scalarList
List of scalar.
Definition scalarList.H:32
labelList f(nPoints)