UnsortedMeshedSurface.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2021 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  InfoInFunction << "Writing to " << name << endl;
111  }
112 
113  const word ext = name.ext();
114 
115  typename writefileExtensionMemberFunctionTable::iterator mfIter =
116  writefileExtensionMemberFunctionTablePtr_->find(ext);
117 
118  if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
119  {
120  // no direct writer, delegate to proxy if possible
121  wordHashSet supported = ProxyType::writeTypes();
122 
123  if (supported.found(ext))
124  {
125  MeshedSurfaceProxy<Face>(surf).write(name);
126  }
127  else
128  {
130  << "Unknown file extension " << ext << nl << nl
131  << "Valid types are :" << endl
132  << (supported | writeTypes())
133  << exit(FatalError);
134  }
135  }
136  else
137  {
138  mfIter()(name, surf);
139  }
140 }
141 
142 
143 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
144 
145 template<class Face>
147 :
148  ParentType()
149 {}
150 
151 
152 template<class Face>
154 (
155  pointField&& pointLst,
156  List<Face>&& faceLst,
158  surfZoneIdentifierList&& zoneTofc
159 )
160 :
161  ParentType(move(pointLst), move(faceLst)),
162  zoneIds_(move(zoneIds)),
163  zoneToc_(move(zoneTofc))
164 {}
165 
166 
167 template<class Face>
169 (
170  pointField&& pointLst,
171  List<Face>&& faceLst,
172  const labelUList& zoneSizes,
173  const UList<word>& zoneNames
174 )
175 :
176  ParentType(move(pointLst), move(faceLst))
177 {
178  if (zoneSizes.size())
179  {
180  if (zoneNames.size())
181  {
182  setZones(zoneSizes, zoneNames);
183  }
184  else
185  {
186  setZones(zoneSizes);
187  }
188  }
189  else
190  {
191  setOneZone();
192  }
193 }
194 
195 
196 template<class Face>
198 (
199  const UnsortedMeshedSurface<Face>& surf
200 )
201 :
202  ParentType
203  (
204  surf.points(),
205  surf.faces()
206  ),
207  zoneIds_(surf.zoneIds()),
208  zoneToc_(surf.zoneToc())
209 {}
210 
211 
212 template<class Face>
214 (
215  const MeshedSurface<Face>& surf
216 )
217 :
218  ParentType
219  (
220  surf.points(),
221  surf.faces()
222  )
223 {
224  setZones(surf.surfZones());
225 }
226 
227 
228 template<class Face>
230 (
232 )
233 :
234  ParentType()
235 {
236  transfer(surf);
237 }
238 
239 
240 template<class Face>
242 (
243  MeshedSurface<Face>&& surf
244 )
245 :
246  ParentType()
247 {
248  transfer(surf);
249 }
250 
251 
252 template<class Face>
254 (
255  const fileName& name,
256  const word& ext
257 )
258 :
259  ParentType()
260 {
261  read(name, ext);
262 }
263 
264 
265 template<class Face>
267 :
268  ParentType()
269 {
270  read(name);
271 }
272 
273 
274 template<class Face>
276 (
277  const Time& t,
278  const word& surfName
279 )
280 :
281  ParentType()
282 {
283  MeshedSurface<Face> surf(t, surfName);
284  transfer(surf);
285 }
286 
287 
288 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
289 
290 template<class Face>
292 {}
293 
294 
295 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
296 
297 template<class Face>
299 {
300  zoneIds_.setSize(size());
301  zoneIds_ = 0;
302 
303  word zoneName;
304  if (zoneToc_.size())
305  {
306  zoneName = zoneToc_[0].name();
307  }
308  if (zoneName.empty())
309  {
310  zoneName = "zone0";
311  }
312 
313  // set single default zone
314  zoneToc_.setSize(1);
315  zoneToc_[0] = surfZoneIdentifier(zoneName, 0);
316 }
317 
318 
319 template<class Face>
321 (
322  const surfZoneList& zoneLst
323 )
324 {
325  zoneIds_.setSize(size());
326  zoneToc_.setSize(zoneLst.size());
327 
328  forAll(zoneToc_, zoneI)
329  {
330  const surfZone& zone = zoneLst[zoneI];
331  zoneToc_[zoneI] = zone;
332 
333  // assign sub-zone Ids
334  SubList<label> subZone(zoneIds_, zone.size(), zone.start());
335  subZone = zoneI;
336  }
337 }
338 
339 
340 template<class Face>
342 (
343  const labelUList& sizes,
344  const UList<word>& names
345 )
346 {
347  zoneIds_.setSize(size());
348  zoneToc_.setSize(sizes.size());
349 
350  label start = 0;
351  forAll(zoneToc_, zoneI)
352  {
353  zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);
354 
355  // assign sub-zone Ids
356  SubList<label> subZone(zoneIds_, sizes[zoneI], start);
357  subZone = zoneI;
358 
359  start += sizes[zoneI];
360  }
361 }
362 
363 
364 template<class Face>
366 (
367  const labelUList& sizes
368 )
369 {
370  zoneIds_.setSize(size());
371  zoneToc_.setSize(sizes.size());
372 
373  label start = 0;
374  forAll(zoneToc_, zoneI)
375  {
376  zoneToc_[zoneI] = surfZoneIdentifier
377  (
378  word("zone") + ::Foam::name(zoneI),
379  zoneI
380  );
381 
382  // assign sub-zone Ids
383  SubList<label> subZone(zoneIds_, sizes[zoneI], start);
384  subZone = zoneI;
385 
386  start += sizes[zoneI];
387  }
388 }
389 
390 
391 template<class Face>
393 (
394  const labelUList& faceMap
395 )
396 {
397  // re-assign the zone Ids
398  if (notNull(faceMap) && faceMap.size())
399  {
400  if (zoneToc_.empty())
401  {
402  setOneZone();
403  }
404  else if (zoneToc_.size() == 1)
405  {
406  // optimised for single-zone case
407  zoneIds_ = 0;
408  }
409  else
410  {
411  List<label> newZones(faceMap.size());
412 
413  forAll(faceMap, facei)
414  {
415  newZones[facei] = zoneIds_[faceMap[facei]];
416  }
417  zoneIds_.transfer(newZones);
418  }
419  }
420 }
421 
422 
423 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
424 
425 template<class Face>
427 {
428  this->storedFaces().setSize(s);
429  // if zones extend: set with last zoneId
430  zoneIds_.setSize(s, zoneToc_.size() - 1);
431 }
432 
433 
434 template<class Face>
436 {
438  zoneIds_.clear();
439  zoneToc_.clear();
440 }
441 
442 
443 template<class Face>
445 (
446  labelList& faceMap
447 ) const
448 {
449  // supply some zone names
450  Map<word> zoneNames;
451  forAll(zoneToc_, zoneI)
452  {
453  zoneNames.insert(zoneI, zoneToc_[zoneI].name());
454  }
455 
456  // std::sort() really seems to mix up the order.
457  // and std::stable_sort() might take too long / too much memory
458 
459  // Assuming that we have relatively fewer zones compared to the
460  // number of items, just do it ourselves
461 
462  // step 1: get zone sizes and store (origId => zoneI)
464  forAll(zoneIds_, facei)
465  {
466  const label origId = zoneIds_[facei];
467 
468  Map<label>::iterator fnd = lookup.find(origId);
469  if (fnd != lookup.end())
470  {
471  fnd()++;
472  }
473  else
474  {
475  lookup.insert(origId, 1);
476  }
477  }
478 
479  // step 2: assign start/size (and name) to the newZones
480  // re-use the lookup to map (zoneId => zoneI)
481  surfZoneList zoneLst(lookup.size());
482  label start = 0;
483  label zoneI = 0;
484  forAllIter(Map<label>, lookup, iter)
485  {
486  label origId = iter.key();
487 
488  word name;
489  Map<word>::const_iterator fnd = zoneNames.find(origId);
490  if (fnd != zoneNames.end())
491  {
492  name = fnd();
493  }
494  else
495  {
496  name = word("zone") + ::Foam::name(zoneI);
497  }
498 
499  zoneLst[zoneI] = surfZone
500  (
501  name,
502  0, // initialise with zero size
503  start,
504  zoneI
505  );
506 
507  // increment the start for the next zone
508  // and save the (zoneId => zoneI) mapping
509  start += iter();
510  iter() = zoneI++;
511  }
512 
513 
514  // step 3: build the re-ordering
515  faceMap.setSize(zoneIds_.size());
516 
517  forAll(zoneIds_, facei)
518  {
519  label zoneI = lookup[zoneIds_[facei]];
520  faceMap[facei] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
521  }
522 
523  // with reordered faces registered in faceMap
524  return zoneLst;
525 }
526 
527 
528 template<class Face>
531 (
532  const labelHashSet& include,
533  labelList& pointMap,
534  labelList& faceMap
535 ) const
536 {
537  const pointField& locPoints = this->localPoints();
538  const List<Face>& locFaces = this->localFaces();
539 
540  // Fill pointMap, faceMap
541  PatchTools::subsetMap(*this, include, pointMap, faceMap);
542 
543  // Create compact coordinate list and forward mapping array
544  pointField newPoints(pointMap.size());
545  labelList oldToNew(locPoints.size());
546  forAll(pointMap, pointi)
547  {
548  newPoints[pointi] = locPoints[pointMap[pointi]];
549  oldToNew[pointMap[pointi]] = pointi;
550  }
551 
552  // Renumber face node labels and compact
553  List<Face> newFaces(faceMap.size());
554  List<label> newZones(faceMap.size());
555 
556  forAll(faceMap, facei)
557  {
558  const label origFacei = faceMap[facei];
559  newFaces[facei] = Face(locFaces[origFacei]);
560 
561  // Renumber labels for face
562  Face& f = newFaces[facei];
563  forAll(f, fp)
564  {
565  f[fp] = oldToNew[f[fp]];
566  }
567 
568  newZones[facei] = zoneIds_[origFacei];
569  }
570  oldToNew.clear();
571 
572  // construct a sub-surface
573  return UnsortedMeshedSurface
574  (
575  move(newPoints),
576  move(newFaces),
577  move(newZones),
578  List<surfZoneIdentifier>(zoneToc_)
579  );
580 }
581 
582 
583 template<class Face>
585 (
586  const labelHashSet& include
587 ) const
588 {
589  labelList pointMap, faceMap;
590  return subsetMesh(include, pointMap, faceMap);
591 }
592 
593 
594 template<class Face>
596 (
597  pointField&& pointLst,
598  List<Face>&& faceLst,
600 )
601 {
603  (
604  move(pointLst),
605  move(faceLst),
606  NullObjectMove<surfZoneList>()
607  );
608 
609  if (notNull(zoneIds))
610  {
611  zoneIds_.transfer(zoneIds);
612  }
613 }
614 
615 
616 template<class Face>
618 (
619  List<point>&& pointLst,
620  List<Face>&& faceLst,
622 )
623 {
625  (
626  move(pointLst),
627  move(faceLst),
628  NullObjectMove<surfZoneList>()
629  );
630 
631  if (notNull(zoneIds))
632  {
633  zoneIds_.transfer(zoneIds);
634  }
635 }
636 
637 
638 template<class Face>
640 (
642 )
643 {
645  (
646  move(surf.storedPoints()),
647  move(surf.storedFaces()),
648  NullObjectMove<surfZoneList>()
649  );
650 
651  zoneIds_.transfer(surf.zoneIds_);
652  zoneToc_.transfer(surf.zoneToc_);
653 
654  surf.clear();
655 }
656 
657 
658 template<class Face>
660 (
661  MeshedSurface<Face>& surf
662 )
663 {
665  (
666  move(surf.storedPoints()),
667  move(surf.storedFaces()),
668  NullObjectMove<surfZoneList>()
669  );
670 
671  setZones(surf.surfZones());
672  surf.clear();
673 }
674 
675 
676 // Read from file, determine format from extension
677 template<class Face>
679 {
680  word ext = name.ext();
681  if (ext == "gz")
682  {
683  fileName unzipName = name.lessExt();
684  return read(unzipName, unzipName.ext());
685  }
686  else
687  {
688  return read(name, ext);
689  }
690 }
691 
692 
693 // Read from file in given format
694 template<class Face>
696 (
697  const fileName& name,
698  const word& ext
699 )
700 {
701  clear();
702 
703  // read via use selector mechanism
704  transfer(New(name, ext)());
705  return true;
706 }
707 
708 
709 template<class Face>
711 (
712  const Time& t,
713  const word& surfName
714 ) const
715 {
716  MeshedSurfaceProxy<Face>(*this).write(t, surfName);
717 }
718 
719 
720 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
721 
722 template<class Face>
723 void Foam::UnsortedMeshedSurface<Face>::operator=
724 (
725  const UnsortedMeshedSurface<Face>& surf
726 )
727 {
728  clear();
729 
730  this->storedPoints() = surf.points();
731  this->storedFaces() = surf.faces();
732  zoneIds_ = surf.zoneIds_;
733  zoneToc_ = surf.zoneToc_;
734 }
735 
736 
737 template<class Face>
738 Foam::UnsortedMeshedSurface<Face>::operator
740 {
742  List<surfZone> zoneLst = this->sortedZones(faceMap);
743 
745  (
746  this->points(),
747  this->faces(),
748  zoneLst,
749  faceMap
750  );
751 }
752 
753 
754 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
755 
757 
758 // ************************************************************************* //
A surface geometry mesh, in which the surface zone information is conveyed by the &#39;zoneId&#39; associated...
Definition: MeshedSurface.H:74
virtual void clear()
Clear all storage.
bool read(const fileName &, const word &ext)
Read from file. Chooses reader based on explicit extension.
A HashTable with keys but without contents.
Definition: HashSet.H:59
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
virtual void reset(pointField &&, List< Face > &&, List< label > &&zoneIds)
Transfer components (points, faces, zone ids).
A class for handling file names.
Definition: fileName.H:79
An identifier for a surface zone on a meshed surface.
An STL-conforming const_iterator.
Definition: HashTable.H:481
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: MeshedSurface.H:72
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:459
A surface zone on a MeshedSurface.
Definition: surfZone.H:62
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
const List< label > & zoneIds() const
Return const access to the zone ids.
virtual void clear()
Clear all storage.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
void transfer(UnsortedMeshedSurface< Face > &)
Transfer the contents of the argument and annul the argument.
static bool canRead(const fileName &, const bool verbose=false)
Can we read this file format?
label size() const
Return size of this zone in the face list.
Definition: surfZone.H:141
const Field< PointType > & localPoints() const
Return pointField of points in patch.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
virtual ~UnsortedMeshedSurface()
Destructor.
word ext() const
Return file name extension (part after last .)
Definition: fileName.C:299
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
label size() const
The surface size is the number of faces.
bool insert(const label &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:142
UnsortedMeshedSurface subsetMesh(const labelHashSet &include, labelList &pointMap, labelList &faceMap) const
Return new surface.
A List obtained as a section of another List.
Definition: SubList.H:53
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))
stressControl lookup("compactNormalStress") >> compactNormalStress
List< Face > & storedFaces()
Non-const access to the faces.
bool found(const Key &) const
Return true if hashedEntry is found in table.
Definition: HashTable.C:113
Base class for zones.
Definition: zone.H:57
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
A class for handling words, derived from string.
Definition: word.H:59
pointField & storedPoints()
Non-const access to global points.
const Field< PointType > & points() const
Return reference to global points.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
virtual void remapFaces(const labelUList &faceMap)
Set new zones from faceMap.
HashSet wordHashSet
A HashSet with word keys.
Definition: HashSet.H:208
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
virtual void reset(pointField &&points, List< Face > &&faces, surfZoneList &&zones)
Reset primitive data (points, faces and zones)
static const char nl
Definition: Ostream.H:260
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats...
Definition: MeshedSurface.H:73
labelList f(nPoints)
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
const List< Face > & faces() const
Return const access to the faces.
const List< surfZoneIdentifier > & zoneToc() const
Return const access to the zone table-of-contents.
surfZoneList sortedZones(labelList &faceMap) const
Sort faces according to zoneIds.
bool notNull(const T &t)
Return true if t is not a reference to the nullObject of type T.
Definition: nullObjectI.H:52
void setSize(const label)
Reset size of List.
Definition: List.C:281
static void write(const fileName &, const MeshedSurfaceProxy< Face > &)
Write to file.
label start() const
Return start label of this zone in the face list.
Definition: surfZone.H:129
static bool canReadType(const word &ext, const bool verbose=false)
Can we read this file format?
void setZones(const surfZoneList &)
Set zone ids and zones.
static void write(const fileName &, const UnsortedMeshedSurface< Face > &)
Write to file.
const List< FaceType > & localFaces() const
Return patch faces addressing into local point list.
fileName lessExt() const
Return file name without extension (part before last .)
Definition: fileName.C:284
static void subsetMap(const PrimitivePatch< FaceList, PointField > &p, const BoolListType &includeFaces, labelList &pointMap, labelList &faceMap)
Determine the mapping for a sub-patch.
static bool canWriteType(const word &ext, const bool verbose=false)
Can we write this file format?
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
static autoPtr< UnsortedMeshedSurface > New(const fileName &, const word &ext)
Select constructed from filename (explicit extension)
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
const List< surfZone > & surfZones() const
Const access to the surface zones.
A HashTable to objects of type <T> with a label key.
Definition: Map.H:49
void setOneZone()
Set zones to 0 and set a single zone.
#define InfoInFunction
Report an information message using Foam::Info.