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 | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2016-2021 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "MeshedSurface.H"
31#include "MeshedSurfaceProxy.H"
32#include "Fstream.H"
33#include "Time.H"
34#include "ListOps.H"
35#include "polyBoundaryMesh.H"
36#include "polyMesh.H"
37
38// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
39
40template<class Face>
42{
43 return wordHashSet(*fileExtensionConstructorTablePtr_);
44}
45
46
47template<class Face>
49{
50 return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
51}
52
53
54template<class Face>
56(
57 const word& fileType,
58 bool verbose
59)
60{
61 return fileFormats::surfaceFormatsCore::checkSupport
62 (
63 readTypes() | MeshReference::readTypes(),
64 fileType,
65 verbose,
66 "reading"
67 );
68}
69
70
71template<class Face>
73(
74 const word& fileType,
75 bool verbose
76)
77{
78 return fileFormats::surfaceFormatsCore::checkSupport
79 (
80 writeTypes(),
81 fileType,
82 verbose,
83 "writing"
84 );
85}
86
87
88template<class Face>
90(
91 const fileName& name,
92 bool verbose
93)
94{
95 word ext(name.ext());
96 if (ext == "gz")
97 {
98 ext = name.lessExt().ext();
99 }
100 return canReadType(ext, verbose);
101}
102
103
104template<class Face>
106(
107 const fileName& name,
108 const UnsortedMeshedSurface<Face>& surf,
109 IOstreamOption streamOpt,
110 const dictionary& options
111)
112{
113 write(name, name.ext(), surf, streamOpt, options);
114}
115
116
117template<class Face>
119(
120 const fileName& name,
121 const word& fileType,
122 const UnsortedMeshedSurface<Face>& surf,
123 IOstreamOption streamOpt,
124 const dictionary& options
125)
126{
127 if (fileType.empty())
128 {
129 // Handle empty/missing type
130
131 const word ext(name.ext());
132
133 if (ext.empty())
134 {
136 << "Cannot determine format from filename" << nl
137 << " " << name << nl
138 << exit(FatalError);
139 }
140
141 write(name, ext, surf, streamOpt, options);
142 return;
143 }
144
145
146 DebugInFunction << "Writing to " << name << nl;
147
148 auto* mfuncPtr = writefileExtensionMemberFunctionTable(fileType);
149
150 if (!mfuncPtr)
151 {
152 // Delegate to proxy if possible
153 const wordHashSet delegate(ProxyType::writeTypes());
154
155 if (!delegate.found(fileType))
156 {
158 << "Unknown write format " << fileType << nl << nl
159 << "Valid types:" << nl
160 << flatOutput((delegate | writeTypes()).sortedToc()) << nl
161 << exit(FatalError);
162 }
163
165 (
166 name, fileType, streamOpt, options
167 );
168 }
169 else
170 {
171 mfuncPtr(name, surf, streamOpt, options);
172 }
173}
174
175
176// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
177
178template<class Face>
180:
182{}
183
184
185template<class Face>
187(
189)
190:
191 MeshReference(surf.points(), surf.surfFaces()), // Copy construct (no zones)
192 zoneIds_(surf.zoneIds()),
193 zoneToc_(surf.zoneToc())
194{}
195
196
197template<class Face>
199(
200 const MeshedSurface<Face>& surf
201)
202:
203 MeshReference(surf.points(), surf.surfFaces()), // Copy construct (no zones)
204 zoneIds_(),
205 zoneToc_()
206{
207 setZones(surf.surfZones());
208}
209
210
211template<class Face>
213(
215)
216:
218{
219 transfer(surf);
220}
221
222
223template<class Face>
225(
227)
228:
230{
231 transfer(surf);
232}
233
234
235template<class Face>
237(
238 pointField&& pointLst,
239 List<Face>&& faceLst,
240 List<label>&& zoneIds,
242)
243:
244 MeshReference(std::move(pointLst), std::move(faceLst)),
245 zoneIds_(std::move(zoneIds)),
246 zoneToc_(tocInfo)
247{}
248
249
250template<class Face>
252(
253 const fileName& name,
254 const word& ext
255)
256:
258{
259 read(name, ext);
260}
261
262
263template<class Face>
265(
266 const fileName& name
267)
268:
270{
271 read(name);
272}
273
274
275template<class Face>
277(
278 Istream& is
279)
280:
282{
283 readIstream(is);
284}
285
286
287template<class Face>
289(
290 const Time& runTime
291)
292:
294{
296 transfer(surf);
297}
298
299
300template<class Face>
302(
303 const Time& runTime,
304 const word& surfName
305)
306:
308{
309 MeshedSurface<Face> surf(runTime, surfName);
310 transfer(surf);
311}
312
313
314template<class Face>
316(
317 const IOobject& io,
318 const dictionary& dict,
319 const bool isGlobal
320)
321:
323{
324 fileName fName
325 (
327 );
328
329 this->read(fName, dict.getOrDefault<word>("fileType", word::null));
330
331 this->scalePoints(dict.getOrDefault<scalar>("scale", 0));
332}
333
334
335// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
336
337template<class Face>
339{
340 this->removeZones(); // Parent information is unreliable
341
342 zoneIds_.resize(size());
343 zoneIds_ = 0;
344
345 // Assign single default zone
346 zoneToc_.resize(1);
347
348 zoneToc_[0].index() = 0;
349
350 if (zoneToc_[0].name().empty())
351 {
352 zoneToc_[0].name() = "zone0";
353 }
354}
355
356
357template<class Face>
359(
360 const surfZoneList& zoneLst
361)
362{
363 this->removeZones(); // Parent information is unreliable
364
365 zoneIds_.resize(size());
366 zoneToc_.resize(zoneLst.size());
367
368 forAll(zoneToc_, zonei)
369 {
370 const surfZone& zone = zoneLst[zonei];
371 zoneToc_[zonei] = zone;
372
373 // Assign sub-zone Ids
374 SubList<label>(zoneIds_, zone.range()) = zonei;
375 }
376}
377
378
379template<class Face>
381(
382 const labelUList& sizes,
383 const UList<word>& names
384)
385{
386 this->removeZones(); // Parent information is unreliable
387
388 zoneIds_.resize(size());
389 zoneToc_.resize(sizes.size());
390
391 label start = 0;
392 forAll(zoneToc_, zonei)
393 {
394 zoneToc_[zonei] = surfZoneIdentifier(names[zonei], zonei);
395
396 // Assign sub-zone Ids
397 SubList<label>(zoneIds_, sizes[zonei], start) = zonei;
398
399 start += sizes[zonei];
400 }
401}
402
403
404template<class Face>
406(
407 const labelUList& sizes
408)
409{
410 this->removeZones(); // Parent information is unreliable
411
412 zoneIds_.resize(size());
413 zoneToc_.resize(sizes.size());
414
415 label start = 0;
416 forAll(zoneToc_, zonei)
417 {
418 zoneToc_[zonei] = surfZoneIdentifier
419 (
421 zonei
422 );
423
424 // Assign sub-zone Ids
425 SubList<label>(zoneIds_, sizes[zonei], start) = zonei;
426
427 start += sizes[zonei];
428 }
429}
430
431
432template<class Face>
434(
435 const labelUList& faceMapNewToOld
436)
437{
438 // Re-assign the zone Ids
439 if (faceMapNewToOld.empty())
440 {
441 return;
442 }
443
444 if (zoneToc_.empty())
445 {
446 setOneZone();
447 }
448 else if (zoneToc_.size() == 1)
449 {
450 zoneIds_ = 0; // Optimized for single-zone case
451 }
452 else
453 {
454 List<label> newZonesIds(faceMapNewToOld.size());
455
456 forAll(faceMapNewToOld, facei)
457 {
458 newZonesIds[facei] = zoneIds_[faceMapNewToOld[facei]];
459 }
460 zoneIds_.transfer(newZonesIds);
461 }
462}
463
464
465// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
466
467template<class Face>
469{
470 is >> this->storedZoneIds()
471 >> this->storedPoints()
472 >> this->storedFaces();
473
475 return true;
476}
477
478
479template<class Face>
481{
482 os << this->zoneIds()
483 << this->points()
484 << this->surfFaces();
485
487}
488
489
490template<class Face>
492{
493 this->storedFaces().resize(s);
494 // if zones extend: set with last zoneId
495 zoneIds_.resize(s, zoneToc_.size() - 1);
496}
497
498
499template<class Face>
501{
502 MeshReference::clear();
503 zoneIds_.clear();
504 zoneToc_.clear();
505}
506
507
508template<class Face>
510(
512) const
513{
514 // supply some zone names
515 Map<word> zoneNames;
516 forAll(zoneToc_, zonei)
517 {
518 zoneNames.insert(zonei, zoneToc_[zonei].name());
519 }
520
521 // std::sort() really seems to mix up the order.
522 // and std::stable_sort() might take too long / too much memory
523
524 // Assuming that we have relatively fewer zones compared to the
525 // number of items, just do it ourselves
526
527 // Step 1: get zone sizes and store (origId => zoneI)
529 for (const label origId : zoneIds_)
530 {
531 ++(lookup(origId, 0));
532 }
533
534 // Step 2: assign start/size (and name) to the newZones
535 // re-use the lookup to map (zoneId => zoneI)
536 surfZoneList zoneLst(lookup.size());
537 label start = 0;
538 label zonei = 0;
539 forAllIters(lookup, iter)
540 {
541 const label origId = iter.key();
542
543 const word zoneName =
544 zoneNames.lookup
545 (
546 origId,
548 );
549
550 zoneLst[zonei] = surfZone
551 (
552 zoneName,
553 0, // initialize with zero size
554 start,
555 zonei
556 );
557
558 // increment the start for the next zone
559 // and save the (zoneId => zoneI) mapping
560 start += iter();
561 iter() = zonei++;
562 }
563
564
565 // Step 3: build the re-ordering
566 faceMap.resize(zoneIds_.size());
567
568 forAll(zoneIds_, facei)
569 {
570 const label zonei = lookup[zoneIds_[facei]];
571 faceMap[facei] = zoneLst[zonei].start() + zoneLst[zonei].size()++;
572 }
573
574 // With reordered faces registered in faceMap
575 return zoneLst;
576}
577
578
579template<class Face>
582(
583 const labelList& pointMap,
584 const labelList& faceMap
585) const
586{
587 const pointField& locPoints = this->localPoints();
588 const List<Face>& locFaces = this->localFaces();
589
590 // Subset of points (compact)
591 pointField newPoints(UIndirectList<point>(locPoints, pointMap));
592
593 // Inverse point mapping - same as ListOps invert() without checks
594 labelList oldToNew(locPoints.size(), -1);
595 forAll(pointMap, pointi)
596 {
597 oldToNew[pointMap[pointi]] = pointi;
598 }
599
600 // Subset of faces
601 List<Face> newFaces(UIndirectList<Face>(locFaces, faceMap));
602
603 // Renumber face node labels
604 for (auto& f : newFaces)
605 {
606 for (label& vert : f)
607 {
608 vert = oldToNew[vert];
609 }
610 }
611 oldToNew.clear();
612
613 // Subset of zones
614 List<label> newZones(UIndirectList<label>(zoneIds_, faceMap));
615
616 // Retain the same zone toc information
617 List<surfZoneIdentifier> subToc(zoneToc_);
618
619 // Construct the sub-surface
620 return UnsortedMeshedSurface<Face>
621 (
622 std::move(newPoints),
623 std::move(newFaces),
624 std::move(newZones),
625 std::move(subToc)
626 );
627}
628
629
630template<class Face>
633(
634 const UList<bool>& include,
635 labelList& pointMap,
637) const
638{
639 this->subsetMeshMap(include, pointMap, faceMap);
640 return this->subsetMeshImpl(pointMap, faceMap);
641}
642
643
644template<class Face>
647(
648 const bitSet& include,
649 labelList& pointMap,
651) const
652{
653 this->subsetMeshMap(include, pointMap, faceMap);
654 return this->subsetMeshImpl(pointMap, faceMap);
655}
656
657
658template<class Face>
661(
662 const UList<bool>& include
663) const
664{
665 labelList pointMap, faceMap;
666 return this->subsetMesh(include, pointMap, faceMap);
667}
668
669
670template<class Face>
673(
674 const bitSet& include
675) const
676{
677 labelList pointMap, faceMap;
678 return this->subsetMesh(include, pointMap, faceMap);
679}
680
681
682template<class Face>
684(
686)
687{
688 if (this == &surf)
689 {
690 return; // Self-swap is a no-op
691 }
692
693 this->clearOut(); // Topology changes
694 surf.clearOut(); // Topology changes
695
696 this->storedPoints().swap(surf.storedPoints());
697 this->storedFaces().swap(surf.storedFaces());
698 zoneIds_.swap(surf.zoneIds_);
699 zoneToc_.swap(surf.zoneToc_);
700
701 this->storedZones().clear(); // Should not be there anyhow
702 surf.storedZones().clear();
703}
704
705
706template<class Face>
708(
710)
711{
712 if (this == &surf)
713 {
714 return; // Self-assignment is a no-op
715 }
716
717 this->clear();
718
719 this->storedPoints().transfer(surf.storedPoints());
720 this->storedFaces().transfer(surf.storedFaces());
721 zoneIds_.transfer(surf.zoneIds_);
722 zoneToc_.transfer(surf.zoneToc_);
723
724 surf.clear();
725}
726
727
728template<class Face>
730(
732)
733{
734 surfZoneList zoneInfo(surf.surfZones());
735
736 this->clear();
737
738 MeshReference::transfer(surf);
739
740 setZones(zoneInfo);
741}
742
743
744template<class Face>
747{
748 return autoPtr<labelList>::New(this->storedZoneIds());
749}
750
751
752template<class Face>
754{
755 this->clear();
756 transfer(*New(name));
757 return true;
758}
759
760
761template<class Face>
763(
764 const fileName& name,
765 const word& fileType
766)
767{
768 this->clear();
769 transfer(*New(name, fileType));
770 return true;
771}
772
773
774template<class Face>
776(
777 const Time& t,
778 const word& surfName
779) const
780{
781 MeshedSurfaceProxy<Face>(*this).write(t, surfName);
782}
783
784
785// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
786
787template<class Face>
789(
791)
792{
793 if (&surf == this)
794 {
795 return; // Self-assignment is a no-op
796 }
797
798 clear();
799
800 this->storedPoints() = surf.points();
801 this->storedFaces() = surf.surfFaces();
802 zoneIds_ = surf.zoneIds_;
803 zoneToc_ = surf.zoneToc_;
804}
805
806
807template<class Face>
809(
811)
812{
813 transfer();
814}
815
816
817template<class Face>
820{
822 List<surfZone> zoneLst = this->sortedZones(faceMap);
823
825 (
826 this->points(),
827 this->surfFaces(),
828 zoneLst,
829 faceMap
830 );
831}
832
833
834// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
835
836template<class Face>
837Foam::Istream& Foam::operator>>
838(
839 Istream& is,
840 UnsortedMeshedSurface<Face>& surf
841)
842{
843 surf.readIstream(is);
844 return is;
845}
846
847
848template<class Face>
849Foam::Ostream& Foam::operator<<
850(
851 Ostream& os,
852 const UnsortedMeshedSurface<Face>& surf
853)
854{
855 surf.writeOstream(os);
856 return os;
857}
858
859
860// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
861
863
864// ************************************************************************* //
Various functions to operate on Lists.
const T & lookup(const Key &key, const T &deflt) const
Return hashed entry if it exists, or return the given default.
Definition: HashTableI.H:224
bool found(const Key &key) const
Return true if hashed entry is found in table.
Definition: HashTableI.H:100
bool insert(const Key &key, const T &obj)
Copy insert a new entry, not overwriting existing entries.
Definition: HashTableI.H:180
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
The IOstreamOption is a simple container for options an IOstream can normally have.
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:58
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void transfer(List< T > &list)
Definition: List.C:447
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
A proxy for writing MeshedSurface, UnsortedMeshedSurface and surfMesh to various file formats.
static void write(const fileName &name, const MeshedSurfaceProxy &surf, IOstreamOption streamOpt=IOstreamOption(), const dictionary &options=dictionary::null)
Write to file, select based on its extension.
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Definition: MeshedSurface.H:99
surfZoneList & storedZones()
Non-const access to the zones.
const surfZoneList & surfZones() const
Const access to the surface zones.
pointField & storedPoints()
Non-const access to global points.
List< Face > & storedFaces()
Non-const access to the faces.
virtual void scalePoints(const scalar scaleFactor)
Scale points. A non-positive factor is ignored.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
virtual bool read()
Re-read model coefficients if they have changed.
A List obtained as a section of another List.
Definition: SubList.H:70
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
static autoPtr< Time > New()
Construct (dummy) Time - no functionObjects or libraries.
Definition: Time.C:717
A List with indirect addressing. Like IndirectList but does not store addressing.
Definition: IndirectList.H:79
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
A surface geometry mesh, in which the surface zone information is conveyed by the 'zoneId' associated...
static bool canWriteType(const word &fileType, bool verbose=false)
Can we write this file format? Also checks friend types.
autoPtr< labelList > releaseZoneIds()
Release (clear) stored zoneIds and return for reuse.
surfZoneList sortedZones(labelList &faceMap) const
Sort faces according to zoneIds.
static wordHashSet writeTypes()
Known writable file-types, without friends or proxies.
virtual void remapFaces(const labelUList &faceMapNewToOld)
Set new zones from faceMap.
void setZones(const surfZoneList &zoneLst)
Set zone ids and zones.
static bool canReadType(const word &fileType, bool verbose=false)
Can we read this file format? Also checks friend types.
void transfer(UnsortedMeshedSurface< Face > &surf)
Transfer the contents of the argument and annul the argument.
bool read(const fileName &name, const word &fileType)
Read from file with given format type.
static bool canRead(const fileName &name, bool verbose=false)
Can we read this file format?
void setOneZone()
Set zones to 0 and set a single zone.
virtual void clear()
Clear all storage.
void swap(MeshedSurface< Face > &surf)=delete
Swap contents - disabled.
UnsortedMeshedSurface subsetMesh(const UList< bool > &include, labelList &pointMap, labelList &faceMap) const
Return a new surface subsetted on the selected faces.
static wordHashSet readTypes()
Known readable file-types, without friends or proxies.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition: autoPtr.H:66
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
static word defaultName
The default cloud name: defaultCloud.
Definition: cloud.H:90
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
T getOrDefault(const word &keyword, const T &deflt, enum keyType::option matchOpt=keyType::REGEX) const
static fileName checkFile(const IOobject &io, const bool isGlobal=true)
Return fileName to load IOobject from.
A class for handling file names.
Definition: fileName.H:76
virtual bool write()
Write the output fields.
Lookup type of boundary radiation properties.
Definition: lookup.H:66
Identifies a surface patch/zone by name and index, with optional geometric type.
A surface zone on a MeshedSurface.
Definition: surfZone.H:59
A class for handling words, derived from Foam::string.
Definition: word.H:68
word ext() const
Return file name extension (part after last .)
Definition: word.C:126
word lessExt() const
Return word without extension (part before last .)
Definition: word.C:113
Base class for mesh zones.
Definition: zone.H:67
patchWriters clear()
engineTime & runTime
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
const pointField & points
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.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))
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
#define FUNCTION_NAME
#define DebugInFunction
Report an information message using Foam::Info.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh > > &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
error FatalError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
runTime write()
labelList f(nPoints)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:260