meshRefinementTemplates.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-2015 OpenFOAM Foundation
9  Copyright (C) 2019-2023 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 "meshRefinement.H"
30 #include "fvMesh.H"
31 #include "globalIndex.H"
32 #include "syncTools.H"
33 
34 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 
36 template<class T>
38 (
39  const labelList& newToOld,
40  const T& nullValue,
41  List<T>& elems
42 )
43 {
44  List<T> newElems(newToOld.size(), nullValue);
45 
46  forAll(newElems, i)
47  {
48  const label oldI = newToOld[i];
49 
50  if (oldI >= 0)
51  {
52  newElems[i] = elems[oldI];
53  }
54  }
55 
56  elems.transfer(newElems);
57 }
58 
59 
60 template<class T>
62 (
63  const bitSet& isMasterElem,
64  const UList<T>& values
65 )
66 {
67  if (values.size() != isMasterElem.size())
68  {
70  << "Number of elements in list " << values.size()
71  << " does not correspond to number of elements in isMasterElem "
72  << isMasterElem.size()
73  << exit(FatalError);
74  }
75 
76  T sum = T(Zero);
77  label n = 0;
78 
79  forAll(values, i)
80  {
81  if (isMasterElem.test(i))
82  {
83  sum += values[i];
84  n++;
85  }
86  }
87 
88  reduce(sum, sumOp<T>());
89  reduce(n, sumOp<label>());
90 
91  if (n > 0)
92  {
93  return sum/n;
94  }
95  else
96  {
97  return pTraits<T>::max;
98  }
99 }
100 
101 
102 // Compare two lists over all boundary faces
103 template<class T>
105 (
106  const scalar tol,
107  const string& msg,
108  const UList<T>& faceData,
109  const UList<T>& syncedFaceData
110 ) const
111 {
112  const label nBFaces = mesh_.nBoundaryFaces();
113 
114  if (faceData.size() != nBFaces || syncedFaceData.size() != nBFaces)
115  {
117  << "Boundary faces:" << nBFaces
118  << " faceData:" << faceData.size()
119  << " syncedFaceData:" << syncedFaceData.size()
120  << abort(FatalError);
121  }
122 
123  const polyBoundaryMesh& patches = mesh_.boundaryMesh();
124 
125  forAll(patches, patchi)
126  {
127  const polyPatch& pp = patches[patchi];
128 
129  label bFacei = pp.start() - mesh_.nInternalFaces();
130 
131  forAll(pp, i)
132  {
133  const T& data = faceData[bFacei];
134  const T& syncData = syncedFaceData[bFacei];
135 
136  if (mag(data - syncData) > tol)
137  {
138  label facei = pp.start()+i;
139 
141  << msg
142  << "patchFace:" << i
143  << " face:" << facei
144  << " fc:" << mesh_.faceCentres()[facei]
145  << " patch:" << pp.name()
146  << " faceData:" << data
147  << " syncedFaceData:" << syncData
148  << " diff:" << mag(data - syncData)
149  << abort(FatalError);
150  }
151 
152  bFacei++;
153  }
154  }
155 }
156 
157 
158 // Print list sorted by coordinates. Used for comparing non-parallel v.s.
159 // parallel operation
160 template<class T>
162 (
163  const UList<point>& points,
164  const UList<T>& data
165 )
166 {
168 
170  globalPoints.gather
171  (
172  points,
173  allPoints,
176  );
177 
178  List<T> allData;
179  globalPoints.gather
180  (
181  data,
182  allData,
185  );
186 
187 
188  scalarField magAllPoints(mag(allPoints-point(-0.317, 0.117, 0.501)));
189 
190  labelList visitOrder(sortedOrder(magAllPoints));
191  for (const label allPointi : visitOrder)
192  {
193  Info<< allPoints[allPointi] << " : " << allData[allPointi]
194  << endl;
195  }
196 }
197 
198 
199 template<class GeoField>
200 void Foam::meshRefinement::addPatchFields
201 (
202  fvMesh& mesh,
203  const word& patchFieldType
204 )
205 {
206  // Field order is irrelevant...
207  for (GeoField& fld : mesh.objectRegistry::objects<GeoField>())
208  {
209  auto& bfld = fld.boundaryFieldRef();
210 
211  const label newPatchi = bfld.size();
212  bfld.resize(newPatchi+1);
213 
214  bfld.set
215  (
216  newPatchi,
218  (
219  patchFieldType,
220  mesh.boundary()[newPatchi],
221  fld.internalField()
222  )
223  );
224  }
225 }
226 
227 
228 template<class GeoField>
229 void Foam::meshRefinement::reorderPatchFields
230 (
231  fvMesh& mesh,
232  const labelList& oldToNew
233 )
234 {
235  // Field order is irrelevant...
236  for (GeoField& fld : mesh.objectRegistry::objects<GeoField>())
237  {
238  fld.boundaryFieldRef().reorder(oldToNew);
239  }
240 }
241 
242 
243 template<class EnumContainer>
245 (
246  const EnumContainer& namedEnum,
247  const wordList& words
248 )
249 {
250  int flags = 0;
251 
252  for (const word& w : words)
253  {
254  flags |= namedEnum[w];
255  }
257  return flags;
258 }
259 
260 
261 template<class Type>
263 (
264  const polyMesh& mesh,
265  const bitSet& isMasterEdge,
266  const labelList& meshPoints,
267  const edgeList& edges,
268  const scalarField& edgeWeights,
269  const Field<Type>& pointData,
271 )
272 {
273  if
274  (
275  edges.size() != isMasterEdge.size()
276  || edges.size() != edgeWeights.size()
277  || meshPoints.size() != pointData.size()
278  )
279  {
281  << "Inconsistent sizes for edge or point data:"
282  << " isMasterEdge:" << isMasterEdge.size()
283  << " edgeWeights:" << edgeWeights.size()
284  << " edges:" << edges.size()
285  << " pointData:" << pointData.size()
286  << " meshPoints:" << meshPoints.size()
287  << abort(FatalError);
288  }
289 
290  sum.setSize(meshPoints.size());
291  sum = Type(Zero);
292 
293  forAll(edges, edgeI)
294  {
295  if (isMasterEdge.test(edgeI))
296  {
297  const edge& e = edges[edgeI];
298 
299  scalar eWeight = edgeWeights[edgeI];
300 
301  label v0 = e[0];
302  label v1 = e[1];
303 
304  sum[v0] += eWeight*pointData[v1];
305  sum[v1] += eWeight*pointData[v0];
306  }
307  }
308 
310  (
311  mesh,
312  meshPoints,
313  sum,
314  plusEqOp<Type>(),
315  Type(Zero) // null value
316  );
317 }
318 
319 
320 template<class Type>
322 (
323  const dictionary& dict,
324  const word& keyword,
325  const bool noExit,
326  enum keyType::option matchOpt,
327  const Type& deflt
328 )
329 {
330  // If noExit, emit FatalIOError message without exiting
332  (
333  noExit
335  );
336 
337  Type val(deflt);
338 
339  if (!dict.readEntry(keyword, val, matchOpt, readOpt))
340  {
342  << "Entry '" << keyword << "' not found in dictionary "
343  << dict.name() << nl;
344  }
345 
346  return val;
347 }
348 
349 
350 // ************************************************************************* //
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1)
"blocking" : (MPI_Bsend, MPI_Recv)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
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:129
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
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:50
static Type get(const dictionary &dict, const word &keyword, const bool noExit, enum keyType::option matchOpt=keyType::REGEX, const Type &deflt=Zero)
Wrapper around dictionary::get which does not exit.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1229
const fileName & name() const noexcept
The dictionary name.
Definition: dictionaryI.H:41
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, IOobjectOption::readOption readOpt=IOobjectOption::MUST_READ) const
Find entry and assign to T val. FatalIOError if it is found and the number of tokens is incorrect...
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
static void updateList(const labelList &newToOld, const T &nullValue, List< T > &elems)
Helper: reorder list according to map.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:61
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
dynamicFvMesh & mesh
const pointField & points
A class for handling words, derived from Foam::string.
Definition: word.H:63
Reading is optional [identical to LAZY_READ].
void testSyncBoundaryFaceList(const scalar mergeDistance, const string &, const UList< T > &, const UList< T > &) const
Compare two lists over all boundary faces.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
static void syncPointList(const polyMesh &mesh, List< T > &pointValues, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
bool test(const label pos) const
Test for True value at specified position, never auto-vivify entries.
Definition: bitSet.H:326
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:105
static int readFlags(const EnumContainer &namedEnum, const wordList &words)
Helper: convert wordList into bit pattern using provided Enum.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
const volScalarField & T
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
List< word > wordList
List of word.
Definition: fileName.H:59
Calculates points shared by more than two processor patches or cyclic patches.
Definition: globalPoints.H:98
static void collectAndPrint(const UList< point > &points, const UList< T > &data)
Print list according to (collected and) sorted coordinate.
vector point
Point is a vector.
Definition: point.H:37
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:59
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
const polyBoundaryMesh & patches
option
Enumeration for the data type and search/match modes (bitmask)
Definition: keyType.H:79
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)
const fvBoundaryMesh & boundary() const noexcept
Return reference to boundary mesh.
Definition: fvMesh.H:395
label n
tmp< pointField > allPoints(const Triangulation &t)
Extract all points in vertex-index order.
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
List< label > labelList
A List of labels.
Definition: List.H:62
static T gAverage(const bitSet &isMasterElem, const UList< T > &values)
Helper: calculate average.
static void weightedSum(const polyMesh &mesh, const bitSet &isMasterEdge, const labelList &meshPoints, const edgeList &edges, const scalarField &edgeWeights, const Field< Type > &data, Field< Type > &sum)
Helper: weighted sum (over all subset of mesh points) by.
label size() const noexcept
Number of entries.
Definition: PackedList.H:371
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127
readOption
Enumeration defining read preferences.