Fixed URL for libccmio-2.6.1 (bug report #5 by Thomas Oliveira)
[foam-extend-3.2.git] / src / surfMesh / UnsortedMeshedSurface / UnsortedMeshedSurface.C
blobd825f3ce7b6395cfbb417dff2674141a4c283ded
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | foam-extend: Open Source CFD
4    \\    /   O peration     | Version:     3.2
5     \\  /    A nd           | Web:         http://www.foam-extend.org
6      \\/     M anipulation  | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
8 License
9     This file is part of foam-extend.
11     foam-extend is free software: you can redistribute it and/or modify it
12     under the terms of the GNU General Public License as published by the
13     Free Software Foundation, either version 3 of the License, or (at your
14     option) any later version.
16     foam-extend is distributed in the hope that it will be useful, but
17     WITHOUT ANY WARRANTY; without even the implied warranty of
18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19     General Public License for more details.
21     You should have received a copy of the GNU General Public License
22     along with foam-extend.  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 "polyBoundaryMesh.H"
32 #include "polyMesh.H"
34 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
36 template<class Face>
37 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::readTypes()
39     return wordHashSet(*fileExtensionConstructorTablePtr_);
43 template<class Face>
44 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::writeTypes()
46     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
50 template<class Face>
51 bool Foam::UnsortedMeshedSurface<Face>::canReadType
53     const word& ext,
54     const bool verbose
57    return fileFormats::surfaceFormatsCore::checkSupport
58    (
59        readTypes() | ParentType::readTypes(),
60        ext,
61        verbose,
62        "reading"
63    );
67 template<class Face>
68 bool Foam::UnsortedMeshedSurface<Face>::canWriteType
70     const word& ext,
71     const bool verbose
74     return fileFormats::surfaceFormatsCore::checkSupport
75     (
76         writeTypes(),
77         ext,
78         verbose,
79         "writing"
80     );
84 template<class Face>
85 bool Foam::UnsortedMeshedSurface<Face>::canRead
87     const fileName& name,
88     const bool verbose
91     word ext = name.ext();
92     if (ext == "gz")
93     {
94         ext = name.lessExt().ext();
95     }
96     return canReadType(ext, verbose);
100 template<class Face>
101 void Foam::UnsortedMeshedSurface<Face>::write
103     const fileName& name,
104     const UnsortedMeshedSurface<Face>& surf
107     if (debug)
108     {
109         Info<< "UnsortedMeshedSurface::write"
110             "(const fileName&, const UnsortedMeshedSurface&) : "
111             "writing to " << name
112             << endl;
113     }
115     const word ext = name.ext();
117     typename writefileExtensionMemberFunctionTable::iterator mfIter =
118         writefileExtensionMemberFunctionTablePtr_->find(ext);
120     if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
121     {
122         // no direct writer, delegate to proxy if possible
123         wordHashSet supported = ProxyType::writeTypes();
125         if (supported.found(ext))
126         {
127             MeshedSurfaceProxy<Face>(surf).write(name);
128         }
129         else
130         {
131             FatalErrorIn
132             (
133                 "UnsortedMeshedSurface::write"
134                 "(const fileName&, const UnsortedMeshedSurface&)"
135             )   << "Unknown file extension " << ext << nl << nl
136                 << "Valid types are :" << endl
137                 << (supported | writeTypes())
138                 << exit(FatalError);
139         }
140     }
141     else
142     {
143         mfIter()(name, surf);
144     }
148 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
150 template<class Face>
151 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface()
153     ParentType()
157 template<class Face>
158 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
160     const Xfer< pointField >& pointLst,
161     const Xfer< List<Face> >& faceLst,
162     const Xfer< List<label> >& zoneIds,
163     const Xfer< surfZoneIdentifierList >& zoneTofc
166     ParentType(pointLst, faceLst),
167     zoneIds_(zoneIds),
168     zoneToc_(zoneTofc)
172 template<class Face>
173 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
175     const Xfer< pointField >& pointLst,
176     const Xfer< List<Face> >& faceLst,
177     const UList<label>& zoneSizes,
178     const UList<word>& zoneNames
181     ParentType(pointLst, faceLst)
183     if (zoneSizes.size())
184     {
185         if (zoneNames.size())
186         {
187             setZones(zoneSizes, zoneNames);
188         }
189         else
190         {
191             setZones(zoneSizes);
192         }
193     }
194     else
195     {
196         setOneZone();
197     }
201 template<class Face>
202 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
204     const UnsortedMeshedSurface<Face>& surf
207     ParentType
208     (
209         xferCopy(surf.points()),
210         xferCopy(surf.faces())
211     ),
212     zoneIds_(surf.zoneIds()),
213     zoneToc_(surf.zoneToc())
217 template<class Face>
218 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
220     const MeshedSurface<Face>& surf
223     ParentType
224     (
225         xferCopy(surf.points()),
226         xferCopy(surf.faces())
227     )
229     setZones(surf.surfZones());
233 template<class Face>
234 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
236     const Xfer< UnsortedMeshedSurface<Face> >& surf
239     ParentType()
241     transfer(surf());
245 template<class Face>
246 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
248     const Xfer< MeshedSurface<Face> >& surf
251     ParentType()
253     transfer(surf());
257 template<class Face>
258 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
260     const fileName& name,
261     const word& ext
264     ParentType()
266     read(name, ext);
270 template<class Face>
271 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
273     ParentType()
275     read(name);
279 template<class Face>
280 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
282     const Time& t,
283     const word& surfName
286     ParentType()
288     MeshedSurface<Face> surf(t, surfName);
289     transfer(surf);
293 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
295 template<class Face>
296 Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
300 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
302 template<class Face>
303 void Foam::UnsortedMeshedSurface<Face>::setOneZone()
305     zoneIds_.setSize(size());
306     zoneIds_ = 0;
308     word zoneName;
309     if (zoneToc_.size())
310     {
311         zoneName = zoneToc_[0].name();
312     }
313     if (zoneName.empty())
314     {
315         zoneName = "zone0";
316     }
318     // set single default zone
319     zoneToc_.setSize(1);
320     zoneToc_[0] = surfZoneIdentifier(zoneName, 0);
324 template<class Face>
325 void Foam::UnsortedMeshedSurface<Face>::setZones
327     const surfZoneList& zoneLst
330     zoneIds_.setSize(size());
331     zoneToc_.setSize(zoneLst.size());
333     forAll(zoneToc_, zoneI)
334     {
335         const surfZone& zone = zoneLst[zoneI];
336         zoneToc_[zoneI] = zone;
338         // assign sub-zone Ids
339         SubList<label> subZone(zoneIds_, zone.size(), zone.start());
340         subZone = zoneI;
341     }
345 template<class Face>
346 void Foam::UnsortedMeshedSurface<Face>::setZones
348     const UList<label>& sizes,
349     const UList<word>& names
352     zoneIds_.setSize(size());
353     zoneToc_.setSize(sizes.size());
355     label start = 0;
356     forAll(zoneToc_, zoneI)
357     {
358         zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);
360         // assign sub-zone Ids
361         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
362         subZone = zoneI;
364         start += sizes[zoneI];
365     }
369 template<class Face>
370 void Foam::UnsortedMeshedSurface<Face>::setZones
372     const UList<label>& sizes
375     zoneIds_.setSize(size());
376     zoneToc_.setSize(sizes.size());
378     label start = 0;
379     forAll(zoneToc_, zoneI)
380     {
381         zoneToc_[zoneI] = surfZoneIdentifier
382         (
383             word("zone") + ::Foam::name(zoneI),
384             zoneI
385         );
387         // assign sub-zone Ids
388         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
389         subZone = zoneI;
391         start += sizes[zoneI];
392     }
396 template<class Face>
397 void Foam::UnsortedMeshedSurface<Face>::remapFaces
399     const UList<label>& faceMap
402     // re-assign the zone Ids
403     if (!faceMap.empty())
404     {
405         if (zoneToc_.empty())
406         {
407             setOneZone();
408         }
409         else if (zoneToc_.size() == 1)
410         {
411             // optimized for single-zone case
412             zoneIds_ = 0;
413         }
414         else
415         {
416             List<label> newZones(faceMap.size());
418             forAll(faceMap, faceI)
419             {
420                 newZones[faceI] = zoneIds_[faceMap[faceI]];
421             }
422             zoneIds_.transfer(newZones);
423         }
424     }
428 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
430 template<class Face>
431 void Foam::UnsortedMeshedSurface<Face>::setSize(const label s)
433     this->storedFaces().setSize(s);
434     // if zones extend: set with last zoneId
435     zoneIds_.setSize(s, zoneToc_.size() - 1);
439 template<class Face>
440 void Foam::UnsortedMeshedSurface<Face>::clear()
442     ParentType::clear();
443     zoneIds_.clear();
444     zoneToc_.clear();
448 template<class Face>
449 Foam::surfZoneList Foam::UnsortedMeshedSurface<Face>::sortedZones
451     labelList& faceMap
452 ) const
454     // supply some zone names
455     Map<word> zoneNames;
456     forAll(zoneToc_, zoneI)
457     {
458         zoneNames.insert(zoneI, zoneToc_[zoneI].name());
459     }
461     // std::sort() really seems to mix up the order.
462     // and std::stable_sort() might take too long / too much memory
464     // Assuming that we have relatively fewer zones compared to the
465     // number of items, just do it ourselves
467     // step 1: get zone sizes and store (origId => zoneI)
468     Map<label> lookup;
469     forAll(zoneIds_, faceI)
470     {
471         const label origId = zoneIds_[faceI];
473         Map<label>::iterator fnd = lookup.find(origId);
474         if (fnd != lookup.end())
475         {
476             fnd()++;
477         }
478         else
479         {
480             lookup.insert(origId, 1);
481         }
482     }
484     // step 2: assign start/size (and name) to the newZones
485     // re-use the lookup to map (zoneId => zoneI)
486     surfZoneList zoneLst(lookup.size());
487     label start = 0;
488     label zoneI = 0;
489     forAllIter(Map<label>, lookup, iter)
490     {
491         label origId = iter.key();
493         word name;
494         Map<word>::const_iterator fnd = zoneNames.find(origId);
495         if (fnd != zoneNames.end())
496         {
497             name = fnd();
498         }
499         else
500         {
501             name = word("zone") + ::Foam::name(zoneI);
502         }
504         zoneLst[zoneI] = surfZone
505         (
506             name,
507             0,           // initialize with zero size
508             start,
509             zoneI
510         );
512         // increment the start for the next zone
513         // and save the (zoneId => zoneI) mapping
514         start += iter();
515         iter() = zoneI++;
516     }
519     // step 3: build the re-ordering
520     faceMap.setSize(zoneIds_.size());
522     forAll(zoneIds_, faceI)
523     {
524         label zoneI = lookup[zoneIds_[faceI]];
525         faceMap[faceI] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
526     }
528     // with reordered faces registered in faceMap
529     return zoneLst;
533 template<class Face>
534 Foam::UnsortedMeshedSurface<Face>
535 Foam::UnsortedMeshedSurface<Face>::subsetMesh
537     const labelHashSet& include,
538     labelList& pointMap,
539     labelList& faceMap
540 ) const
542     const pointField&  locPoints = this->localPoints();
543     const List<Face>&  locFaces  = this->localFaces();
545     // Fill pointMap, faceMap
546     PatchTools::subsetMap(*this, include, pointMap, faceMap);
548     // Create compact coordinate list and forward mapping array
549     pointField newPoints(pointMap.size());
550     labelList  oldToNew(locPoints.size());
551     forAll(pointMap, pointI)
552     {
553         newPoints[pointI] = locPoints[pointMap[pointI]];
554         oldToNew[pointMap[pointI]] = pointI;
555     }
557     // Renumber face node labels and compact
558     List<Face>  newFaces(faceMap.size());
559     List<label> newZones(faceMap.size());
561     forAll(faceMap, faceI)
562     {
563         const label origFaceI = faceMap[faceI];
564         newFaces[faceI] = Face(locFaces[origFaceI]);
566         // Renumber labels for face
567         Face& f = newFaces[faceI];
568         forAll(f, fp)
569         {
570             f[fp] = oldToNew[f[fp]];
571         }
573         newZones[faceI] = zoneIds_[origFaceI];
574     }
575     oldToNew.clear();
577     // construct a sub-surface
578     return UnsortedMeshedSurface
579     (
580         xferMove(newPoints),
581         xferMove(newFaces),
582         xferMove(newZones),
583         xferCopy(zoneToc_)
584     );
588 template<class Face>
589 Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
591     const labelHashSet& include
592 ) const
594     labelList pointMap, faceMap;
595     return subsetMesh(include, pointMap, faceMap);
599 template<class Face>
600 void Foam::UnsortedMeshedSurface<Face>::reset
602     const Xfer< pointField >& pointLst,
603     const Xfer< List<Face> >& faceLst,
604     const Xfer< List<label> >& zoneIds
607     ParentType::reset
608     (
609         pointLst,
610         faceLst,
611         Xfer<surfZoneList>()
612     );
614     if (!zoneIds().empty())
615     {
616         zoneIds_.transfer(zoneIds());
617     }
621 template<class Face>
622 void Foam::UnsortedMeshedSurface<Face>::reset
624     const Xfer< List<point> >& pointLst,
625     const Xfer< List<Face> >& faceLst,
626     const Xfer< List<label> >& zoneIds
629     ParentType::reset
630     (
631         pointLst,
632         faceLst,
633         Xfer<surfZoneList>()
634     );
636     if (!zoneIds().empty())
637     {
638         zoneIds_.transfer(zoneIds());
639     }
643 template<class Face>
644 void Foam::UnsortedMeshedSurface<Face>::transfer
646     UnsortedMeshedSurface<Face>& surf
649     ParentType::reset
650     (
651         xferMove(surf.storedPoints()),
652         xferMove(surf.storedFaces()),
653         Xfer<surfZoneList>()
654     );
656     zoneIds_.transfer(surf.zoneIds_);
657     zoneToc_.transfer(surf.zoneToc_);
659     surf.clear();
663 template<class Face>
664 void Foam::UnsortedMeshedSurface<Face>::transfer
666     MeshedSurface<Face>& surf
669     ParentType::reset
670     (
671         xferMove(surf.storedPoints()),
672         xferMove(surf.storedFaces()),
673         Xfer<surfZoneList>()
674     );
676     setZones(surf.surfZones());
677     surf.clear();
681 template<class Face>
682 Foam::Xfer< Foam::UnsortedMeshedSurface<Face> >
683 Foam::UnsortedMeshedSurface<Face>::xfer()
685     return xferMove(*this);
689 // Read from file, determine format from extension
690 template<class Face>
691 bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
693     word ext = name.ext();
694     if (ext == "gz")
695     {
696         fileName unzipName = name.lessExt();
697         return read(unzipName, unzipName.ext());
698     }
699     else
700     {
701         return read(name, ext);
702     }
706 // Read from file in given format
707 template<class Face>
708 bool Foam::UnsortedMeshedSurface<Face>::read
710     const fileName& name,
711     const word& ext
714     clear();
716     // read via use selector mechanism
717     transfer(New(name, ext)());
718     return true;
722 template<class Face>
723 void Foam::UnsortedMeshedSurface<Face>::write
725     const Time& t,
726     const word& surfName
727 ) const
729     MeshedSurfaceProxy<Face>(*this).write(t, surfName);
733 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
735 template<class Face>
736 void Foam::UnsortedMeshedSurface<Face>::operator=
738     const UnsortedMeshedSurface<Face>& surf
741     clear();
743     this->storedPoints() = surf.points();
744     this->storedFaces()  = surf.faces();
745     zoneIds_ = surf.zoneIds_;
746     zoneToc_ = surf.zoneToc_;
750 template<class Face>
751 Foam::UnsortedMeshedSurface<Face>::operator
752 Foam::MeshedSurfaceProxy<Face>() const
754     labelList faceMap;
755     List<surfZone> zoneLst = this->sortedZones(faceMap);
757     return MeshedSurfaceProxy<Face>
758     (
759         this->points(),
760         this->faces(),
761         zoneLst,
762         faceMap
763     );
767 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
769 #include "UnsortedMeshedSurfaceNew.C"
771 // ************************************************************************* //