FreeFOAM The Cross-Platform CFD Toolkit
topoSet.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) 1991-2010 OpenCFD Ltd.
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 "topoSet.H"
27 #include <OpenFOAM/mapPolyMesh.H>
28 #include <OpenFOAM/polyMesh.H>
29 #include <OpenFOAM/boundBox.H>
30 
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
32 
33 namespace Foam
34 {
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 defineTypeNameAndDebug(topoSet, 0);
39 defineRunTimeSelectionTable(topoSet, word);
40 defineRunTimeSelectionTable(topoSet, size);
41 defineRunTimeSelectionTable(topoSet, set);
42 
43 
44 // Construct named object from existing set.
45 autoPtr<topoSet> topoSet::New
46 (
47  const word& setType,
48  const polyMesh& mesh,
49  const word& name,
50  readOption r,
51  writeOption w
52 )
53 {
54  wordConstructorTable::iterator cstrIter =
55  wordConstructorTablePtr_
56  ->find(setType);
57 
58  if (cstrIter == wordConstructorTablePtr_->end())
59  {
61  (
62  "topoSet::New(const word&, "
63  "const polyMesh&, const word&, readOption, writeOption)"
64  ) << "Unknown set type " << setType
65  << endl << endl
66  << "Valid set types : " << endl
67  << wordConstructorTablePtr_->sortedToc()
68  << exit(FatalError);
69  }
70 
71  return autoPtr<topoSet>(cstrIter()(mesh, name, r, w));
72 }
73 
74 
75 // Construct named object from size (non-existing set).
77 (
78  const word& setType,
79  const polyMesh& mesh,
80  const word& name,
81  const label size,
82  writeOption w
83 )
84 {
85  sizeConstructorTable::iterator cstrIter =
86  sizeConstructorTablePtr_
87  ->find(setType);
88 
89  if (cstrIter == sizeConstructorTablePtr_->end())
90  {
92  (
93  "topoSet::New(const word&, "
94  "const polyMesh&, const word&, const label, writeOption)"
95  ) << "Unknown set type " << setType
96  << endl << endl
97  << "Valid set types : " << endl
98  << sizeConstructorTablePtr_->sortedToc()
99  << exit(FatalError);
100  }
101 
102  return autoPtr<topoSet>(cstrIter()(mesh, name, size, w));
103 }
104 
105 
106 // Construct named object from existing set.
108 (
109  const word& setType,
110  const polyMesh& mesh,
111  const word& name,
112  const topoSet& set,
113  writeOption w
114 )
115 {
116  setConstructorTable::iterator cstrIter =
117  setConstructorTablePtr_
118  ->find(setType);
119 
120  if (cstrIter == setConstructorTablePtr_->end())
121  {
123  (
124  "topoSet::New(const word&, "
125  "const polyMesh&, const word&, const topoSet&, writeOption)"
126  ) << "Unknown set type " << setType
127  << endl << endl
128  << "Valid set types : " << endl
129  << setConstructorTablePtr_->sortedToc()
130  << exit(FatalError);
131  }
132 
133  return autoPtr<topoSet>(cstrIter()(mesh, name, set, w));
134 }
135 
136 
138 (
139  const polyMesh& mesh,
140  const word& name
141 )
142 {
143  return mesh.pointsInstance()/polyMesh::meshSubDir/"sets"/name;
144 }
145 
146 
147 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
148 
149 // Update stored cell numbers using map.
150 // Do in two passes to prevent allocation if nothing changed.
152 {
153  // Iterate over map to see if anything changed
154  bool changed = false;
155 
156  for
157  (
158  labelHashSet::const_iterator iter = begin();
159  iter != end();
160  ++iter
161  )
162  {
163  if ((iter.key() < 0) || (iter.key() > map.size()))
164  {
166  (
167  "topoSet::updateLabels(const labelList&, labelHashSet)"
168  ) << "Illegal content " << iter.key() << " of set:" << name()
169  << " of type " << type() << endl
170  << "Value should be between 0 and " << map.size()-1
171  << abort(FatalError);
172  }
173 
174  label newCellI = map[iter.key()];
175 
176  if (newCellI != iter.key())
177  {
178  changed = true;
179 
180  break;
181  }
182  }
183 
184  // Relabel (use second Map to prevent overlapping)
185  if (changed)
186  {
187  labelHashSet newSet(2*size());
188 
189  for
190  (
191  labelHashSet::const_iterator iter = begin();
192  iter != end();
193  ++iter
194  )
195  {
196  label newCellI = map[iter.key()];
197 
198  if (newCellI >= 0)
199  {
200  newSet.insert(newCellI);
201  }
202  }
203 
204  transfer(newSet);
205  }
206 }
207 
208 
209 void topoSet::topoSet::check(const label maxLabel)
210 {
211  for
212  (
213  topoSet::const_iterator iter = begin();
214  iter != end();
215  ++iter
216  )
217  {
218  if ((iter.key() < 0) || (iter.key() > maxLabel))
219  {
220  FatalErrorIn("topoSet::check(const label)")
221  << "Illegal content " << iter.key() << " of set:" << name()
222  << " of type " << type() << endl
223  << "Value should be between 0 and " << maxLabel
224  << abort(FatalError);
225  }
226  }
227 }
228 
229 
230 // Write maxElem elements, starting at iter. Updates iter and elemI.
232 (
233  Ostream& os,
234  const label maxElem,
236  label& elemI
237 ) const
238 {
239  label n = 0;
240 
241  for (; (iter != end()) && (n < maxElem); ++iter)
242  {
243  if ((n != 0) && ((n % 10) == 0))
244  {
245  os << endl;
246  }
247  os << iter.key() << ' ';
248 
249  n++;
250  elemI++;
251  }
252 }
253 
254 
255 // Write maxElem elements, starting at iter. Updates iter and elemI.
257 (
258  Ostream& os,
259  const pointField& coords,
260  const label maxElem,
262  label& elemI
263 ) const
264 {
265  label n = 0;
266 
267  for (; (iter != end()) && (n < maxElem); ++iter)
268  {
269  if ((n != 0) && ((n % 3) == 0))
270  {
271  os << endl;
272  }
273  os << iter.key() << coords[iter.key()] << ' ';
274 
275  n++;
276  elemI++;
277  }
278 }
279 
280 
282 (
283  Ostream& os,
284  const pointField& coords,
285  const label maxLen
286 ) const
287 {
288  // Bounding box of contents.
289  boundBox bb(pointField(coords, toc()), true);
290 
291  os << "Set bounding box: min = "
292  << bb.min() << " max = " << bb.max() << " meters. " << endl << endl;
293 
294  label n = 0;
295 
296  topoSet::const_iterator iter = begin();
297 
298  if (size() <= maxLen)
299  {
300  writeDebug(os, coords, maxLen, iter, n);
301  }
302  else
303  {
304  label halfLen = maxLen/2;
305 
306  os << "Size larger than " << maxLen << ". Printing first and last "
307  << halfLen << " elements:" << endl << endl;
308 
309  writeDebug(os, coords, halfLen, iter, n);
310 
311  os<< endl
312  << " .." << endl
313  << endl;
314 
315  for (; n < size() - halfLen; ++n)
316  {
317  ++iter;
318  }
319 
320  writeDebug(os, coords, halfLen, iter, n);
321  }
322 }
323 
324 
325 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
326 
327 topoSet::topoSet(const IOobject& obj, const word& wantedType)
328 :
329  regIOobject(obj)
330 {
331  if
332  (
334  || (
336  && headerOk()
337  )
338  )
339  {
340  if (readStream(wantedType).good())
341  {
342  readStream(wantedType) >> static_cast<labelHashSet&>(*this);
343 
344  close();
345  }
346  }
347 }
348 
349 
351 (
352  const polyMesh& mesh,
353  const word& wantedType,
354  const word& name,
355  readOption r,
356  writeOption w
357 )
358 :
360  (
361  IOobject
362  (
363  name,
364  mesh.pointsInstance(),
365  polyMesh::meshSubDir/"sets",
366  mesh,
367  r,
368  w
369  )
370  )
371 {
372  if
373  (
374  readOpt() == IOobject::MUST_READ
375  || (
376  readOpt() == IOobject::READ_IF_PRESENT
377  && headerOk()
378  )
379  )
380  {
381  if (readStream(wantedType).good())
382  {
383  readStream(wantedType) >> static_cast<labelHashSet&>(*this);
384 
385  close();
386  }
387  }
388 }
389 
390 
392 (
393  const polyMesh& mesh,
394  const word& name,
395  const label size,
396  writeOption w
397 )
398 :
400  (
401  IOobject
402  (
403  name,
404  mesh.pointsInstance(),
405  polyMesh::meshSubDir/"sets",
406  mesh,
407  NO_READ,
408  w
409  )
410  ),
411  labelHashSet(size)
412 {}
413 
414 
416 (
417  const polyMesh& mesh,
418  const word& name,
419  const labelHashSet& set,
420  writeOption w
421 )
422 :
424  (
425  IOobject
426  (
427  name,
428  mesh.pointsInstance(),
429  polyMesh::meshSubDir/"sets",
430  mesh,
431  NO_READ,
432  w
433  )
434  ),
435  labelHashSet(set)
436 {}
437 
438 
439 topoSet::topoSet(const IOobject& obj, const label size)
440 :
441  regIOobject(obj),
442  labelHashSet(size)
443 {}
444 
445 
446 topoSet::topoSet(const IOobject& obj, const labelHashSet& set)
447 :
448  regIOobject(obj),
449  labelHashSet(set)
450 {}
451 
452 
453 
454 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
455 
457 {}
458 
459 
460 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
461 
462 void topoSet::invert(const label maxLen)
463 {
464  // Keep copy of current set.
465  labelHashSet currentSet(*this);
466 
467  clear();
468  resize(2*(maxLen - currentSet.size()));
469 
470  for (label cellI = 0; cellI < maxLen; cellI++)
471  {
472  if (!currentSet.found(cellI))
473  {
474  insert(cellI);
475  }
476  }
477 
478 }
479 
480 
481 void topoSet::subset(const topoSet& set)
482 {
483  // Keep copy of current set.
484  labelHashSet currentSet(*this);
485 
486  clear();
487  resize(2*min(currentSet.size(), set.size()));
488 
489  for
490  (
491  labelHashSet::const_iterator iter = currentSet.begin();
492  iter != currentSet.end();
493  ++iter
494  )
495  {
496  if (set.found(iter.key()))
497  {
498  // element present in both currentSet and set.
499  insert(iter.key());
500  }
501  }
502 }
503 
504 
505 void topoSet::addSet(const topoSet& set)
506 {
507  for
508  (
509  topoSet::const_iterator iter = set.begin();
510  iter != set.end();
511  ++iter
512  )
513  {
514  insert(iter.key());
515  }
516 }
517 
518 
519 void topoSet::deleteSet(const topoSet& set)
520 {
521  for
522  (
523  topoSet::const_iterator iter = set.begin();
524  iter != set.end();
525  ++iter
526  )
527  {
528  erase(iter.key());
529  }
530 }
531 
532 
534 {
535  notImplemented("topoSet::sync(const polyMesh&)");
536 }
537 
538 
539 void topoSet::writeDebug(Ostream& os, const label maxLen) const
540 {
541  label n = 0;
542 
544 
545  if (size() <= maxLen)
546  {
547  writeDebug(os, maxLen, iter, n);
548  }
549  else
550  {
551  label halfLen = maxLen/2;
552 
553  os << "Size larger than " << maxLen << ". Printing first and last "
554  << halfLen << " elements:" << endl << endl;
555 
556  writeDebug(os, halfLen, iter, n);
557 
558  os<< endl
559  << " .." << endl
560  << endl;
561 
562  for (; n < size() - halfLen; ++n)
563  {
564  ++iter;
565  }
566 
567  writeDebug(os, halfLen, iter, n);
568  }
569 }
570 
571 
573 (
574  Ostream&,
575  const primitiveMesh&,
576  const label
577 ) const
578 {
580  (
581  "topoSet::writeDebug(Ostream&, const primitiveMesh&, const label)"
582  );
583 }
584 
585 
587 {
588  return (os << *this).good();
589 }
590 
591 
593 {
594  notImplemented("topoSet::updateMesh(const mapPolyMesh&)");
595 }
596 
597 
598 //- Return max index+1.
599 label topoSet::maxSize(const polyMesh&) const
600 {
601  notImplemented("topoSet::maxSize(const polyMesh&)");
602 
603  return -1;
604 }
605 
606 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
607 
608 void topoSet::operator=(const topoSet& rhs)
609 {
611 }
612 
613 
614 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
615 
616 } // End namespace Foam
617 
618 // ************************ vim: set sw=4 sts=4 et: ************************ //