ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / surfMesh / UnsortedMeshedSurface / UnsortedMeshedSurface.C
blob7f6de73066b21b61df91c433f58ce8b8b081bd1b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 \*---------------------------------------------------------------------------*/
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"
35 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
37 template<class Face>
38 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::readTypes()
40     return wordHashSet(*fileExtensionConstructorTablePtr_);
44 template<class Face>
45 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::writeTypes()
47     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
51 template<class Face>
52 bool Foam::UnsortedMeshedSurface<Face>::canReadType
54     const word& ext,
55     const bool verbose
58    return fileFormats::surfaceFormatsCore::checkSupport
59    (
60        readTypes() | ParentType::readTypes(),
61        ext,
62        verbose,
63        "reading"
64    );
68 template<class Face>
69 bool Foam::UnsortedMeshedSurface<Face>::canWriteType
71     const word& ext,
72     const bool verbose
75     return fileFormats::surfaceFormatsCore::checkSupport
76     (
77         writeTypes(),
78         ext,
79         verbose,
80         "writing"
81     );
85 template<class Face>
86 bool Foam::UnsortedMeshedSurface<Face>::canRead
88     const fileName& name,
89     const bool verbose
92     word ext = name.ext();
93     if (ext == "gz")
94     {
95         ext = name.lessExt().ext();
96     }
97     return canReadType(ext, verbose);
101 template<class Face>
102 void Foam::UnsortedMeshedSurface<Face>::write
104     const fileName& name,
105     const UnsortedMeshedSurface<Face>& surf
108     if (debug)
109     {
110         Info<< "UnsortedMeshedSurface::write"
111             "(const fileName&, const UnsortedMeshedSurface&) : "
112             "writing to " << name
113             << endl;
114     }
116     const word ext = name.ext();
118     typename writefileExtensionMemberFunctionTable::iterator mfIter =
119         writefileExtensionMemberFunctionTablePtr_->find(ext);
121     if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
122     {
123         // no direct writer, delegate to proxy if possible
124         wordHashSet supported = ProxyType::writeTypes();
126         if (supported.found(ext))
127         {
128             MeshedSurfaceProxy<Face>(surf).write(name);
129         }
130         else
131         {
132             FatalErrorIn
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     }
149 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
151 template<class Face>
152 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface()
154     ParentType()
158 template<class Face>
159 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
161     const Xfer<pointField>& pointLst,
162     const Xfer<List<Face> >& faceLst,
163     const Xfer<List<label> >& zoneIds,
164     const Xfer<surfZoneIdentifierList>& zoneTofc
167     ParentType(pointLst, faceLst),
168     zoneIds_(zoneIds),
169     zoneToc_(zoneTofc)
173 template<class Face>
174 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
176     const Xfer<pointField>& pointLst,
177     const Xfer<List<Face> >& faceLst,
178     const labelUList& zoneSizes,
179     const UList<word>& zoneNames
182     ParentType(pointLst, faceLst)
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     }
202 template<class Face>
203 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
205     const UnsortedMeshedSurface<Face>& surf
208     ParentType
209     (
210         xferCopy(surf.points()),
211         xferCopy(surf.faces())
212     ),
213     zoneIds_(surf.zoneIds()),
214     zoneToc_(surf.zoneToc())
218 template<class Face>
219 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
221     const MeshedSurface<Face>& surf
224     ParentType
225     (
226         xferCopy(surf.points()),
227         xferCopy(surf.faces())
228     )
230     setZones(surf.surfZones());
234 template<class Face>
235 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
237     const Xfer<UnsortedMeshedSurface<Face> >& surf
240     ParentType()
242     transfer(surf());
246 template<class Face>
247 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
249     const Xfer<MeshedSurface<Face> >& surf
252     ParentType()
254     transfer(surf());
258 template<class Face>
259 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
261     const fileName& name,
262     const word& ext
265     ParentType()
267     read(name, ext);
271 template<class Face>
272 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
274     ParentType()
276     read(name);
280 template<class Face>
281 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
283     const Time& t,
284     const word& surfName
287     ParentType()
289     MeshedSurface<Face> surf(t, surfName);
290     transfer(surf);
294 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
296 template<class Face>
297 Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
301 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
303 template<class Face>
304 void Foam::UnsortedMeshedSurface<Face>::setOneZone()
306     zoneIds_.setSize(size());
307     zoneIds_ = 0;
309     word zoneName;
310     if (zoneToc_.size())
311     {
312         zoneName = zoneToc_[0].name();
313     }
314     if (zoneName.empty())
315     {
316         zoneName = "zone0";
317     }
319     // set single default zone
320     zoneToc_.setSize(1);
321     zoneToc_[0] = surfZoneIdentifier(zoneName, 0);
325 template<class Face>
326 void Foam::UnsortedMeshedSurface<Face>::setZones
328     const surfZoneList& zoneLst
331     zoneIds_.setSize(size());
332     zoneToc_.setSize(zoneLst.size());
334     forAll(zoneToc_, zoneI)
335     {
336         const surfZone& zone = zoneLst[zoneI];
337         zoneToc_[zoneI] = zone;
339         // assign sub-zone Ids
340         SubList<label> subZone(zoneIds_, zone.size(), zone.start());
341         subZone = zoneI;
342     }
346 template<class Face>
347 void Foam::UnsortedMeshedSurface<Face>::setZones
349     const labelUList& sizes,
350     const UList<word>& names
353     zoneIds_.setSize(size());
354     zoneToc_.setSize(sizes.size());
356     label start = 0;
357     forAll(zoneToc_, zoneI)
358     {
359         zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);
361         // assign sub-zone Ids
362         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
363         subZone = zoneI;
365         start += sizes[zoneI];
366     }
370 template<class Face>
371 void Foam::UnsortedMeshedSurface<Face>::setZones
373     const labelUList& sizes
376     zoneIds_.setSize(size());
377     zoneToc_.setSize(sizes.size());
379     label start = 0;
380     forAll(zoneToc_, zoneI)
381     {
382         zoneToc_[zoneI] = surfZoneIdentifier
383         (
384             word("zone") + ::Foam::name(zoneI),
385             zoneI
386         );
388         // assign sub-zone Ids
389         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
390         subZone = zoneI;
392         start += sizes[zoneI];
393     }
397 template<class Face>
398 void Foam::UnsortedMeshedSurface<Face>::remapFaces
400     const labelUList& faceMap
403     // re-assign the zone Ids
404     if (&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());
419             forAll(faceMap, faceI)
420             {
421                 newZones[faceI] = zoneIds_[faceMap[faceI]];
422             }
423             zoneIds_.transfer(newZones);
424         }
425     }
429 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
431 template<class Face>
432 void Foam::UnsortedMeshedSurface<Face>::setSize(const label s)
434     this->storedFaces().setSize(s);
435     // if zones extend: set with last zoneId
436     zoneIds_.setSize(s, zoneToc_.size() - 1);
440 template<class Face>
441 void Foam::UnsortedMeshedSurface<Face>::clear()
443     ParentType::clear();
444     zoneIds_.clear();
445     zoneToc_.clear();
449 template<class Face>
450 Foam::surfZoneList Foam::UnsortedMeshedSurface<Face>::sortedZones
452     labelList& faceMap
453 ) const
455     // supply some zone names
456     Map<word> zoneNames;
457     forAll(zoneToc_, zoneI)
458     {
459         zoneNames.insert(zoneI, zoneToc_[zoneI].name());
460     }
462     // std::sort() really seems to mix up the order.
463     // and std::stable_sort() might take too long / too much memory
465     // Assuming that we have relatively fewer zones compared to the
466     // number of items, just do it ourselves
468     // step 1: get zone sizes and store (origId => zoneI)
469     Map<label> lookup;
470     forAll(zoneIds_, faceI)
471     {
472         const label origId = zoneIds_[faceI];
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     }
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();
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         }
505         zoneLst[zoneI] = surfZone
506         (
507             name,
508             0,           // initialize with zero size
509             start,
510             zoneI
511         );
513         // increment the start for the next zone
514         // and save the (zoneId => zoneI) mapping
515         start += iter();
516         iter() = zoneI++;
517     }
520     // step 3: build the re-ordering
521     faceMap.setSize(zoneIds_.size());
523     forAll(zoneIds_, faceI)
524     {
525         label zoneI = lookup[zoneIds_[faceI]];
526         faceMap[faceI] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
527     }
529     // with reordered faces registered in faceMap
530     return zoneLst;
534 template<class Face>
535 Foam::UnsortedMeshedSurface<Face>
536 Foam::UnsortedMeshedSurface<Face>::subsetMesh
538     const labelHashSet& include,
539     labelList& pointMap,
540     labelList& faceMap
541 ) const
543     const pointField&  locPoints = this->localPoints();
544     const List<Face>&  locFaces  = this->localFaces();
546     // Fill pointMap, faceMap
547     PatchTools::subsetMap(*this, include, pointMap, faceMap);
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     }
558     // Renumber face node labels and compact
559     List<Face>  newFaces(faceMap.size());
560     List<label> newZones(faceMap.size());
562     forAll(faceMap, faceI)
563     {
564         const label origFaceI = faceMap[faceI];
565         newFaces[faceI] = Face(locFaces[origFaceI]);
567         // Renumber labels for face
568         Face& f = newFaces[faceI];
569         forAll(f, fp)
570         {
571             f[fp] = oldToNew[f[fp]];
572         }
574         newZones[faceI] = zoneIds_[origFaceI];
575     }
576     oldToNew.clear();
578     // construct a sub-surface
579     return UnsortedMeshedSurface
580     (
581         xferMove(newPoints),
582         xferMove(newFaces),
583         xferMove(newZones),
584         xferCopy(zoneToc_)
585     );
589 template<class Face>
590 Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
592     const labelHashSet& include
593 ) const
595     labelList pointMap, faceMap;
596     return subsetMesh(include, pointMap, faceMap);
600 template<class Face>
601 void Foam::UnsortedMeshedSurface<Face>::reset
603     const Xfer<pointField>& pointLst,
604     const Xfer<List<Face> >& faceLst,
605     const Xfer<List<label> >& zoneIds
608     ParentType::reset
609     (
610         pointLst,
611         faceLst,
612         Xfer<surfZoneList>()
613     );
615     if (&zoneIds)
616     {
617         zoneIds_.transfer(zoneIds());
618     }
622 template<class Face>
623 void Foam::UnsortedMeshedSurface<Face>::reset
625     const Xfer<List<point> >& pointLst,
626     const Xfer<List<Face> >& faceLst,
627     const Xfer<List<label> >& zoneIds
630     ParentType::reset
631     (
632         pointLst,
633         faceLst,
634         Xfer<surfZoneList>()
635     );
637     if (&zoneIds)
638     {
639         zoneIds_.transfer(zoneIds());
640     }
644 template<class Face>
645 void Foam::UnsortedMeshedSurface<Face>::transfer
647     UnsortedMeshedSurface<Face>& surf
650     ParentType::reset
651     (
652         xferMove(surf.storedPoints()),
653         xferMove(surf.storedFaces()),
654         Xfer<surfZoneList>()
655     );
657     zoneIds_.transfer(surf.zoneIds_);
658     zoneToc_.transfer(surf.zoneToc_);
660     surf.clear();
664 template<class Face>
665 void Foam::UnsortedMeshedSurface<Face>::transfer
667     MeshedSurface<Face>& surf
670     ParentType::reset
671     (
672         xferMove(surf.storedPoints()),
673         xferMove(surf.storedFaces()),
674         Xfer<surfZoneList>()
675     );
677     setZones(surf.surfZones());
678     surf.clear();
682 template<class Face>
683 Foam::Xfer<Foam::UnsortedMeshedSurface<Face> >
684 Foam::UnsortedMeshedSurface<Face>::xfer()
686     return xferMove(*this);
690 // Read from file, determine format from extension
691 template<class Face>
692 bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
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     }
707 // Read from file in given format
708 template<class Face>
709 bool Foam::UnsortedMeshedSurface<Face>::read
711     const fileName& name,
712     const word& ext
715     clear();
717     // read via use selector mechanism
718     transfer(New(name, ext)());
719     return true;
723 template<class Face>
724 void Foam::UnsortedMeshedSurface<Face>::write
726     const Time& t,
727     const word& surfName
728 ) const
730     MeshedSurfaceProxy<Face>(*this).write(t, surfName);
734 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
736 template<class Face>
737 void Foam::UnsortedMeshedSurface<Face>::operator=
739     const UnsortedMeshedSurface<Face>& surf
742     clear();
744     this->storedPoints() = surf.points();
745     this->storedFaces()  = surf.faces();
746     zoneIds_ = surf.zoneIds_;
747     zoneToc_ = surf.zoneToc_;
751 template<class Face>
752 Foam::UnsortedMeshedSurface<Face>::operator
753 Foam::MeshedSurfaceProxy<Face>() const
755     labelList faceMap;
756     List<surfZone> zoneLst = this->sortedZones(faceMap);
758     return MeshedSurfaceProxy<Face>
759     (
760         this->points(),
761         this->faces(),
762         zoneLst,
763         faceMap
764     );
768 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
770 #include "UnsortedMeshedSurfaceNew.C"
772 // ************************************************************************* //