uniformBin.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) 2021-2022 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 "uniformBin.H"
30 
31 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 namespace binModels
36 {
39 }
40 }
41 
42 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43 
45 {
47 
48  // Determine extents of patches in a given coordinate system
49  vector geomMin(GREAT, GREAT, GREAT);
50  vector geomMax(-GREAT, -GREAT, -GREAT);
51 
52  for (const label patchi : patchSet_)
53  {
54  const polyPatch& pp = pbm[patchi];
55  const vectorField ppcs(coordSysPtr_->localPosition(pp.faceCentres()));
56 
57  for (direction i = 0; i < vector::nComponents; ++i)
58  {
59  geomMin[i] = min(min(ppcs.component(i)), geomMin[i]);
60  geomMax[i] = max(max(ppcs.component(i)), geomMax[i]);
61  }
62  }
63 
64  for (const label zonei : cellZoneIDs_)
65  {
66  const cellZone& cZone = mesh_.cellZones()[zonei];
67  const vectorField d
68  (
69  coordSysPtr_->localPosition(vectorField(mesh_.C(), cZone))
70  );
71 
72  for (direction i = 0; i < vector::nComponents; ++i)
73  {
74  geomMin[i] = min(min(d.component(i)), geomMin[i]);
75  geomMax[i] = max(max(d.component(i)), geomMax[i]);
76  }
77  }
78 
79  reduce(geomMin, minOp<vector>());
80  reduce(geomMax, maxOp<vector>());
81 
82  for (direction i = 0; i < vector::nComponents; ++i)
83  {
84  // Slightly boost max so that region of interest is fully within bounds
85  geomMax[i] = 1.0001*(geomMax[i] - geomMin[i]) + geomMin[i];
86 
87  // Use geometry limits if not specified by the user
88  if (binMinMax_[i][0] == GREAT) binMinMax_[i][0] = geomMin[i];
89  if (binMinMax_[i][1] == GREAT) binMinMax_[i][1] = geomMax[i];
90 
91  if (binMinMax_[i][0] > binMinMax_[i][1])
92  {
94  << "Max bounds must be greater than min bounds" << nl
95  << " direction = " << i << nl
96  << " min = " << binMinMax_[i][0] << nl
97  << " max = " << binMinMax_[i][1] << nl
98  << exit(FatalError);
99  }
100 
101  //- Compute bin widths in binning directions
102  binW_[i] = (binMinMax_[i][1] - binMinMax_[i][0])/scalar(nBins_[i]);
103 
104  if (binW_[i] <= 0)
105  {
107  << "Bin widths must be greater than zero" << nl
108  << " direction = " << i << nl
109  << " min bound = " << binMinMax_[i][0] << nl
110  << " max bound = " << binMinMax_[i][1] << nl
111  << " bin width = " << binW_[i]
112  << exit(FatalError);
113  }
114  }
117 }
118 
119 
121 {
122  labelList binIndices(d.size(), -1);
123 
124  forAll(d, i)
125  {
126  // Avoid elements outside of the bin
127  bool faceInside = true;
128  for (direction j = 0; j < vector::nComponents; ++j)
129  {
130  if (d[i][j] < binMinMax_[j][0] || d[i][j] > binMinMax_[j][1])
131  {
132  faceInside = false;
133  break;
134  }
135  }
136 
137  if (faceInside)
138  {
139  // Find the bin division corresponding to the element
140  Vector<label> n(Zero);
141  for (direction j = 0; j < vector::nComponents; ++j)
142  {
143  n[j] = floor((d[i][j] - binMinMax_[j][0])/binW_[j]);
144  n[j] = min(max(n[j], 0), nBins_[j] - 1);
145  }
146 
147  // Order: (e1, e2, e3), the first varies the fastest
148  binIndices[i] = n[0] + nBins_[0]*n[1] + nBins_[0]*nBins_[1]*n[2];
149  }
150  else
151  {
152  binIndices[i] = -1;
153  }
154  }
156  return binIndices;
157 }
158 
159 
161 {
162  faceToBin_.setSize(mesh_.nBoundaryFaces());
163  faceToBin_ = -1;
164 
165  forAllIters(patchSet_, iter)
166  {
167  const polyPatch& pp = mesh_.boundaryMesh()[iter()];
168  const label i0 = pp.start() - mesh_.nInternalFaces();
169 
170  SubList<label>(faceToBin_, pp.size(), i0) =
171  binAddr(coordSysPtr_->localPosition(pp.faceCentres()));
172  }
173 
174  cellToBin_.setSize(mesh_.nCells());
175  cellToBin_ = -1;
176 
177  for (const label zonei : cellZoneIDs_)
178  {
179  const cellZone& cZone = mesh_.cellZones()[zonei];
180  labelList bins
181  (
182  binAddr(coordSysPtr_->localPosition(vectorField(mesh_.C(), cZone)))
183  );
184 
185  forAll(cZone, i)
186  {
187  const label celli = cZone[i];
188  cellToBin_[celli] = bins[i];
189  }
190  }
191 }
193 
194 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
195 
197 (
198  const dictionary& dict,
199  const fvMesh& mesh,
200  const word& outputPrefix
201 )
202 :
203  binModel(dict, mesh, outputPrefix),
204  nBins_(Zero),
205  binW_(Zero),
206  binMinMax_
207  (
208  vector2D(GREAT, GREAT),
209  vector2D(GREAT, GREAT),
210  vector2D(GREAT, GREAT)
211  )
212 {
213  read(dict);
214 }
215 
216 
217 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
218 
220 {
221  if (!binModel::read(dict))
222  {
223  return false;
224  }
225 
226  Info<< " Activating a set of uniform bins" << endl;
227 
228  const dictionary& binDict = dict.subDict("binData");
229 
230  nBins_ = binDict.get<Vector<label>>("nBin");
231 
232  for (const label n : nBins_)
233  {
234  nBin_ *= n;
235  }
236 
237  if (nBin_ <= 0)
238  {
239  FatalIOErrorInFunction(binDict)
240  << "Number of bins must be greater than zero" << nl
241  << " e1 bins = " << nBins_[0] << nl
242  << " e2 bins = " << nBins_[1] << nl
243  << " e3 bins = " << nBins_[2]
244  << exit(FatalIOError);
245  }
246 
247  Info<< " - Employing:" << nl
248  << " " << nBins_[0] << " e1 bins," << nl
249  << " " << nBins_[1] << " e2 bins," << nl
250  << " " << nBins_[2] << " e3 bins"
251  << endl;
252 
253  cumulative_ = binDict.getOrDefault<bool>("cumulative", false);
254  Info<< " - cumulative : " << cumulative_ << endl;
255  Info<< " - decomposePatchValues : " << decomposePatchValues_ << endl;
256 
257  if (binDict.found("minMax"))
258  {
259  const dictionary& minMaxDict = binDict.subDict("minMax");
260 
261  for (direction i = 0; i < vector::nComponents; ++i)
262  {
263  const word ei("e" + Foam::name(i));
264 
265  if (minMaxDict.readIfPresent(ei, binMinMax_[i]))
266  {
267  Info<< " - " << ei << " min : "
268  << binMinMax_[i][0] << nl
269  << " - " << ei << " max : "
270  << binMinMax_[i][1] << endl;
271  }
272  }
273  }
274  Info<< endl;
275 
276  initialise();
278  return true;
279 }
280 
281 
283 {
284  forAll(fieldNames_, i)
285  {
286  const bool ok =
287  processField<scalar>(i)
288  || processField<vector>(i)
289  || processField<sphericalTensor>(i)
290  || processField<symmTensor>(i)
291  || processField<tensor>(i);
292 
293  if (!ok)
294  {
296  << "Unable to find field " << fieldNames_[i]
297  << endl;
298  }
299  }
301  writtenHeader_ = true;
302 }
303 
306 {}
307 
308 
310 {
311  setBinsAddressing();
312 }
313 
314 
315 // ************************************************************************* //
Vector< vector2D > binMinMax_
Min-max bounds of bins in binning directions.
Definition: uniformBin.H:178
const polyBoundaryMesh & pbm
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
uniformBin(const dictionary &dict, const fvMesh &mesh, const word &outputPrefix)
Construct from components.
Definition: uniformBin.C:192
Calculates binned data in multiple segments according to a specified Cartesian or cylindrical coordin...
Definition: uniformBin.H:157
uint8_t direction
Definition: direction.H:48
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
const fvMesh & mesh_
Reference to the mesh.
Definition: binModel.H:68
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:120
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:578
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
virtual void initialise()
Initialise bin properties.
Definition: uniformBin.C:37
virtual void updateMesh(const mapPolyMesh &mpm)
Update for changes of mesh.
Definition: uniformBin.C:300
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T. FatalIOError if not found, or if the number of tokens is incorrect.
labelHashSet patchSet_
Indices of operand patches.
Definition: binModel.H:94
defineTypeNameAndDebug(singleDirectionUniformBin, 0)
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:453
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
Definition: mapPolyMesh.H:157
Macros for easy insertion into run-time selection tables.
bool found(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry (const access) with the given keyword.
Definition: dictionaryI.H:100
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
Base class for bin models to handle general bin characteristics.
Definition: binModel.H:57
virtual void movePoints(const polyMesh &mesh)
Update for changes of mesh.
Definition: uniformBin.C:304
A List obtained as a section of another List.
Definition: SubList.H:50
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Definition: polyMesh.H:584
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual labelList binAddr(const vectorField &d) const
Return list of bin indices corresponding to positions given by d.
Definition: uniformBin.C:115
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:329
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
autoPtr< coordinateSystem > coordSysPtr_
Local coordinate system of bins.
Definition: binModel.H:84
vector binW_
Equidistant bin widths in binning directions.
Definition: uniformBin.H:173
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
addToRunTimeSelectionTable(binModel, singleDirectionUniformBin, dictionary)
A subset of mesh cells.
Definition: cellZone.H:58
#define WarningInFunction
Report a warning using Foam::Warning.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:607
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:79
virtual bool read(const dictionary &dict)
Read the dictionary.
Definition: uniformBin.C:214
virtual bool read(const dictionary &dict)
Read the dictionary.
Definition: binModel.C:129
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:654
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
messageStream Info
Information stream (stdout output on master, null elsewhere)
label n
Field< vector > vectorField
Specialisation of Field<T> for vector.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:73
const volVectorField & C() const
Return cell centres as volVectorField.
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a T, or return the given default value. FatalIOError if it is found and the number of...
labelList cellZoneIDs_
Indices of operand cell zones.
Definition: binModel.H:104
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:69
virtual void setBinsAddressing()
Set/cache the bin addressing.
Definition: uniformBin.C:155
Vector< label > nBins_
Numbers of bins in binning directions.
Definition: uniformBin.H:168
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Namespace for OpenFOAM.
virtual void apply()
Apply bins.
Definition: uniformBin.C:277
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:133