PDRmeshArrays.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) 2016 Shell Research Ltd.
9  Copyright (C) 2019 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 "PDRmeshArrays.H"
30 #include "PDRblock.H"
31 #include "polyMesh.H"
32 #include "Time.H"
33 #include "IjkField.H"
34 
35 // Notes
36 //
37 // Determines the face and cell numbers of all faces and cells in the
38 // central rectangular region where CAD_PDR operates. First,
39 // "points" is read and the coordinates (by which I mean here the
40 // indices in the x, y and z coordinate arrays) are determined. Then
41 // "faces" is read and for each the coordinates of the lower- x,y,z
42 // corner are determioned, also the orientation (X, Y or Z).
43 // (Orientation in the sense of e.g. + or -x is not noted.) The files
44 // "owner" and "neighbour" specify the six faces around each cell, so
45 // from these the coordinates of the cells are determined.
46 //
47 // Full checks are made that the mesh in the central region is consistent
48 // with CAD_PDR's mesh specified by the PDRmeshSpec file.
49 //
50 // Eventually, when writing out results, we shall work through the
51 // full list of cells, writing default values for any cells that are
52 // not in the central regtion.
53 
54 
55 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
56 
57 Foam::scalar Foam::PDRmeshArrays::gridPointRelTol = 0.02;
58 
59 
60 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
61 
63 (
64  const polyMesh& mesh,
65  const PDRblock& pdrBlock
66 )
67 {
68  // Additional copy of i-j-k addressing
69  cellDims = pdrBlock.sizes();
71 
72  const label maxPointId = cmptMax(pdrBlock.sizes())+1;
73 
74  Info<< "Mesh" << nl
75  << " nPoints:" << mesh.nPoints()
76  << " nCells:" << mesh.nCells()
77  << " nFaces:" << mesh.nFaces() << nl;
78 
79  Info<< "PDRblock" << nl
80  << " minEdgeLen:" << pdrBlock.minEdgeLen() << nl;
81 
82 
83  // Bin points into i-j-k locations
84  List<labelVector> pointIndex(mesh.nPoints());
85 
86  for (label pointi=0; pointi < mesh.nPoints(); ++pointi)
87  {
88  const point& pt = mesh.points()[pointi];
89  pointIndex[pointi] = pdrBlock.gridIndex(pt, gridPointRelTol);
90  }
91 
92  // Min x,y,z index
93  const labelMinMax invertedLimits(maxPointId, -maxPointId);
94  Vector<labelMinMax> faceLimits;
95 
96  const Vector<direction> faceBits
97  (
101  );
102 
103  faceIndex.resize(mesh.nFaces());
104  faceOrient.resize(mesh.nFaces());
105 
106  for (label facei=0; facei < mesh.nFaces(); ++facei)
107  {
108  faceLimits.x() = faceLimits.y() = faceLimits.z() = invertedLimits;
109 
110  for (const label pointi : mesh.faces()[facei])
111  {
112  for (direction cmpt=0; cmpt < labelVector::nComponents; ++cmpt)
113  {
114  faceLimits[cmpt].add(pointIndex[pointi][cmpt]);
115  }
116  }
117 
118  direction inPlane(0u);
119 
120  for (direction cmpt=0; cmpt < labelVector::nComponents; ++cmpt)
121  {
122  const auto& limits = faceLimits[cmpt];
123 
124  if (!limits.valid())
125  {
126  // This should be impossible
128  << "Unexpected search failure for " << facei << " in "
129  << vector::componentNames[cmpt] << "-direction" << nl
130  << exit(FatalError);
131  }
132 
133  if (limits.min() < 0)
134  {
136  << "Face " << facei << " contains non-grid point in "
137  << vector::componentNames[cmpt] << "-direction" << nl
138  << exit(FatalError);
139  }
140  else if (limits.min() == limits.max())
141  {
142  // In plane
143  inPlane |= faceBits[cmpt];
144  }
145  else if (limits.min() + 1 != limits.max())
146  {
148  << "Face " << facei
149  << " not in " << vector::componentNames[cmpt] << "-plane" << nl
150  << exit(FatalError);
151  }
152  }
153 
154  switch (inPlane)
155  {
156  case boundBox::XDIR:
157  faceOrient[facei] = vector::X;
158  break;
159 
160  case boundBox::YDIR:
161  faceOrient[facei] = vector::Y;
162  break;
163 
164  case boundBox::ZDIR:
165  faceOrient[facei] = vector::Z;
166  break;
167 
168  default:
170  << "Face " << facei << " not in an x/y/z plane?" << nl
171  << exit(FatalError);
172  break;
173  }
174 
175  faceIndex[facei] =
177  (
178  faceLimits.x().min(),
179  faceLimits.y().min(),
180  faceLimits.z().min()
181  );
182  }
183 
184 
185  // Bin cells into i-j-k locations
186  cellIndex = std::move(pointIndex);
187  cellIndex = labelVector::uniform(maxPointId);
188  cellIndex.resize(mesh.nCells(), labelVector::uniform(maxPointId));
189 
190  // Option 1: use PDRblock.findCell() method
191  if (true)
192  {
193  const pointField& cc = mesh.cellCentres();
194 
195  for (label celli=0; celli < mesh.nCells(); ++celli)
196  {
197  cellIndex[celli] = pdrBlock.findCell(cc[celli]);
198  }
199  }
200 
201  // Option 2: walk cell faces and use faceIndex information
202  if (false)
203  {
204  for (label celli=0; celli < mesh.nCells(); ++celli)
205  {
206  labelVector& cellIdx = cellIndex[celli];
207 
208  for (const label facei : mesh.cells()[celli])
209  {
210  cellIdx.x() = min(cellIdx.x(), faceIndex[facei].x());
211  cellIdx.y() = min(cellIdx.y(), faceIndex[facei].y());
212  cellIdx.z() = min(cellIdx.z(), faceIndex[facei].z());
213  }
214 
215  if (cmptMin(cellIdx) < 0)
216  {
217  cellIdx = labelVector(-1,-1,-1);
218  }
219  }
220  }
221 
222 
223  // Verify that all i-j-k cells were found
224  {
225  // This could be more efficient - but we want to be picky
226  IjkField<bool> cellFound(pdrBlock.sizes(), false);
227 
228  for (label celli=0; celli < cellIndex.size(); ++celli)
229  {
230  const labelVector& cellIdx = cellIndex[celli];
231 
232  if (cmptMin(cellIdx) >= 0)
233  {
234  cellFound(cellIdx) = true;
235  }
236  }
237 
238  label firstMissing = cellFound.find(false);
239 
240  if (firstMissing >= 0)
241  {
243  << "No cell found for " << pdrBlock.index(firstMissing)
244  << " indexing"
245  << exit(FatalError);
246  }
247  }
248 }
249 
250 
252 (
253  const Time& runTime,
254  const PDRblock& pdrBlock
255 )
256 {
257  #include "createPolyMesh.H"
258  classify(mesh, pdrBlock);
259 }
260 
261 
262 // ************************************************************************* //
Foam::PDRmeshArrays::faceIndex
List< labelVector > faceIndex
For each face, the corresponding i-j-k address.
Definition: PDRmeshArrays.H:82
Foam::pointField
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::PDRmeshArrays::classify
void classify(const polyMesh &mesh, const PDRblock &pdrBlock)
Determine i-j-k indices for faces/cells.
Foam::VectorSpace< Vector< label >, label, 3 >::one
static const Vector< label > one
Definition: VectorSpace.H:116
Foam::Vector< scalar >::Z
Definition: Vector.H:81
Foam::Vector< scalar >::Y
Definition: Vector.H:81
Foam::VectorSpace< Vector< label >, label, 3 >::uniform
static Vector< label > uniform(const label &s)
Return a VectorSpace with all elements = s.
Definition: VectorSpaceI.H:164
Foam::VectorSpace< Vector< scalar >, scalar, 3 >::componentNames
static const char *const componentNames[]
Definition: VectorSpace.H:114
Foam::PDRmeshArrays::cellDims
labelVector cellDims
The cell i-j-k addressing range.
Definition: PDRmeshArrays.H:73
Foam::boundBox::XDIR
1: x-direction (vector component 0)
Definition: boundBox.H:77
Foam::boundBox::YDIR
2: y-direction (vector component 1)
Definition: boundBox.H:78
polyMesh.H
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
IjkField.H
Foam::PDRmeshArrays::faceDims
labelVector faceDims
The face i-j-k addressing range.
Definition: PDRmeshArrays.H:76
Foam::cmptMin
void cmptMin(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:302
Foam::labelVector
Vector< label > labelVector
Vector of labels.
Definition: labelVector.H:51
Foam::cmptMax
void cmptMax(FieldField< Field, typename FieldField< Field, Type >::cmptType > &cf, const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:253
Foam::PDRmeshArrays::faceOrient
List< direction > faceOrient
For each face, the x/y/z orientation.
Definition: PDRmeshArrays.H:85
Foam::Info
messageStream Info
Information stream (uses stdout - output is on the master only)
Foam::Vector< scalar >::X
Definition: Vector.H:81
Foam::PDRmeshArrays::cellIndex
List< labelVector > cellIndex
For each cell, the corresponding i-j-k address.
Definition: PDRmeshArrays.H:79
PDRblock.H
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::FatalError
error FatalError
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::labelMinMax
MinMax< label > labelMinMax
A label min/max range.
Definition: MinMax.H:113
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::PDRmeshArrays::read
void read(const Time &runTime, const PDRblock &pdrBlock)
Read OpenFOAM mesh and determine i-j-k indices for faces/cells.
PDRmeshArrays.H
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:372
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::boundBox::ZDIR
4: z-direction (vector component 2)
Definition: boundBox.H:79
Foam::direction
uint8_t direction
Definition: direction.H:47
Foam::point
vector point
Point is a vector.
Definition: point.H:43
Foam::PDRmeshArrays::gridPointRelTol
static scalar gridPointRelTol
Relative tolerance when matching grid points. Default = 0.02.
Definition: PDRmeshArrays.H:70
createPolyMesh.H
Foam::VectorSpace< Vector< label >, label, 3 >::nComponents
static constexpr direction nComponents
Number of components in this vector space.
Definition: VectorSpace.H:101