ZoneMesh.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 | Copyright (C) 2011-2016 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "ZoneMesh.H"
27 #include "entry.H"
28 #include "demandDrivenData.H"
29 #include "stringListOps.H"
30 #include "Pstream.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 template<class ZoneType, class MeshType>
36 {
37  // It is an error to attempt to recalculate cellEdges
38  // if the pointer is already set
39  if (zoneMapPtr_)
40  {
42  << "zone map already calculated"
43  << abort(FatalError);
44  }
45  else
46  {
47  // Count number of objects in all zones
48  label nObjects = 0;
49 
50  forAll(*this, zoneI)
51  {
52  nObjects += this->operator[](zoneI).size();
53  }
54 
55  zoneMapPtr_ = new Map<label>(2*nObjects);
56  Map<label>& zm = *zoneMapPtr_;
57 
58  // Fill in objects of all zones into the map. The key is the global
59  // object index and the result is the zone index
60  forAll(*this, zoneI)
61  {
62  const labelList& zoneObjects = this->operator[](zoneI);
63 
64  forAll(zoneObjects, objI)
65  {
66  zm.insert(zoneObjects[objI], zoneI);
67  }
68  }
69  }
70 }
71 
72 
73 template<class ZoneType, class MeshType>
75 {
76  if
77  (
78  readOpt() == IOobject::MUST_READ
79  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
80  || (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
81  )
82  {
83  if (readOpt() == IOobject::MUST_READ_IF_MODIFIED)
84  {
86  << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
87  << " does not support automatic rereading."
88  << endl;
89  }
90 
91  PtrList<ZoneType>& zones = *this;
92 
93  // Read zones
94  Istream& is = readStream(typeName);
95 
96  PtrList<entry> patchEntries(is);
97  zones.setSize(patchEntries.size());
98 
99  forAll(zones, zoneI)
100  {
101  zones.set
102  (
103  zoneI,
105  (
106  patchEntries[zoneI].keyword(),
107  patchEntries[zoneI].dict(),
108  zoneI,
109  *this
110  )
111  );
112  }
113 
114  // Check state of IOstream
115  is.check
116  (
117  "ZoneMesh::ZoneMesh"
118  "(const IOobject&, const MeshType&)"
119  );
120 
121  close();
122 
123  return true;
124  }
125  else
126  {
127  // Nothing read
128  return false;
129  }
130 }
131 
132 
133 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
134 
135 template<class ZoneType, class MeshType>
137 (
138  const IOobject& io,
139  const MeshType& mesh
140 )
141 :
143  regIOobject(io),
144  mesh_(mesh),
145  zoneMapPtr_(nullptr)
146 {
147  read();
148 }
149 
150 
151 template<class ZoneType, class MeshType>
153 (
154  const IOobject& io,
155  const MeshType& mesh,
156  const label size
157 )
158 :
159  PtrList<ZoneType>(size),
160  regIOobject(io),
161  mesh_(mesh),
162  zoneMapPtr_(nullptr)
163 {
164  // Optionally read contents, otherwise keep size
165  read();
166 }
167 
168 
169 template<class ZoneType, class MeshType>
171 (
172  const IOobject& io,
173  const MeshType& mesh,
174  const PtrList<ZoneType>& pzm
175 )
176 :
178  regIOobject(io),
179  mesh_(mesh),
180  zoneMapPtr_(nullptr)
181 {
182  if (!read())
183  {
184  // Nothing read. Use supplied zones
185  PtrList<ZoneType>& zones = *this;
186  zones.setSize(pzm.size());
187  forAll(zones, zoneI)
188  {
189  zones.set(zoneI, pzm[zoneI].clone(*this).ptr());
190  }
191  }
192 }
193 
194 
195 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
196 
197 template<class ZoneType, class MeshType>
199 {
200  clearAddressing();
201 }
202 
203 
204 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
205 
206 template<class ZoneType, class MeshType>
209 {
210  if (!zoneMapPtr_)
211  {
212  calcZoneMap();
213  }
214 
215  return *zoneMapPtr_;
216 }
217 
218 
219 template<class ZoneType, class MeshType>
221 (
222  const label objectIndex
223 ) const
224 {
225  const Map<label>& zm = zoneMap();
226  Map<label>::const_iterator zmIter = zm.find(objectIndex);
227 
228  if (zmIter == zm.end())
229  {
230  return -1;
231  }
232  else
233  {
234  return zmIter();
235  }
236 }
237 
238 
239 template<class ZoneType, class MeshType>
241 {
242  const PtrList<ZoneType>& zones = *this;
243 
244  wordList lst(zones.size());
245 
246  forAll(zones, zoneI)
247  {
248  lst[zoneI] = zones[zoneI].type();
249  }
250 
251  return lst;
252 }
253 
254 
255 template<class ZoneType, class MeshType>
257 {
258  const PtrList<ZoneType>& zones = *this;
259 
260  wordList lst(zones.size());
261 
262  forAll(zones, zoneI)
263  {
264  lst[zoneI] = zones[zoneI].name();
265  }
266 
267  return lst;
268 }
269 
270 
271 template<class ZoneType, class MeshType>
273 (
274  const keyType& key
275 ) const
276 {
277  labelList indices;
278 
279  if (!key.empty())
280  {
281  if (key.isPattern())
282  {
283  indices = findStrings(key, this->names());
284  }
285  else
286  {
287  indices.setSize(this->size());
288  label nFound = 0;
289  forAll(*this, i)
290  {
291  if (key == operator[](i).name())
292  {
293  indices[nFound++] = i;
294  }
295  }
296  indices.setSize(nFound);
297  }
298  }
299 
300  return indices;
301 }
302 
303 
304 template<class ZoneType, class MeshType>
306 (
307  const keyType& key
308 ) const
309 {
310  if (!key.empty())
311  {
312  if (key.isPattern())
313  {
314  labelList indices = this->findIndices(key);
315 
316  // return first element
317  if (!indices.empty())
318  {
319  return indices[0];
320  }
321  }
322  else
323  {
324  forAll(*this, i)
325  {
326  if (key == operator[](i).name())
327  {
328  return i;
329  }
330  }
331  }
332  }
333 
334  // not found
335  return -1;
336 }
337 
338 
339 template<class ZoneType, class MeshType>
341 (
342  const word& zoneName
343 ) const
344 {
345  const PtrList<ZoneType>& zones = *this;
346 
347  forAll(zones, zoneI)
348  {
349  if (zones[zoneI].name() == zoneName)
350  {
351  return zoneI;
352  }
353  }
354 
355  // Zone not found
356  if (debug)
357  {
359  << "Zone named " << zoneName << " not found. "
360  << "List of available zone names: " << names() << endl;
361  }
362 
363  // not found
364  return -1;
365 }
366 
367 
368 template<class ZoneType, class MeshType>
370 (
371  const keyType& key
372 ) const
373 {
374  PackedBoolList lst;
375 
376  const labelList indices = this->findIndices(key);
377  forAll(indices, i)
378  {
379  lst |= static_cast<const labelList&>(this->operator[](indices[i]));
380  }
381 
382  return lst;
383 }
384 
385 
386 template<class ZoneType, class MeshType>
388 {
389  deleteDemandDrivenData(zoneMapPtr_);
390 
391  PtrList<ZoneType>& zones = *this;
392 
393  forAll(zones, zoneI)
394  {
395  zones[zoneI].clearAddressing();
396  }
397 }
398 
399 
400 template<class ZoneType, class MeshType>
402 {
403  clearAddressing();
405 }
406 
407 
408 template<class ZoneType, class MeshType>
410 (
411  const bool report
412 ) const
413 {
414  bool inError = false;
415 
416  const PtrList<ZoneType>& zones = *this;
417 
418  forAll(zones, zoneI)
419  {
420  inError |= zones[zoneI].checkDefinition(report);
421  }
422  return inError;
423 }
424 
425 
426 template<class ZoneType, class MeshType>
428 (
429  const bool report
430 ) const
431 {
432  if (!Pstream::parRun())
433  {
434  return false;
435  }
436 
437 
438  const PtrList<ZoneType>& zones = *this;
439 
440  bool hasError = false;
441 
442  // Collect all names
443  List<wordList> allNames(Pstream::nProcs());
444  allNames[Pstream::myProcNo()] = this->names();
445  Pstream::gatherList(allNames);
446  Pstream::scatterList(allNames);
447 
448  List<wordList> allTypes(Pstream::nProcs());
449  allTypes[Pstream::myProcNo()] = this->types();
450  Pstream::gatherList(allTypes);
451  Pstream::scatterList(allTypes);
452 
453  // Have every processor check but only master print error.
454 
455  for (label proci = 1; proci < allNames.size(); proci++)
456  {
457  if
458  (
459  (allNames[proci] != allNames[0])
460  || (allTypes[proci] != allTypes[0])
461  )
462  {
463  hasError = true;
464 
465  if (debug || (report && Pstream::master()))
466  {
467  Info<< " ***Inconsistent zones across processors, "
468  "processor 0 has zone names:" << allNames[0]
469  << " zone types:" << allTypes[0]
470  << " processor " << proci << " has zone names:"
471  << allNames[proci]
472  << " zone types:" << allTypes[proci]
473  << endl;
474  }
475  }
476  }
477 
478  // Check contents
479  if (!hasError)
480  {
481  forAll(zones, zoneI)
482  {
483  if (zones[zoneI].checkParallelSync(false))
484  {
485  hasError = true;
486 
487  if (debug || (report && Pstream::master()))
488  {
489  Info<< " ***Zone " << zones[zoneI].name()
490  << " of type " << zones[zoneI].type()
491  << " is not correctly synchronised"
492  << " across coupled boundaries."
493  << " (coupled faces are either not both"
494  << " present in set or have same flipmap)" << endl;
495  }
496  }
497  }
498  }
499 
500  return hasError;
501 }
502 
503 
504 template<class ZoneType, class MeshType>
506 {
507  PtrList<ZoneType>& zones = *this;
508 
509  forAll(zones, zoneI)
510  {
511  zones[zoneI].movePoints(p);
512  }
513 }
514 
515 
516 template<class ZoneType, class MeshType>
518 {
519  os << *this;
520  return os.good();
521 }
522 
523 
524 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
525 
526 template<class ZoneType, class MeshType>
528 (
529  const word& zoneName
530 ) const
531 {
532  const label zoneI = findZoneID(zoneName);
533 
534  if (zoneI < 0)
535  {
537  << "Zone named " << zoneName << " not found." << nl
538  << "Available zone names: " << names() << endl
539  << abort(FatalError);
540  }
541 
542  return operator[](zoneI);
543 }
544 
545 
546 template<class ZoneType, class MeshType>
548 (
549  const word& zoneName
550 )
551 {
552  const label zoneI = findZoneID(zoneName);
553 
554  if (zoneI < 0)
555  {
557  << "Zone named " << zoneName << " not found." << nl
558  << "Available zone names: " << names() << endl
559  << abort(FatalError);
560  }
561 
562  return operator[](zoneI);
563 }
564 
565 
566 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
567 
568 template<class ZoneType, class MeshType>
569 Foam::Ostream& Foam::operator<<
570 (
571  Ostream& os,
572  const ZoneMesh<ZoneType, MeshType>& zones
573 )
574 {
575  os << zones.size() << nl << token::BEGIN_LIST;
576 
577  forAll(zones, zoneI)
578  {
579  zones[zoneI].writeDict(os);
580  }
581 
582  os << token::END_LIST;
583 
584  return os;
585 }
586 
587 
588 // ************************************************************************* //
label findIndex(const keyType &) const
Return zone index for the first match, return -1 if not found.
Definition: ZoneMesh.C:306
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order. Return.
Definition: ZoneMesh.C:428
A class for handling keywords in dictionaries.
Definition: keyType.H:64
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
wordList types() const
Return a list of zone types.
Definition: ZoneMesh.C:240
bool empty() const
Return true if the UList is empty (ie, size() is zero)
Definition: UListI.H:313
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:387
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
bool set(const label) const
Is element set.
Definition: PtrListI.H:65
void clear()
Clear the zones.
Definition: ZoneMesh.C:401
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:110
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
tUEqn clear()
const Map< label > & zoneMap() const
Map of zones containing zone index for all zoned elements.
Definition: ZoneMesh.C:208
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:163
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
A list of mesh zones.
Operations on lists of strings.
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
~ZoneMesh()
Destructor.
Definition: ZoneMesh.C:198
labelList findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurences of given element. Linear search.
void movePoints(const pointField &)
Correct zone mesh after moving points.
Definition: ZoneMesh.C:505
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
bool findStrings(const wordReListMatcher &matcher, const std::string &str)
Return true if string matches one of the regular expressions.
Definition: stringListOps.H:52
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:142
label findZoneID(const word &zoneName) const
Find zone index given a name.
Definition: ZoneMesh.C:341
A class for handling words, derived from string.
Definition: word.H:59
List< label > labelList
A List of labels.
Definition: labelList.H:56
errorManip< error > abort(error &err)
Definition: errorManip.H:131
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:131
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
static const char nl
Definition: Ostream.H:262
PackedBoolList findMatching(const keyType &) const
Mark cells that match the zone specification.
Definition: ZoneMesh.C:370
labelList findIndices(const keyType &) const
Return zone indices for all matches.
Definition: ZoneMesh.C:273
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:221
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
void setSize(const label)
Reset size of List.
Definition: List.C:281
Template functions to aid in the implementation of demand driven data.
A bit-packed bool list.
#define WarningInFunction
Report a warning using Foam::Warning.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:65
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition: ZoneMesh.C:410
wordList names() const
Return a list of zone names.
Definition: ZoneMesh.C:256
messageStream Info
volScalarField & p
bool writeData(Ostream &) const
writeData member function required by regIOobject
Definition: ZoneMesh.C:517
void deleteDemandDrivenData(DataPtr &dataPtr)
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:92
bool isPattern() const
Should be treated as a match rather than a literal string.
Definition: keyTypeI.H:76
A HashTable to objects of type <T> with a label key.
Definition: Map.H:49
#define InfoInFunction
Report an information message using Foam::Info.