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-2013 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  {
41  FatalErrorIn("void ZoneMesh<ZoneType>::calcZoneMap() const")
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  {
85  WarningIn
86  (
87  "ZoneMesh::ZoneMesh\n"
88  "(\n"
89  " const IOobject&,\n"
90  " const MeshType&\n"
91  ")"
92  ) << "Specified IOobject::MUST_READ_IF_MODIFIED but class"
93  << " does not support automatic rereading."
94  << endl;
95  }
96 
97  PtrList<ZoneType>& zones = *this;
98 
99  // Read zones
100  Istream& is = readStream(typeName);
101 
102  PtrList<entry> patchEntries(is);
103  zones.setSize(patchEntries.size());
104 
105  forAll(zones, zoneI)
106  {
107  zones.set
108  (
109  zoneI,
111  (
112  patchEntries[zoneI].keyword(),
113  patchEntries[zoneI].dict(),
114  zoneI,
115  *this
116  )
117  );
118  }
119 
120  // Check state of IOstream
121  is.check
122  (
123  "ZoneMesh::ZoneMesh"
124  "(const IOobject&, const MeshType&)"
125  );
126 
127  close();
128 
129  return true;
130  }
131  else
132  {
133  // Nothing read
134  return false;
135  }
136 }
137 
138 
139 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
140 
141 // Read constructor given IOobject and a MeshType reference
142 template<class ZoneType, class MeshType>
144 (
145  const IOobject& io,
146  const MeshType& mesh
147 )
148 :
150  regIOobject(io),
151  mesh_(mesh),
152  zoneMapPtr_(NULL)
153 {
154  read();
155 }
156 
157 
158 // Construct given size. Zones will be set later
159 template<class ZoneType, class MeshType>
161 (
162  const IOobject& io,
163  const MeshType& mesh,
164  const label size
165 )
166 :
167  PtrList<ZoneType>(size),
168  regIOobject(io),
169  mesh_(mesh),
170  zoneMapPtr_(NULL)
171 {
172  // Optionally read contents, otherwise keep size
173  read();
174 }
175 
176 
177 template<class ZoneType, class MeshType>
179 (
180  const IOobject& io,
181  const MeshType& mesh,
182  const PtrList<ZoneType>& pzm
183 )
184 :
186  regIOobject(io),
187  mesh_(mesh),
188  zoneMapPtr_(NULL)
189 {
190  if (!read())
191  {
192  // Nothing read. Use supplied zones
193  PtrList<ZoneType>& zones = *this;
194  zones.setSize(pzm.size());
195  forAll (zones, zoneI)
196  {
197  zones.set(zoneI, pzm[zoneI].clone(*this).ptr());
198  }
199  }
200 }
201 
202 
203 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
204 
205 template<class ZoneType, class MeshType>
207 {
208  clearAddressing();
209 }
210 
211 
212 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
213 
214 // Map of zones for quick zone lookup
215 template<class ZoneType, class MeshType>
218 {
219  if (!zoneMapPtr_)
220  {
221  calcZoneMap();
222  }
223 
224  return *zoneMapPtr_;
225 }
226 
227 
228 // Given a global object index, return the zone it is in.
229 // If object does not belong to any zones, return -1
230 template<class ZoneType, class MeshType>
232 (
233  const label objectIndex
234 ) const
235 {
236  const Map<label>& zm = zoneMap();
237  Map<label>::const_iterator zmIter = zm.find(objectIndex);
238 
239  if (zmIter == zm.end())
240  {
241  return -1;
242  }
243  else
244  {
245  return zmIter();
246  }
247 }
248 
249 
250 // Return a list of zone names
251 template<class ZoneType, class MeshType>
253 {
254  const PtrList<ZoneType>& zones = *this;
255 
256  wordList lst(zones.size());
257 
258  forAll(zones, zoneI)
259  {
260  lst[zoneI] = zones[zoneI].type();
261  }
262 
263  return lst;
264 }
265 
266 
267 // Return a list of zone names
268 template<class ZoneType, class MeshType>
270 {
271  const PtrList<ZoneType>& zones = *this;
272 
273  wordList lst(zones.size());
274 
275  forAll(zones, zoneI)
276  {
277  lst[zoneI] = zones[zoneI].name();
278  }
279 
280  return lst;
281 }
282 
283 
284 template<class ZoneType, class MeshType>
286 (
287  const keyType& key
288 ) const
289 {
290  labelList indices;
291 
292  if (!key.empty())
293  {
294  if (key.isPattern())
295  {
296  indices = findStrings(key, this->names());
297  }
298  else
299  {
300  indices.setSize(this->size());
301  label nFound = 0;
302  forAll(*this, i)
303  {
304  if (key == operator[](i).name())
305  {
306  indices[nFound++] = i;
307  }
308  }
309  indices.setSize(nFound);
310  }
311  }
312 
313  return indices;
314 }
315 
316 
317 template<class ZoneType, class MeshType>
319 (
320  const keyType& key
321 ) const
322 {
323  if (!key.empty())
324  {
325  if (key.isPattern())
326  {
327  labelList indices = this->findIndices(key);
328 
329  // return first element
330  if (!indices.empty())
331  {
332  return indices[0];
333  }
334  }
335  else
336  {
337  forAll(*this, i)
338  {
339  if (key == operator[](i).name())
340  {
341  return i;
342  }
343  }
344  }
345  }
346 
347  // not found
348  return -1;
349 }
350 
351 
352 template<class ZoneType, class MeshType>
354 (
355  const word& zoneName
356 ) const
357 {
358  const PtrList<ZoneType>& zones = *this;
359 
360  forAll(zones, zoneI)
361  {
362  if (zones[zoneI].name() == zoneName)
363  {
364  return zoneI;
365  }
366  }
367 
368  // Zone not found
369  if (debug)
370  {
371  Info<< "label ZoneMesh<ZoneType>::findZoneID(const word&) const : "
372  << "Zone named " << zoneName << " not found. "
373  << "List of available zone names: " << names() << endl;
374  }
375 
376  // not found
377  return -1;
378 }
379 
380 
381 template<class ZoneType, class MeshType>
383 (
384  const keyType& key
385 ) const
386 {
387  PackedBoolList lst;
388 
389  const labelList indices = this->findIndices(key);
390  forAll(indices, i)
391  {
392  lst |= static_cast<const labelList&>(this->operator[](indices[i]));
393  }
394 
395  return lst;
396 }
397 
398 
399 template<class ZoneType, class MeshType>
401 {
402  deleteDemandDrivenData(zoneMapPtr_);
403 
404  PtrList<ZoneType>& zones = *this;
405 
406  forAll(zones, zoneI)
407  {
408  zones[zoneI].clearAddressing();
409  }
410 }
411 
412 
413 template<class ZoneType, class MeshType>
415 {
416  clearAddressing();
418 }
419 
420 
421 // Check zone definition
422 template<class ZoneType, class MeshType>
424 (
425  const bool report
426 ) const
427 {
428  bool inError = false;
429 
430  const PtrList<ZoneType>& zones = *this;
431 
432  forAll(zones, zoneI)
433  {
434  inError |= zones[zoneI].checkDefinition(report);
435  }
436  return inError;
437 }
438 
439 
440 template<class ZoneType, class MeshType>
442 (
443  const bool report
444 ) const
445 {
446  if (!Pstream::parRun())
447  {
448  return false;
449  }
450 
451 
452  const PtrList<ZoneType>& zones = *this;
453 
454  bool hasError = false;
455 
456  // Collect all names
457  List<wordList> allNames(Pstream::nProcs());
458  allNames[Pstream::myProcNo()] = this->names();
459  Pstream::gatherList(allNames);
460  Pstream::scatterList(allNames);
461 
462  List<wordList> allTypes(Pstream::nProcs());
463  allTypes[Pstream::myProcNo()] = this->types();
464  Pstream::gatherList(allTypes);
465  Pstream::scatterList(allTypes);
466 
467  // Have every processor check but only master print error.
468 
469  for (label procI = 1; procI < allNames.size(); procI++)
470  {
471  if
472  (
473  (allNames[procI] != allNames[0])
474  || (allTypes[procI] != allTypes[0])
475  )
476  {
477  hasError = true;
478 
479  if (debug || (report && Pstream::master()))
480  {
481  Info<< " ***Inconsistent zones across processors, "
482  "processor 0 has zone names:" << allNames[0]
483  << " zone types:" << allTypes[0]
484  << " processor " << procI << " has zone names:"
485  << allNames[procI]
486  << " zone types:" << allTypes[procI]
487  << endl;
488  }
489  }
490  }
491 
492  // Check contents
493  if (!hasError)
494  {
495  forAll(zones, zoneI)
496  {
497  if (zones[zoneI].checkParallelSync(false))
498  {
499  hasError = true;
500 
501  if (debug || (report && Pstream::master()))
502  {
503  Info<< " ***Zone " << zones[zoneI].name()
504  << " of type " << zones[zoneI].type()
505  << " is not correctly synchronised"
506  << " across coupled boundaries."
507  << " (coupled faces are either not both"
508  << " present in set or have same flipmap)" << endl;
509  }
510  }
511  }
512  }
513 
514  return hasError;
515 }
516 
517 
518 // Correct zone mesh after moving points
519 template<class ZoneType, class MeshType>
521 {
522  PtrList<ZoneType>& zones = *this;
523 
524  forAll(zones, zoneI)
525  {
526  zones[zoneI].movePoints(p);
527  }
528 }
529 
530 
531 // writeData member function required by regIOobject
532 template<class ZoneType, class MeshType>
534 {
535  os << *this;
536  return os.good();
537 }
538 
539 // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
540 
541 template<class ZoneType, class MeshType>
543 (
544  const word& zoneName
545 ) const
546 {
547  const label zoneI = findZoneID(zoneName);
548 
549  if (zoneI < 0)
550  {
552  (
553  "ZoneMesh<ZoneType>::operator[](const word&) const"
554  ) << "Zone named " << zoneName << " not found." << nl
555  << "Available zone names: " << names() << endl
556  << abort(FatalError);
557  }
558 
559  return operator[](zoneI);
560 }
561 
562 
563 template<class ZoneType, class MeshType>
565 (
566  const word& zoneName
567 )
568 {
569  const label zoneI = findZoneID(zoneName);
570 
571  if (zoneI < 0)
572  {
574  (
575  "ZoneMesh<ZoneType>::operator[](const word&)"
576  ) << "Zone named " << zoneName << " not found." << nl
577  << "Available zone names: " << names() << endl
578  << abort(FatalError);
579  }
580 
581  return operator[](zoneI);
582 }
583 
584 
585 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
586 
587 template<class ZoneType, class MeshType>
588 Foam::Ostream& Foam::operator<<
589 (
590  Ostream& os,
591  const ZoneMesh<ZoneType, MeshType>& zones
592 )
593 {
594  os << zones.size() << nl << token::BEGIN_LIST;
595 
596  forAll(zones, zoneI)
597  {
598  zones[zoneI].writeDict(os);
599  }
600 
601  os << token::END_LIST;
602 
603  return os;
604 }
605 
606 
607 // ************************************************************************* //
bool checkParallelSync(const bool report=false) const
Check whether all procs have all zones and in same order. Return.
Definition: ZoneMesh.C:442
void setSize(const label)
Reset size of PtrList. If extending the PtrList, new entries are.
Definition: PtrList.C:142
label size() const
Return the number of elements in the PtrList.
Definition: PtrListI.H:32
bool set(const label) const
Is element set.
Definition: PtrListI.H:107
~ZoneMesh()
Destructor.
Definition: ZoneMesh.C:206
label whichZone(const label objectIndex) const
Given a global object index, return the zone it is in.
Definition: ZoneMesh.C:232
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
bool empty() const
Return true if the UList is empty (ie, size() is zero).
Definition: UListI.H:313
wordList types() const
Return a list of zone types.
Definition: ZoneMesh.C:252
A HashTable to objects of type <T> with a label key.
Definition: Map.H:49
void deleteDemandDrivenData(DataPtr &dataPtr)
A bit-packed bool list.
A class for handling words, derived from string.
Definition: word.H:59
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
bool isPattern() const
Should be treated as a match rather than a literal string.
Definition: keyTypeI.H:76
messageStream Info
const Map< label > & zoneMap() const
Map of zones containing zone index for all zoned elements.
Definition: ZoneMesh.C:217
autoPtr< BasicCompressibleTurbulenceModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const typename BasicCompressibleTurbulenceModel::transportModel &transport, const word &propertiesName)
A class for handling keywords in dictionaries.
Definition: keyType.H:56
PackedBoolList findMatching(const keyType &) const
Mark cells that match the zone specification.
Definition: ZoneMesh.C:383
dictionary dict
void clearAddressing()
Clear addressing.
Definition: ZoneMesh.C:400
static const char nl
Definition: Ostream.H:260
void setSize(const label)
Reset size of List.
Definition: List.C:318
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:91
#define WarningIn(functionName)
Report a warning using Foam::Warning.
volScalarField & p
Definition: createFields.H:51
bool findStrings(const wordReListMatcher &matcher, const std::string &str)
Return true if string matches one of the regular expressions.
Definition: stringListOps.H:52
#define forAll(list, i)
Definition: UList.H:421
bool good() const
Return true if next operation might succeed.
Definition: IOstream.H:333
labelList findIndices(const keyType &) const
Return zone indices for all matches.
Definition: ZoneMesh.C:286
Template functions to aid in the implementation of demand driven data.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
bool checkDefinition(const bool report=false) const
Check zone definition. Return true if in error.
Definition: ZoneMesh.C:424
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A list of mesh zones.
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:60
error FatalError
List< label > labelList
A List of labels.
Definition: labelList.H:56
Operations on lists of strings.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:53
label findZoneID(const word &zoneName) const
Find zone index given a name.
Definition: ZoneMesh.C:354
bool read(const char *, int32_t &)
Definition: int32IO.C:87
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
wordList names() const
Return a list of zone names.
Definition: ZoneMesh.C:269
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:139
label findIndex(const keyType &) const
Return zone index for the first match, return -1 if not found.
Definition: ZoneMesh.C:319
UEqn clear()
void movePoints(const pointField &)
Correct zone mesh after moving points.
Definition: ZoneMesh.C:520
labelList findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurences of given element. Linear search.
void clear()
Clear the zones.
Definition: ZoneMesh.C:414
bool writeData(Ostream &) const
writeData member function required by regIOobject
Definition: ZoneMesh.C:533