cellTable.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-2024 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 "cellTable.H"
30 #include "IOMap.H"
31 #include "polyMesh.H"
32 #include "OFstream.H"
33 #include "predicates.H"
34 #include "ListOps.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 static const char* const defaultMaterial_ = "fluid";
39 
40 
41 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 template<class MatchPredicate>
47 static Map<word> names_impl
48 (
49  const Map<dictionary>& input,
50  const MatchPredicate& nameMatcher
51 )
52 {
54  output.reserve(input.size());
55 
56  forAllConstIters(input, iter)
57  {
58  word lookupName;
59  if (!iter().readIfPresent("Label", lookupName))
60  {
61  lookupName = "cellTable_" + Foam::name(iter.key());
62  }
63 
64  if (nameMatcher(lookupName))
65  {
66  output.emplace(iter.key(), std::move(lookupName));
67  }
68  }
69 
70  return output;
71 }
72 
73 } // End namespace Foam
74 
75 
76 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
77 
78 void Foam::cellTable::addDefaults()
79 {
80  forAllIters(*this, iter)
81  {
82  if (!iter().found("MaterialType"))
83  {
84  iter().add("MaterialType", word(defaultMaterial_));
85  }
86  }
87 }
88 
89 
90 void Foam::cellTable::setEntry
91 (
92  const label id,
93  const word& key,
94  const word& value
95 )
96 {
98  dict.add(key, value);
99 
100  iterator iter = find(id);
101  if (iter.good())
102  {
103  iter().merge(dict);
104  }
105  else
106  {
107  insert(id, dict);
108  }
109 }
110 
111 
112 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
113 
115 (
116  const objectRegistry& obr,
117  const word& name,
118  const fileName& instance
119 )
120 {
121  readDict(obr, name, instance);
122 }
123 
124 
125 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
126 
127 Foam::label Foam::cellTable::maxIndex() const
128 {
129  label maxId = -1;
130  forAllConstIters(*this, iter)
131  {
132  if (maxId < iter.key())
133  {
134  maxId = iter.key();
135  }
136  }
137 
138  return maxId;
139 }
140 
141 
142 Foam::label Foam::cellTable::push_back(const dictionary& dict)
143 {
144  label maxId = this->maxIndex();
145 
146  insert(++maxId, dict);
147  return maxId;
148 }
149 
152 {
153  return names_impl(*this, predicates::always{});
154 }
155 
158 {
159  return names_impl(*this, patterns);
160 }
161 
162 
163 Foam::word Foam::cellTable::name(const label id) const
164 {
165  word lookupName;
166 
167  const auto iter = cfind(id);
168  if (iter.good())
169  {
170  iter.val().readIfPresent("Label", lookupName);
171  }
172 
173  if (lookupName.empty() && id >= 0)
174  {
175  lookupName = "cellTable_" + Foam::name(id);
176  }
177 
178  return lookupName;
179 }
180 
181 
182 Foam::label Foam::cellTable::findIndex(const word& name) const
183 {
184  if (name.empty())
185  {
186  return -1;
187  }
188 
189  forAllConstIters(*this, iter)
190  {
191  const auto& dict = iter.val();
192 
193  word lookupName;
194  if (dict.readIfPresent("Label", lookupName) && (lookupName == name))
195  {
196  return iter.key();
197  }
198  }
199 
200  return -1;
201 }
202 
203 
205 {
206  Map<word> output;
207  output.reserve(size());
208 
209  forAllConstIters(*this, iter)
210  {
211  word lookupType;
212  if (!iter().readIfPresent("MaterialType", lookupType))
213  {
214  lookupType = defaultMaterial_;
215  }
216 
217  output.emplace(iter.key(), std::move(lookupType));
218  }
219 
220  return output;
221 }
222 
223 
225 {
226  Map<word> output;
227  output.reserve(size());
228 
229  forAllConstIters(*this, iter)
230  {
231  const dictionary& dict = iter.val();
232 
233  if
234  (
235  matl
236  == dict.getOrDefault<word>("MaterialType", defaultMaterial_)
237  )
238  {
239  word lookupName;
240  if (dict.readIfPresent("Label", lookupName))
241  {
242  lookupName = "cellTable_" + Foam::name(iter.key());
243  }
244 
245  output.emplace(iter.key(), std::move(lookupName));
246  }
247  }
248 
249  return output;
250 }
251 
254 {
255  return selectType("fluid");
256 }
257 
260 {
261  return selectType("solid");
262 }
263 
266 {
267  return selectType("shell");
268 }
269 
271 void Foam::cellTable::setMaterial(const label id, const word& matlType)
272 {
273  setEntry(id, "MaterialType", matlType);
274 }
275 
277 void Foam::cellTable::setName(const label id, const word& name)
278 {
279  setEntry(id, "Label", name);
280 }
281 
282 
283 void Foam::cellTable::setName(const label id)
284 {
285  iterator iter = find(id);
286 
287  if (!iter.good() || !iter().found("Label"))
288  {
289  setName(id, "cellTable_" + Foam::name(id));
290  }
291 }
292 
293 
295 (
296  const objectRegistry& obr,
297  const word& name,
298  const fileName& instance
299 )
300 {
301  clear();
302 
303  // read constant/dictName
304  IOMap<dictionary> ioObj
305  (
306  IOobject
307  (
308  name,
309  instance,
310  obr,
314  )
315  );
316 
317  if (ioObj.headerOk())
318  {
319  *this = ioObj;
320  addDefaults();
321  }
322  else
323  {
324  Info<< "no constant/cellTable information available" << endl;
325  }
326 }
327 
328 
330 (
331  const objectRegistry& obr,
332  const word& name,
333  const fileName& instance
334 ) const
335 {
336  // write constant/dictName
337  IOMap<dictionary> ioObj
338  (
339  IOobject
340  (
341  name,
342  instance,
343  obr,
347  )
348  );
349 
350  ioObj.note() =
351  "persistent data for third-party mesh <-> OpenFOAM translation";
352 
353  Info<< "Writing " << ioObj.name() << " to "
354  << ioObj.objectRelPath() << endl;
355 
356  OFstream os(ioObj.objectPath());
357  ioObj.writeHeader(os);
358  os << *this;
361 }
362 
363 
364 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
365 
367 {
369  addDefaults();
370 }
371 
372 
374 {
376  addDefaults();
377 }
378 
379 
381 {
382  Map<dictionary> zoneDict;
383 
384  // create cellTableId and cellTable based on cellZones
385  label nZoneCells = 0;
386 
387  wordList zoneNames = mesh.cellZones().names();
388  label unZonedType = zoneNames.size() + 1;
389 
390  // do cell zones
391  forAll(mesh.cellZones(), zoneI)
392  {
393  const cellZone& cZone = mesh.cellZones()[zoneI];
394  nZoneCells += cZone.size();
395 
397  dict.add("Label", zoneNames[zoneI]);
398  zoneDict.insert(zoneI + 1, dict);
399  }
400 
401  // collect unzoned cells
402  // special case: no zones at all - do entire mesh
403  if (nZoneCells == 0)
404  {
405  zoneDict.clear();
406  unZonedType = 1;
407  }
408 
409  if (mesh.nCells() > nZoneCells)
410  {
411  zoneDict.insert
412  (
413  unZonedType,
414  dictionary(IStringStream("Label cells;")())
415  );
416  }
417 
418  Map<dictionary>::operator=(zoneDict);
419  addDefaults();
420 }
421 
422 
423 // * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
424 
426 (
427  polyMesh& mesh,
428  const labelList& tableIds
429 ) const
430 {
431  // From cellTable ID => zone index
432  Map<label> typeToZone;
433 
434  // Name per zone (not cellTableID)
435  wordList zoneNames;
436 
437  {
438  // The cellTable ID => zone name
439  Map<word> namesLookup = this->names();
440 
441  zoneNames.resize(namesLookup.size());
442  typeToZone.reserve(namesLookup.size());
443 
444  // Linear indexing
445  label zonei = 0;
446  for (const label id : namesLookup.sortedToc())
447  {
448  typeToZone(id) = zonei;
449  zoneNames[zonei] = namesLookup[id];
450  ++zonei;
451  }
452  }
453 
454 
455  List<DynamicList<label>> zoneCells(zoneNames.size());
456 
457  forAll(tableIds, celli)
458  {
459  label zonei = typeToZone.lookup(tableIds[celli], -1);
460  if (zonei >= 0)
461  {
462  zoneCells[zonei].push_back(celli);
463  }
464  }
465 
466  // Track which zones were actually used
467  DynamicList<label> zoneUsed(zoneCells.size());
468 
469  forAll(zoneCells, zonei)
470  {
471  zoneCells[zonei].shrink();
472  if (!zoneCells[zonei].empty())
473  {
474  zoneUsed.push_back(zonei);
475  }
476  }
477 
478  const label nZonesUsed = zoneUsed.size();
479 
480  cellZoneMesh& czMesh = mesh.cellZones();
481 
482  czMesh.clear();
483  if (nZonesUsed <= 1)
484  {
485  Info<< "cellZones not used" << endl;
486  return;
487  }
488  czMesh.resize(nZonesUsed);
489 
490  forAll(zoneUsed, zonei)
491  {
492  const label origZonei = zoneUsed[zonei];
493 
494  Info<< "cellZone " << zonei
495  << " (size: " << zoneCells[origZonei].size()
496  << ") name: " << zoneNames[origZonei] << endl;
497 
498  czMesh.set
499  (
500  zonei,
501  new cellZone
502  (
503  zoneNames[origZonei],
504  zoneCells[origZonei],
505  zonei,
506  czMesh
507  )
508  );
509  }
510  czMesh.writeOpt(IOobject::AUTO_WRITE);
511 }
512 
513 
514 void Foam::cellTable::combine(const dictionary& mapDict, labelList& tableIds)
515 {
516  if (mapDict.empty())
517  {
518  return;
519  }
520 
521  Map<word> origNames(this->names());
522  labelList mapping(identity(this->maxIndex() + 1));
523 
524  bool remap = false;
525  for (const entry& dEntry : mapDict)
526  {
527  wordRes patterns(dEntry.stream());
528 
529  // find all matches
530  Map<word> matches;
531  forAllConstIters(origNames, namesIter)
532  {
533  if (patterns.match(namesIter()))
534  {
535  matches.insert(namesIter.key(), namesIter());
536  }
537  }
538 
539  if (matches.size())
540  {
541  label targetId = this->findIndex(dEntry.keyword());
542 
543  Info<< "combine cellTable: " << dEntry.keyword();
544  if (targetId < 0)
545  {
546  // not found - reuse 1st element but with different name
547  targetId = min(matches.toc());
548  operator[](targetId).set("Label", dEntry.keyword());
549 
550  Info<< " = (";
551  }
552  else
553  {
554  Info<< " += (";
555  }
556 
557 
558  // the mapping and name for targetId is already okay
559  matches.erase(targetId);
560  origNames.erase(targetId);
561 
562  // remove matched names, leaving targetId on 'this'
563  this->erase(matches);
564  origNames.erase(matches);
565 
566  forAllConstIters(matches, matchIter)
567  {
568  mapping[matchIter.key()] = targetId;
569  Info<< " " << matchIter();
570  }
571  Info<< " )" << endl;
572 
573  remap = true;
574  }
575  }
576 
577  if (remap)
578  {
579  inplaceRenumber(mapping, tableIds);
580  }
581 }
582 
583 // ************************************************************************* //
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:827
dictionary dict
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
List< word > names(const UPtrList< T > &list, const UnaryMatchPredicate &matcher)
List of names generated by calling name() for each list item and filtered for matches.
void clear()
Clear the zones.
Definition: ZoneMesh.C:931
Map< word > shells() const
Return a Map of (id => name) for shells.
Definition: cellTable.C:258
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
srcOptions erase("case")
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
static const char *const defaultMaterial_
Definition: cellTable.C:31
bool found(const Key &key) const
Same as contains()
Definition: HashTable.H:1370
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
void setName(const label, const word &)
Assign name.
Definition: cellTable.C:270
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Map< word > solids() const
Return a Map of (id => name) for solids.
Definition: cellTable.C:252
entry * add(entry *entryPtr, bool mergeEntry=false)
Add a new entry.
Definition: dictionary.C:625
Ignore writing from objectRegistry::writeObject()
void setMaterial(const label, const word &)
Assign material Type.
Definition: cellTable.C:264
void operator=(const cellTable &)
Assignment.
Definition: cellTable.C:359
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void writeDict(const objectRegistry &, const word &name="cellTable", const fileName &instance="constant") const
Write constant/cellTable for later reuse.
Definition: cellTable.C:323
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:152
label size() const noexcept
The number of elements in table.
Definition: HashTable.H:358
Unary and binary predicates that always return true, useful for templating.
Definition: predicates.H:53
void readDict(const objectRegistry &, const word &name="cellTable", const fileName &instance="constant")
Read constant/cellTable.
Definition: cellTable.C:288
dynamicFvMesh & mesh
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
A class for handling words, derived from Foam::string.
Definition: word.H:63
void clear()
Remove all entries from table.
Definition: HashTable.C:749
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:33
Map< word > names() const
Return the extracted Map of (id => name)
Definition: cellTable.C:144
Map< word > materialTypes() const
Return a Map of (id => fluid|solid|shell)
Definition: cellTable.C:197
Reading is optional [identical to LAZY_READ].
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:336
label maxIndex() const
The max table index, -1 if empty.
Definition: cellTable.C:120
A List of wordRe with additional matching capabilities.
Definition: wordRes.H:53
Map< word > fluids() const
Return a Map of (id => name) for fluids.
Definition: cellTable.C:246
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
The cellTable persistent data saved as a Map<dictionary>.
Definition: cellTable.H:77
label push_back(const dictionary &dict)
Add to the end, return index.
Definition: cellTable.C:135
static Ostream & writeEndDivider(Ostream &os)
Write the standard end file divider.
word name(const label id) const
The &#39;Label&#39; name corresponding to id, or cellTable_ID if not otherwise defined.
Definition: cellTable.C:156
bool readIfPresent(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX) const
Find an entry if present, and assign to T val. FatalIOError if it is found and the number of tokens i...
static Map< word > names_impl(const Map< dictionary > &input, const MatchPredicate &nameMatcher)
OBJstream os(runTime.globalPath()/outputName)
A subset of mesh cells.
Definition: cellZone.H:58
cellTable() noexcept=default
Default construct.
void inplaceRenumber(const labelUList &oldToNew, IntListType &input)
Inplace renumber the values within a list.
const T & lookup(const Key &key, const T &deflt) const
Return hashed entry if it exists, or return the given default.
Definition: HashTableI.H:222
label nCells() const noexcept
Number of mesh cells.
auto key(const Type &t) -> typename std::enable_if< std::is_enum< Type >::value, typename std::underlying_type< Type >::type >::type
Definition: foamGltfBase.H:103
surface1 clear()
List< label > sortedToc() const
The table of contents (the keys) in sorted order.
Definition: HashTable.C:163
void reserve(label numEntries)
Reserve space for at least the specified number of elements (not the number of buckets) and regenerat...
Definition: HashTable.C:736
Nothing to be read.
meshDefDict readIfPresent("polyMeshPatches", polyPatchNames)
Automatically write from objectRegistry::writeObject()
void combine(const dictionary &mapDict, labelList &tableIds)
Combine tableIds together.
Definition: cellTable.C:507
const cellZoneMesh & cellZones() const noexcept
Return cell zone mesh.
Definition: polyMesh.H:679
wordList names() const
A list of the zone names.
Definition: ZoneMesh.C:451
messageStream Info
Information stream (stdout output on master, null elsewhere)
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:44
void addCellZones(polyMesh &, const labelList &tableIds) const
Classify tableIds into cellZones according to the cellTable.
Definition: cellTable.C:419
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:75
label findIndex(const ListType &input, typename ListType::const_reference val, const label start=0)
Deprecated(2017-10) search for first occurrence of the given element.
Definition: ListOps.H:517
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...
List< label > labelList
A List of labels.
Definition: List.H:62
label findIndex(const word &name) const
The index corresponding to entry with &#39;Label&#39; of given name, or -1 if not found.
Definition: cellTable.C:175
void operator=(const this_type &rhs)
Copy assignment.
Definition: Map.H:155
Map< word > selectType(const word &materialType) const
Return the extracted Map of (id => name) for materialType (fluid | solid | shell) ...
Definition: cellTable.C:217
Do not request registration (bool: false)
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with the type cellZone.
Namespace for OpenFOAM.
forAllConstIters(mixture.phases(), phase)
Definition: pEqn.H:28
A HashTable to objects of type <T> with a label key.