UnsortedMeshedSurface.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-2014 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 "MeshedSurface.H"
27 #include "UnsortedMeshedSurface.H"
28 #include "MeshedSurfaceProxy.H"
29 #include "IFstream.H"
30 #include "OFstream.H"
31 #include "Time.H"
32 #include "polyBoundaryMesh.H"
33 #include "polyMesh.H"
34 
35 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
36 
37 template<class Face>
39 {
40  return wordHashSet(*fileExtensionConstructorTablePtr_);
41 }
42 
43 
44 template<class Face>
46 {
47  return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
48 }
49 
50 
51 template<class Face>
53 (
54  const word& ext,
55  const bool verbose
56 )
57 {
58  return fileFormats::surfaceFormatsCore::checkSupport
59  (
60  readTypes() | ParentType::readTypes(),
61  ext,
62  verbose,
63  "reading"
64  );
65 }
66 
67 
68 template<class Face>
70 (
71  const word& ext,
72  const bool verbose
73 )
74 {
75  return fileFormats::surfaceFormatsCore::checkSupport
76  (
77  writeTypes(),
78  ext,
79  verbose,
80  "writing"
81  );
82 }
83 
84 
85 template<class Face>
87 (
88  const fileName& name,
89  const bool verbose
90 )
91 {
92  word ext = name.ext();
93  if (ext == "gz")
94  {
95  ext = name.lessExt().ext();
96  }
97  return canReadType(ext, verbose);
98 }
99 
100 
101 template<class Face>
103 (
104  const fileName& name,
105  const UnsortedMeshedSurface<Face>& surf
106 )
107 {
108  if (debug)
109  {
110  Info<< "UnsortedMeshedSurface::write"
111  "(const fileName&, const UnsortedMeshedSurface&) : "
112  "writing to " << name
113  << endl;
114  }
115 
116  const word ext = name.ext();
117 
118  typename writefileExtensionMemberFunctionTable::iterator mfIter =
119  writefileExtensionMemberFunctionTablePtr_->find(ext);
120 
121  if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
122  {
123  // no direct writer, delegate to proxy if possible
124  wordHashSet supported = ProxyType::writeTypes();
125 
126  if (supported.found(ext))
127  {
128  MeshedSurfaceProxy<Face>(surf).write(name);
129  }
130  else
131  {
133  (
134  "UnsortedMeshedSurface::write"
135  "(const fileName&, const UnsortedMeshedSurface&)"
136  ) << "Unknown file extension " << ext << nl << nl
137  << "Valid types are :" << endl
138  << (supported | writeTypes())
139  << exit(FatalError);
140  }
141  }
142  else
143  {
144  mfIter()(name, surf);
145  }
146 }
147 
148 
149 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
150 
151 template<class Face>
153 :
154  ParentType()
155 {}
156 
157 
158 template<class Face>
160 (
161  const Xfer<pointField>& pointLst,
162  const Xfer<List<Face> >& faceLst,
163  const Xfer<List<label> >& zoneIds,
164  const Xfer<surfZoneIdentifierList>& zoneTofc
165 )
166 :
167  ParentType(pointLst, faceLst),
168  zoneIds_(zoneIds),
169  zoneToc_(zoneTofc)
170 {}
171 
172 
173 template<class Face>
175 (
176  const Xfer<pointField>& pointLst,
177  const Xfer<List<Face> >& faceLst,
178  const labelUList& zoneSizes,
179  const UList<word>& zoneNames
180 )
181 :
182  ParentType(pointLst, faceLst)
183 {
184  if (zoneSizes.size())
185  {
186  if (zoneNames.size())
187  {
188  setZones(zoneSizes, zoneNames);
189  }
190  else
191  {
192  setZones(zoneSizes);
193  }
194  }
195  else
196  {
197  setOneZone();
198  }
199 }
200 
201 
202 template<class Face>
204 (
205  const UnsortedMeshedSurface<Face>& surf
206 )
207 :
208  ParentType
209  (
210  xferCopy(surf.points()),
211  xferCopy(surf.faces())
212  ),
213  zoneIds_(surf.zoneIds()),
214  zoneToc_(surf.zoneToc())
215 {}
216 
217 
218 template<class Face>
220 (
221  const MeshedSurface<Face>& surf
222 )
223 :
224  ParentType
225  (
226  xferCopy(surf.points()),
227  xferCopy(surf.faces())
228  )
229 {
230  setZones(surf.surfZones());
231 }
232 
233 
234 template<class Face>
236 (
237  const Xfer<UnsortedMeshedSurface<Face> >& surf
238 )
239 :
240  ParentType()
241 {
242  transfer(surf());
243 }
244 
245 
246 template<class Face>
248 (
249  const Xfer<MeshedSurface<Face> >& surf
250 )
251 :
252  ParentType()
253 {
254  transfer(surf());
255 }
256 
257 
258 template<class Face>
260 (
261  const fileName& name,
262  const word& ext
263 )
264 :
265  ParentType()
266 {
267  read(name, ext);
268 }
269 
270 
271 template<class Face>
273 :
274  ParentType()
275 {
276  read(name);
277 }
278 
279 
280 template<class Face>
282 (
283  const Time& t,
284  const word& surfName
285 )
286 :
287  ParentType()
288 {
289  MeshedSurface<Face> surf(t, surfName);
290  transfer(surf);
291 }
292 
293 
294 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
295 
296 template<class Face>
298 {}
299 
300 
301 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
302 
303 template<class Face>
305 {
306  zoneIds_.setSize(size());
307  zoneIds_ = 0;
308 
309  word zoneName;
310  if (zoneToc_.size())
311  {
312  zoneName = zoneToc_[0].name();
313  }
314  if (zoneName.empty())
315  {
316  zoneName = "zone0";
317  }
318 
319  // set single default zone
320  zoneToc_.setSize(1);
321  zoneToc_[0] = surfZoneIdentifier(zoneName, 0);
322 }
323 
324 
325 template<class Face>
327 (
328  const surfZoneList& zoneLst
329 )
330 {
331  zoneIds_.setSize(size());
332  zoneToc_.setSize(zoneLst.size());
333 
334  forAll(zoneToc_, zoneI)
335  {
336  const surfZone& zone = zoneLst[zoneI];
337  zoneToc_[zoneI] = zone;
338 
339  // assign sub-zone Ids
340  SubList<label> subZone(zoneIds_, zone.size(), zone.start());
341  subZone = zoneI;
342  }
343 }
344 
345 
346 template<class Face>
348 (
349  const labelUList& sizes,
350  const UList<word>& names
351 )
352 {
353  zoneIds_.setSize(size());
354  zoneToc_.setSize(sizes.size());
355 
356  label start = 0;
357  forAll(zoneToc_, zoneI)
358  {
359  zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);
360 
361  // assign sub-zone Ids
362  SubList<label> subZone(zoneIds_, sizes[zoneI], start);
363  subZone = zoneI;
364 
365  start += sizes[zoneI];
366  }
367 }
368 
369 
370 template<class Face>
372 (
373  const labelUList& sizes
374 )
375 {
376  zoneIds_.setSize(size());
377  zoneToc_.setSize(sizes.size());
378 
379  label start = 0;
380  forAll(zoneToc_, zoneI)
381  {
382  zoneToc_[zoneI] = surfZoneIdentifier
383  (
384  word("zone") + ::Foam::name(zoneI),
385  zoneI
386  );
387 
388  // assign sub-zone Ids
389  SubList<label> subZone(zoneIds_, sizes[zoneI], start);
390  subZone = zoneI;
391 
392  start += sizes[zoneI];
393  }
394 }
395 
396 
397 template<class Face>
399 (
400  const labelUList& faceMap
401 )
402 {
403  // re-assign the zone Ids
404  if (notNull(faceMap) && faceMap.size())
405  {
406  if (zoneToc_.empty())
407  {
408  setOneZone();
409  }
410  else if (zoneToc_.size() == 1)
411  {
412  // optimized for single-zone case
413  zoneIds_ = 0;
414  }
415  else
416  {
417  List<label> newZones(faceMap.size());
418 
419  forAll(faceMap, faceI)
420  {
421  newZones[faceI] = zoneIds_[faceMap[faceI]];
422  }
423  zoneIds_.transfer(newZones);
424  }
425  }
426 }
427 
428 
429 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
430 
431 template<class Face>
433 {
434  this->storedFaces().setSize(s);
435  // if zones extend: set with last zoneId
436  zoneIds_.setSize(s, zoneToc_.size() - 1);
437 }
438 
439 
440 template<class Face>
442 {
444  zoneIds_.clear();
445  zoneToc_.clear();
446 }
447 
448 
449 template<class Face>
451 (
452  labelList& faceMap
453 ) const
454 {
455  // supply some zone names
456  Map<word> zoneNames;
457  forAll(zoneToc_, zoneI)
458  {
459  zoneNames.insert(zoneI, zoneToc_[zoneI].name());
460  }
461 
462  // std::sort() really seems to mix up the order.
463  // and std::stable_sort() might take too long / too much memory
464 
465  // Assuming that we have relatively fewer zones compared to the
466  // number of items, just do it ourselves
467 
468  // step 1: get zone sizes and store (origId => zoneI)
470  forAll(zoneIds_, faceI)
471  {
472  const label origId = zoneIds_[faceI];
473 
474  Map<label>::iterator fnd = lookup.find(origId);
475  if (fnd != lookup.end())
476  {
477  fnd()++;
478  }
479  else
480  {
481  lookup.insert(origId, 1);
482  }
483  }
484 
485  // step 2: assign start/size (and name) to the newZones
486  // re-use the lookup to map (zoneId => zoneI)
487  surfZoneList zoneLst(lookup.size());
488  label start = 0;
489  label zoneI = 0;
490  forAllIter(Map<label>, lookup, iter)
491  {
492  label origId = iter.key();
493 
494  word name;
495  Map<word>::const_iterator fnd = zoneNames.find(origId);
496  if (fnd != zoneNames.end())
497  {
498  name = fnd();
499  }
500  else
501  {
502  name = word("zone") + ::Foam::name(zoneI);
503  }
504 
505  zoneLst[zoneI] = surfZone
506  (
507  name,
508  0, // initialize with zero size
509  start,
510  zoneI
511  );
512 
513  // increment the start for the next zone
514  // and save the (zoneId => zoneI) mapping
515  start += iter();
516  iter() = zoneI++;
517  }
518 
519 
520  // step 3: build the re-ordering
521  faceMap.setSize(zoneIds_.size());
522 
523  forAll(zoneIds_, faceI)
524  {
525  label zoneI = lookup[zoneIds_[faceI]];
526  faceMap[faceI] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
527  }
528 
529  // with reordered faces registered in faceMap
530  return zoneLst;
531 }
532 
533 
534 template<class Face>
537 (
538  const labelHashSet& include,
539  labelList& pointMap,
540  labelList& faceMap
541 ) const
542 {
543  const pointField& locPoints = this->localPoints();
544  const List<Face>& locFaces = this->localFaces();
545 
546  // Fill pointMap, faceMap
547  PatchTools::subsetMap(*this, include, pointMap, faceMap);
548 
549  // Create compact coordinate list and forward mapping array
550  pointField newPoints(pointMap.size());
551  labelList oldToNew(locPoints.size());
552  forAll(pointMap, pointI)
553  {
554  newPoints[pointI] = locPoints[pointMap[pointI]];
555  oldToNew[pointMap[pointI]] = pointI;
556  }
557 
558  // Renumber face node labels and compact
559  List<Face> newFaces(faceMap.size());
560  List<label> newZones(faceMap.size());
561 
562  forAll(faceMap, faceI)
563  {
564  const label origFaceI = faceMap[faceI];
565  newFaces[faceI] = Face(locFaces[origFaceI]);
566 
567  // Renumber labels for face
568  Face& f = newFaces[faceI];
569  forAll(f, fp)
570  {
571  f[fp] = oldToNew[f[fp]];
572  }
573 
574  newZones[faceI] = zoneIds_[origFaceI];
575  }
576  oldToNew.clear();
577 
578  // construct a sub-surface
579  return UnsortedMeshedSurface
580  (
581  xferMove(newPoints),
582  xferMove(newFaces),
583  xferMove(newZones),
584  xferCopy(zoneToc_)
585  );
586 }
587 
588 
589 template<class Face>
591 (
592  const labelHashSet& include
593 ) const
594 {
595  labelList pointMap, faceMap;
596  return subsetMesh(include, pointMap, faceMap);
597 }
598 
599 
600 template<class Face>
602 (
603  const Xfer<pointField>& pointLst,
604  const Xfer<List<Face> >& faceLst,
605  const Xfer<List<label> >& zoneIds
606 )
607 {
609  (
610  pointLst,
611  faceLst,
613  );
614 
615  if (notNull(zoneIds))
616  {
617  zoneIds_.transfer(zoneIds());
618  }
619 }
620 
621 
622 template<class Face>
624 (
625  const Xfer<List<point> >& pointLst,
626  const Xfer<List<Face> >& faceLst,
627  const Xfer<List<label> >& zoneIds
628 )
629 {
631  (
632  pointLst,
633  faceLst,
635  );
636 
637  if (notNull(zoneIds))
638  {
639  zoneIds_.transfer(zoneIds());
640  }
641 }
642 
643 
644 template<class Face>
646 (
648 )
649 {
651  (
652  xferMove(surf.storedPoints()),
653  xferMove(surf.storedFaces()),
655  );
656 
657  zoneIds_.transfer(surf.zoneIds_);
658  zoneToc_.transfer(surf.zoneToc_);
659 
660  surf.clear();
661 }
662 
663 
664 template<class Face>
666 (
667  MeshedSurface<Face>& surf
668 )
669 {
671  (
672  xferMove(surf.storedPoints()),
673  xferMove(surf.storedFaces()),
675  );
676 
677  setZones(surf.surfZones());
678  surf.clear();
679 }
680 
681 
682 template<class Face>
685 {
686  return xferMove(*this);
687 }
688 
689 
690 // Read from file, determine format from extension
691 template<class Face>
693 {
694  word ext = name.ext();
695  if (ext == "gz")
696  {
697  fileName unzipName = name.lessExt();
698  return read(unzipName, unzipName.ext());
699  }
700  else
701  {
702  return read(name, ext);
703  }
704 }
705 
706 
707 // Read from file in given format
708 template<class Face>
710 (
711  const fileName& name,
712  const word& ext
713 )
714 {
715  clear();
716 
717  // read via use selector mechanism
718  transfer(New(name, ext)());
719  return true;
720 }
721 
722 
723 template<class Face>
725 (
726  const Time& t,
727  const word& surfName
728 ) const
729 {
730  MeshedSurfaceProxy<Face>(*this).write(t, surfName);
731 }
732 
733 
734 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
735 
736 template<class Face>
737 void Foam::UnsortedMeshedSurface<Face>::operator=
738 (
739  const UnsortedMeshedSurface<Face>& surf
740 )
741 {
742  clear();
743 
744  this->storedPoints() = surf.points();
745  this->storedFaces() = surf.faces();
746  zoneIds_ = surf.zoneIds_;
747  zoneToc_ = surf.zoneToc_;
748 }
749 
750 
751 template<class Face>
752 Foam::UnsortedMeshedSurface<Face>::operator
754 {
756  List<surfZone> zoneLst = this->sortedZones(faceMap);
757 
759  (
760  this->points(),
761  this->faces(),
762  zoneLst,
763  faceMap
764  );
765 }
766 
767 
768 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
769 
771 
772 // ************************************************************************* //
label start() const
Return start label of this zone in the face list.
Definition: surfZone.H:132
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:323
const List< surfZoneIdentifier > & zoneToc() const
Return const access to the zone table-of-contents.
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:207
label size() const
Return size of this zone in the face list.
Definition: surfZone.H:144
const List< surfZone > & surfZones() const
Const access to the surface zones.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject( name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE ))
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
Xfer< T > xferCopy(const T &)
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:390
An STL-conforming const_iterator.
Definition: HashTable.H:470
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
labelList f(nPoints)
Xfer< UnsortedMeshedSurface< Face > > xfer()
Transfer contents to the Xfer container.
static void write(const fileName &, const MeshedSurfaceProxy< Face > &)
Write to file.
bool insert(const label &, const T &newElmt)
Insert a new hashedEntry.
A HashTable to objects of type <T> with a label key.
Definition: Map.H:49
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:73
A simple container for copying or transferring objects of type <T>.
Definition: Xfer.H:85
#define forAllIter(Container, container, iter)
Definition: UList.H:440
const List< label > & zoneIds() const
Return const access to the zone ids.
A class for handling words, derived from string.
Definition: word.H:59
static autoPtr< UnsortedMeshedSurface > New(const fileName &, const word &ext)
Select constructed from filename (explicit extension)
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
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
bool read(const fileName &, const word &ext)
Read from file. Chooses reader based on explicit extension.
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:46
messageStream Info
Xfer< T > xferMove(T &)
void setOneZone()
Set zones to 0 and set a single zone.
pointField & storedPoints()
Non-const access to global points.
runTime write()
virtual void clear()
Clear all storage.
virtual void clear()
Clear all storage.
An identifier for a surface zone on a meshed surface.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
const Field< point > & localPoints() const
Return pointField of points in patch.
void clear()
Clear the list, i.e. set size to zero.
Definition: List.C:379
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
const List< Face > & faces() const
Return const access to the faces.
label size() const
The surface size is the number of faces.
stressControl lookup("compactNormalStress") >> compactNormalStress
Base class for zones.
Definition: zone.H:57
virtual void reset(const Xfer< pointField > &points, const Xfer< List< Face > > &faces, const Xfer< surfZoneList > &zones)
Reset primitive data (points, faces and zones)
#define forAll(list, i)
Definition: UList.H:421
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
void transfer(UnsortedMeshedSurface< Face > &)
Transfer the contents of the argument and annul the argument.
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format?
A surface zone on a MeshedSurface.
Definition: surfZone.H:62
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Definition: error.H:314
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:74
error FatalError
UnsortedMeshedSurface subsetMesh(const labelHashSet &include, labelList &pointMap, labelList &faceMap) const
Return new surface.
virtual ~UnsortedMeshedSurface()
Destructor.
A class for handling file names.
Definition: fileName.H:69
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:60
A HashTable with keys but without contents.
Definition: HashSet.H:59
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: MeshedSurface.H:72
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:307
static void subsetMap(const PrimitivePatch< Face, FaceList, PointField, PointType > &, const BoolListType &includeFaces, labelList &pointMap, labelList &faceMap)
Determine the mapping for a sub-patch.
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
A List obtained as a section of another List.
Definition: SubList.H:53
List< Face > & storedFaces()
Non-const access to the faces.
void setZones(const surfZoneList &)
Set zone ids and zones.
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:139
virtual void remapFaces(const labelUList &faceMap)
Set new zones from faceMap.
static void write(const fileName &, const UnsortedMeshedSurface< Face > &)
Write to file.
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:109
surfZoneList sortedZones(labelList &faceMap) const
Sort faces according to zoneIds.
const Field< point > & points() const
Return reference to global points.
virtual void reset(const Xfer< pointField > &, const Xfer< List< Face > > &, const Xfer< List< label > > &zoneIds)
Transfer components (points, faces, zone ids).
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?