Loading...
Searching...
No Matches
PatchToolsNormals.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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2019-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "PatchTools.H"
30#include "polyMesh.H"
32#include "globalMeshData.H"
33
34// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35
36template<class FaceList, class PointField>
39(
40 const polyMesh& mesh,
42 const bitSet& pFlip
43)
44{
45 const globalMeshData& globalData = mesh.globalData();
46 const indirectPrimitivePatch& coupledPatch = globalData.coupledPatch();
47 const Map<label>& coupledPatchMP = coupledPatch.meshPointMap();
48 const mapDistribute& map = globalData.globalPointSlavesMap();
49 const globalIndexAndTransform& transforms =
50 globalData.globalTransforms();
51
52
53 // Combine normals. Note: do on all master points. Cannot just use
54 // patch points since the master point does not have to be on the
55 // patch!
56
57 pointField coupledPointNormals(map.constructSize(), Zero);
58
59 {
60 // Collect local pointFaces (sized on patch points only)
61 List<List<point>> pointFaceNormals(map.constructSize());
62 forAll(p.meshPoints(), patchPointi)
63 {
64 const label meshPointi = p.meshPoints()[patchPointi];
65
66 const auto fnd = coupledPatchMP.cfind(meshPointi);
67 if (fnd.good())
68 {
69 const label coupledPointi = fnd.val();
70
71 List<point>& pNormals = pointFaceNormals[coupledPointi];
72 const labelList& pFaces = p.pointFaces()[patchPointi];
73 pNormals.setSize(pFaces.size());
74 forAll(pFaces, i)
75 {
76 const label facei = pFaces[i];
77 const vector& n = p.faceNormals()[facei];
78 pNormals[i] = ((pFlip.empty() || !pFlip[facei]) ? n : -n);
79 }
80 }
81 }
82
83
84 // Pull remote data into local slots
85 map.distribute
86 (
87 transforms,
88 pointFaceNormals,
90 );
91
92
93 // Combine all face normals (-local, -remote,untransformed,
94 // -remote,transformed)
95
96 const labelListList& slaves = globalData.globalPointSlaves();
97 const labelListList& transformedSlaves =
99
100 forAll(slaves, coupledPointi)
101 {
102 const labelList& slaveSlots = slaves[coupledPointi];
103 const labelList& transformedSlaveSlots =
104 transformedSlaves[coupledPointi];
105
106 point& n = coupledPointNormals[coupledPointi];
107
108 // Local entries
109 const List<point>& local = pointFaceNormals[coupledPointi];
110
111 label nFaces =
112 local.size()
113 + slaveSlots.size()
114 + transformedSlaveSlots.size();
115
116 n = sum(local);
117
118 // Add any remote face normals
119 forAll(slaveSlots, i)
120 {
121 n += sum(pointFaceNormals[slaveSlots[i]]);
122 }
123 forAll(transformedSlaveSlots, i)
124 {
125 n += sum(pointFaceNormals[transformedSlaveSlots[i]]);
126 }
127
128 if (nFaces >= 1)
129 {
130 n /= mag(n)+VSMALL;
131 }
132
133 // Put back into slave slots
134 forAll(slaveSlots, i)
135 {
136 coupledPointNormals[slaveSlots[i]] = n;
137 }
138 forAll(transformedSlaveSlots, i)
139 {
140 coupledPointNormals[transformedSlaveSlots[i]] = n;
141 }
142 }
143
144
145 // Send back
147 (
148 transforms,
149 coupledPointNormals.size(),
150 coupledPointNormals,
152 );
153 }
154
155
156 // 1. Start off with local normals (note:without calculating pointNormals
157 // to avoid them being stored)
158
159 auto textrudeN = tmp<pointField>::New(p.nPoints(), Zero);
160 auto& extrudeN = textrudeN.ref();
161 {
162 const faceList& localFaces = p.localFaces();
163 const vectorField& faceNormals = p.faceNormals();
164
165 forAll(localFaces, facei)
166 {
167 const face& f = localFaces[facei];
168 const vector& n = faceNormals[facei];
169 forAll(f, fp)
170 {
171 extrudeN[f[fp]] += ((pFlip.empty() || !pFlip[facei]) ? n : -n);
172 }
173 }
174 extrudeN /= mag(extrudeN)+VSMALL;
175 }
176
177
178 // 2. Override patch normals on coupled points
179 forAll(p.meshPoints(), patchPointi)
180 {
181 const label meshPointi = p.meshPoints()[patchPointi];
182
183 const auto fnd = coupledPatchMP.cfind(meshPointi);
184 if (fnd.good())
185 {
186 const label coupledPointi = fnd.val();
187 extrudeN[patchPointi] = coupledPointNormals[coupledPointi];
188 }
189 }
191 return textrudeN;
192}
193
194
195template<class FaceList, class PointField>
198(
199 const polyMesh& mesh,
201 const labelList& patchEdges,
202 const labelList& coupledEdges,
203 const bitSet& pFlip
204)
205{
206 // 1. Start off with local normals
207
208 auto tedgeNormals = tmp<pointField>::New(p.nEdges(), Zero);
209 auto& edgeNormals = tedgeNormals.ref();
210
211 {
212 const labelListList& edgeFaces = p.edgeFaces();
213 const vectorField& faceNormals = p.faceNormals();
214
215 forAll(edgeFaces, edgei)
216 {
217 const labelList& eFaces = edgeFaces[edgei];
218 for (const label facei : eFaces)
219 {
220 const vector& n = faceNormals[facei];
221 edgeNormals[edgei] +=
222 (
223 (pFlip.empty() || !pFlip[facei])
224 ? n
225 : -n
226 );
227 }
228 }
229 edgeNormals /= mag(edgeNormals)+VSMALL;
230 }
231
232
233
234 const globalMeshData& globalData = mesh.globalData();
235 const mapDistribute& map = globalData.globalEdgeSlavesMap();
236
237
238 // Convert patch-edge data into cpp-edge data
239 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240
241 //- Construct with all data in consistent orientation
242 pointField cppEdgeData(map.constructSize(), Zero);
243
244 forAll(patchEdges, i)
245 {
246 label patchEdgeI = patchEdges[i];
247 label coupledEdgeI = coupledEdges[i];
248 cppEdgeData[coupledEdgeI] = edgeNormals[patchEdgeI];
249 }
250
251
252 // Synchronise
253 // ~~~~~~~~~~~
254
255 globalData.syncData
256 (
257 cppEdgeData,
258 globalData.globalEdgeSlaves(),
259 globalData.globalEdgeTransformedSlaves(),
260 map,
261 globalData.globalTransforms(),
262 plusEqOp<point>(), // add since normalised later on
264 );
265 cppEdgeData /= mag(cppEdgeData)+VSMALL;
266
267
268 // Back from cpp-edge to patch-edge data
269 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
270
271 forAll(patchEdges, i)
272 {
273 label patchEdgeI = patchEdges[i];
274 label coupledEdgeI = coupledEdges[i];
275 edgeNormals[patchEdgeI] = cppEdgeData[coupledEdgeI];
276 }
277
278 return tedgeNormals;
280
281
282template<class FaceList, class PointField>
285(
286 const polyMesh& mesh,
288 const pointField& localPoints,
289 const bitSet& pFlip
290)
291{
292 const globalMeshData& globalData = mesh.globalData();
293 const indirectPrimitivePatch& coupledPatch = globalData.coupledPatch();
294 const Map<label>& coupledPatchMP = coupledPatch.meshPointMap();
295 const mapDistribute& map = globalData.globalPointSlavesMap();
296 const globalIndexAndTransform& transforms = globalData.globalTransforms();
297 const auto& localFaces = p.localFaces();
298
299
300 // Combine normals. Note: do on all master points. Cannot just use
301 // patch points since the master point does not have to be on the
302 // patch!
303
304 pointField coupledPointNormals(map.constructSize(), Zero);
305
306 {
307 // Collect local pointFaces (sized on patch points only)
308 List<List<point>> pointFaceNormals(map.constructSize());
309 forAll(p.meshPoints(), patchPointi)
310 {
311 const label meshPointi = p.meshPoints()[patchPointi];
312
313 const auto fnd = coupledPatchMP.cfind(meshPointi);
314 if (fnd.good())
315 {
316 const label coupledPointi = fnd.val();
317
318 List<point>& pNormals = pointFaceNormals[coupledPointi];
319 const labelList& pFaces = p.pointFaces()[patchPointi];
320 pNormals.setSize(pFaces.size());
321 forAll(pFaces, i)
322 {
323 const label facei = pFaces[i];
324 const vector n = localFaces[facei].unitNormal(localPoints);
325 pNormals[i] = ((pFlip.empty() || !pFlip[facei]) ? n : -n);
326 }
327 }
328 }
329
330
331 // Pull remote data into local slots
332 map.distribute
333 (
334 transforms,
335 pointFaceNormals,
337 );
338
339
340 // Combine all face normals (-local, -remote,untransformed,
341 // -remote,transformed)
342
343 const labelListList& slaves = globalData.globalPointSlaves();
344 const labelListList& transformedSlaves =
345 globalData.globalPointTransformedSlaves();
346
347 forAll(slaves, coupledPointi)
348 {
349 const labelList& slaveSlots = slaves[coupledPointi];
350 const labelList& transformedSlaveSlots =
351 transformedSlaves[coupledPointi];
352
353 point& n = coupledPointNormals[coupledPointi];
354
355 // Local entries
356 const List<point>& local = pointFaceNormals[coupledPointi];
357
358 label nFaces =
359 local.size()
360 + slaveSlots.size()
361 + transformedSlaveSlots.size();
362
363 n = sum(local);
364
365 // Add any remote face normals
366 forAll(slaveSlots, i)
367 {
368 n += sum(pointFaceNormals[slaveSlots[i]]);
369 }
370 forAll(transformedSlaveSlots, i)
371 {
372 n += sum(pointFaceNormals[transformedSlaveSlots[i]]);
373 }
374
375 if (nFaces >= 1)
376 {
377 n /= mag(n)+VSMALL;
378 }
379
380 // Put back into slave slots
381 forAll(slaveSlots, i)
382 {
383 coupledPointNormals[slaveSlots[i]] = n;
384 }
385 forAll(transformedSlaveSlots, i)
386 {
387 coupledPointNormals[transformedSlaveSlots[i]] = n;
388 }
389 }
390
391
392 // Send back
394 (
395 transforms,
396 coupledPointNormals.size(),
397 coupledPointNormals,
399 );
400 }
401
402
403 // 1. Start off with local normals (note:without calculating pointNormals
404 // to avoid them being stored)
405
406 auto textrudeN = tmp<pointField>::New(p.nPoints(), Zero);
407 auto& extrudeN = textrudeN.ref();
408 {
409 forAll(localFaces, facei)
410 {
411 const face& f = localFaces[facei];
412 const vector n = f.unitNormal(localPoints);
413 forAll(f, fp)
414 {
415 extrudeN[f[fp]] += ((pFlip.empty() || !pFlip[facei]) ? n : -n);
416 }
417 }
418 extrudeN /= mag(extrudeN)+VSMALL;
419 }
420
421
422 // 2. Override patch normals on coupled points
423 forAll(p.meshPoints(), patchPointi)
424 {
425 const label meshPointi = p.meshPoints()[patchPointi];
426
427 const auto fnd = coupledPatchMP.cfind(meshPointi);
428 if (fnd.good())
429 {
430 const label coupledPointi = fnd.val();
431 extrudeN[patchPointi] = coupledPointNormals[coupledPointi];
432 }
433 }
434
435 return textrudeN;
437
438
439template<class FaceList, class PointField>
442(
443 const polyMesh& mesh,
445 const pointField& localPoints,
446 const labelList& patchEdges,
447 const labelList& coupledEdges,
448 const bitSet& pFlip
449)
450{
451 const auto& localFaces = p.localFaces();
452
453 // 1. Start off with local normals
454
455 auto tedgeNormals = tmp<pointField>::New(p.nEdges(), Zero);
456 auto& edgeNormals = tedgeNormals.ref();
457
458 {
459 const labelListList& edgeFaces = p.edgeFaces();
460
461 forAll(edgeFaces, edgei)
462 {
463 const labelList& eFaces = edgeFaces[edgei];
464 for (const label facei : eFaces)
465 {
466 const vector n = localFaces[facei].unitNormal(localPoints);
467
468 edgeNormals[edgei] +=
469 (
470 (pFlip.empty() || !pFlip[facei])
471 ? n
472 : -n
473 );
474 }
475 }
476 edgeNormals /= mag(edgeNormals)+VSMALL;
477 }
478
479
480
481 const globalMeshData& globalData = mesh.globalData();
482 const mapDistribute& map = globalData.globalEdgeSlavesMap();
483
484
485 // Convert patch-edge data into cpp-edge data
486 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
487
488 //- Construct with all data in consistent orientation
489 pointField cppEdgeData(map.constructSize(), Zero);
490
491 forAll(patchEdges, i)
492 {
493 label patchEdgeI = patchEdges[i];
494 label coupledEdgeI = coupledEdges[i];
495 cppEdgeData[coupledEdgeI] = edgeNormals[patchEdgeI];
496 }
497
498
499 // Synchronise
500 // ~~~~~~~~~~~
501
502 globalData.syncData
503 (
504 cppEdgeData,
505 globalData.globalEdgeSlaves(),
506 globalData.globalEdgeTransformedSlaves(),
507 map,
508 globalData.globalTransforms(),
509 plusEqOp<point>(), // add since normalised later on
511 );
512 cppEdgeData /= mag(cppEdgeData)+VSMALL;
513
514
515 // Back from cpp-edge to patch-edge data
516 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
517
518 forAll(patchEdges, i)
519 {
520 label patchEdgeI = patchEdges[i];
521 label coupledEdgeI = coupledEdges[i];
522 edgeNormals[patchEdgeI] = cppEdgeData[coupledEdgeI];
523 }
524
525 return tedgeNormals;
526}
527
528
529// ************************************************************************* //
label n
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition HashTableI.H:113
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 setSize(label n)
Alias for resize().
Definition List.H:536
A HashTable to objects of type <T> with a label key.
Definition Map.H:54
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition PackedList.H:387
static tmp< pointField > edgeNormals(const polyMesh &, const PrimitivePatch< FaceList, PointField > &, const labelList &patchEdges, const labelList &coupledEdges, const bitSet &flipMap=bitSet::null())
Return parallel consistent edge normals for patches using mesh points.
static tmp< pointField > pointNormals(const polyMesh &, const PrimitivePatch< FaceList, PointField > &, const bitSet &flipMap=bitSet::null())
Return parallel consistent point normals for patches using mesh points.
A list of faces which address into the list of points.
const Map< label > & meshPointMap() const
Mesh point map.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Determination and storage of the possible independent transforms introduced by coupledPolyPatches,...
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
const labelListList & globalEdgeTransformedSlaves() const
const mapDistribute & globalPointSlavesMap() const
const mapDistribute & globalEdgeSlavesMap() const
static void syncData(List< Type > &elems, const labelListList &slaves, const labelListList &transformedSlaves, const mapDistribute &slavesMap, const globalIndexAndTransform &, const CombineOp &cop, const TransformOp &top)
Helper: synchronise data with transforms.
const labelListList & globalPointSlaves() const
const globalIndexAndTransform & globalTransforms() const
Global transforms numbering.
const labelListList & globalPointTransformedSlaves() const
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
const labelListList & globalEdgeSlaves() const
label constructSize() const noexcept
Constructed data size.
Default transformation behaviour.
Class containing processor-to-processor mapping information.
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute List data using default commsType, default flip/negate operator.
Mesh consisting of general polyhedral cells.
Definition polyMesh.H:79
A class for managing temporary objects.
Definition tmp.H:75
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition tmp.H:215
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
volScalarField & p
bool local
Definition EEqn.H:20
dynamicFvMesh & mesh
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
List< face > faceList
List of faces.
Definition faceListFwd.H:41
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field.
Field< vector > vectorField
Specialisation of Field<T> for vector.
vector point
Point is a vector.
Definition point.H:37
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};constexpr label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< DynamicList< face > > pFaces[nBCs]
labelList f(nPoints)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299