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-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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"
31 #include "indirectPrimitivePatch.H"
32 #include "globalMeshData.H"
33 
34 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 
36 template<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 =
98  globalData.globalPointTransformedSlaves();
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  }
190 
191  return textrudeN;
192 }
193 
194 
195 template<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;
279 }
280 
281 
282 // ************************************************************************* //
reference val() const
Const access to referenced object (value)
Definition: HashTable.H:1185
const labelListList & globalPointSlaves() const
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
const labelListList & globalPointTransformedSlaves() const
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
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.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
const mapDistribute & globalEdgeSlavesMap() const
Various mesh related information for a parallel run. Upon construction, constructs all info using par...
const mapDistribute & globalPointSlavesMap() const
label constructSize() const noexcept
Constructed data size.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
A list of faces which address into the list of points.
const Map< label > & meshPointMap() const
Mesh point map.
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
void setSize(const label n)
Alias for resize()
Definition: List.H:316
dynamicFvMesh & mesh
Default transformation behaviour.
const globalIndexAndTransform & globalTransforms() const
Global transforms numbering.
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:113
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
const globalMeshData & globalData() const
Return parallel info (demand-driven)
Definition: polyMesh.C:1311
bool local
Definition: EEqn.H:20
void reverseDistribute(const label constructSize, List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
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.
labelList f(nPoints)
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];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } 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};const 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< SLList< face > > pFaces[nBCs]
Definition: readKivaGrid.H:235
const indirectPrimitivePatch & coupledPatch() const
Return patch of all coupled faces.
bool empty() const noexcept
True if the list is empty (ie, size() is zero).
Definition: PackedList.H:366
Class containing processor-to-processor mapping information.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
label n
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50
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.
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:521
Determination and storage of the possible independent transforms introduced by coupledPolyPatches, as well as all of the possible permutations of these transforms generated by the presence of multiple coupledPolyPatches, i.e. more than one cyclic boundary. Note that any given point can be on maximum 3 transforms only (and these transforms have to be perpendicular)
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127