Merge remote-tracking branch 'origin/nr/multiSolverFix' into nextRelease
[foam-extend-3.2.git] / src / surfMesh / UnsortedMeshedSurface / UnsortedMeshedSurface.C
blob82c882749a928d7840643b795813e3b11357c1aa
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright held by original author
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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "MeshedSurface.H"
28 #include "UnsortedMeshedSurface.H"
29 #include "MeshedSurfaceProxy.H"
30 #include "IFstream.H"
31 #include "OFstream.H"
32 #include "Time.H"
33 #include "polyBoundaryMesh.H"
34 #include "polyMesh.H"
36 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
38 template<class Face>
39 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::readTypes()
41     return wordHashSet(*fileExtensionConstructorTablePtr_);
45 template<class Face>
46 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::writeTypes()
48     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
52 template<class Face>
53 bool Foam::UnsortedMeshedSurface<Face>::canReadType
55     const word& ext,
56     const bool verbose
59    return checkSupport
60    (
61        readTypes() | ParentType::readTypes(),
62        ext,
63        verbose,
64        "reading"
65    );
69 template<class Face>
70 bool Foam::UnsortedMeshedSurface<Face>::canWriteType
72     const word& ext,
73     const bool verbose
76     return checkSupport
77     (
78         writeTypes(),
79         ext,
80         verbose,
81         "writing"
82     );
86 template<class Face>
87 bool Foam::UnsortedMeshedSurface<Face>::canRead
89     const fileName& name,
90     const bool verbose
93     word ext = name.ext();
94     if (ext == "gz")
95     {
96         ext = name.lessExt().ext();
97     }
98     return canReadType(ext, verbose);
102 template<class Face>
103 void Foam::UnsortedMeshedSurface<Face>::write
105     const fileName& name,
106     const UnsortedMeshedSurface<Face>& surf
109     if (debug)
110     {
111         Info<< "UnsortedMeshedSurface::write"
112             "(const fileName&, const UnsortedMeshedSurface&) : "
113             "writing to " << name
114             << endl;
115     }
117     const word ext = name.ext();
119     typename writefileExtensionMemberFunctionTable::iterator mfIter =
120         writefileExtensionMemberFunctionTablePtr_->find(ext);
122     if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
123     {
124         // no direct writer, delegate to proxy if possible
125         wordHashSet supported = ProxyType::writeTypes();
127         if (supported.found(ext))
128         {
129             MeshedSurfaceProxy<Face>(surf).write(name);
130         }
131         else
132         {
133             FatalErrorIn
134             (
135                 "UnsortedMeshedSurface::write"
136                 "(const fileName&, const UnsortedMeshedSurface&)"
137             )   << "Unknown file extension " << ext << nl << nl
138                 << "Valid types are :" << endl
139                 << (supported | writeTypes())
140                 << exit(FatalError);
141         }
142     }
143     else
144     {
145         mfIter()(name, surf);
146     }
150 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
152 template<class Face>
153 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface()
155     ParentType()
159 template<class Face>
160 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
162     const Xfer< pointField >& pointLst,
163     const Xfer< List<Face> >& faceLst,
164     const Xfer< List<label> >& zoneIds,
165     const Xfer< surfZoneIdentifierList >& zoneTofc
168     ParentType(pointLst, faceLst),
169     zoneIds_(zoneIds),
170     zoneToc_(zoneTofc)
174 template<class Face>
175 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
177     const Xfer< pointField >& pointLst,
178     const Xfer< List<Face> >& faceLst,
179     const UList<label>& zoneSizes,
180     const UList<word>& zoneNames
183     ParentType(pointLst, faceLst)
185     if (zoneSizes.size())
186     {
187         if (zoneNames.size())
188         {
189             setZones(zoneSizes, zoneNames);
190         }
191         else
192         {
193             setZones(zoneSizes);
194         }
195     }
196     else
197     {
198         setOneZone();
199     }
203 template<class Face>
204 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
206     const UnsortedMeshedSurface<Face>& surf
209     ParentType
210     (
211         xferCopy(surf.points()),
212         xferCopy(surf.faces())
213     ),
214     zoneIds_(surf.zoneIds()),
215     zoneToc_(surf.zoneToc())
219 template<class Face>
220 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
222     const MeshedSurface<Face>& surf
225     ParentType
226     (
227         xferCopy(surf.points()),
228         xferCopy(surf.faces())
229     )
231     setZones(surf.surfZones());
235 template<class Face>
236 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
238     const Xfer< UnsortedMeshedSurface<Face> >& surf
241     ParentType()
243     transfer(surf());
247 template<class Face>
248 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
250     const Xfer< MeshedSurface<Face> >& surf
253     ParentType()
255     transfer(surf());
259 template<class Face>
260 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
262     const fileName& name,
263     const word& ext
266     ParentType()
268     read(name, ext);
272 template<class Face>
273 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
275     ParentType()
277     read(name);
281 template<class Face>
282 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
284     const Time& t,
285     const word& surfName
288     ParentType()
290     MeshedSurface<Face> surf(t, surfName);
291     transfer(surf);
295 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
297 template<class Face>
298 Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
302 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
304 template<class Face>
305 void Foam::UnsortedMeshedSurface<Face>::setOneZone()
307     zoneIds_.setSize(size());
308     zoneIds_ = 0;
310     word zoneName;
311     if (zoneToc_.size())
312     {
313         zoneName = zoneToc_[0].name();
314     }
315     if (zoneName.empty())
316     {
317         zoneName = "zone0";
318     }
320     // set single default zone
321     zoneToc_.setSize(1);
322     zoneToc_[0] = surfZoneIdentifier(zoneName, 0);
326 template<class Face>
327 void Foam::UnsortedMeshedSurface<Face>::setZones
329     const surfZoneList& zoneLst
332     zoneIds_.setSize(size());
333     zoneToc_.setSize(zoneLst.size());
335     forAll(zoneToc_, zoneI)
336     {
337         const surfZone& zone = zoneLst[zoneI];
338         zoneToc_[zoneI] = zone;
340         // assign sub-zone Ids
341         SubList<label> subZone(zoneIds_, zone.size(), zone.start());
342         subZone = zoneI;
343     }
347 template<class Face>
348 void Foam::UnsortedMeshedSurface<Face>::setZones
350     const UList<label>& sizes,
351     const UList<word>& names
354     zoneIds_.setSize(size());
355     zoneToc_.setSize(sizes.size());
357     label start = 0;
358     forAll(zoneToc_, zoneI)
359     {
360         zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);
362         // assign sub-zone Ids
363         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
364         subZone = zoneI;
366         start += sizes[zoneI];
367     }
371 template<class Face>
372 void Foam::UnsortedMeshedSurface<Face>::setZones
374     const UList<label>& sizes
377     zoneIds_.setSize(size());
378     zoneToc_.setSize(sizes.size());
380     label start = 0;
381     forAll(zoneToc_, zoneI)
382     {
383         zoneToc_[zoneI] = surfZoneIdentifier
384         (
385             word("zone") + ::Foam::name(zoneI),
386             zoneI
387         );
389         // assign sub-zone Ids
390         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
391         subZone = zoneI;
393         start += sizes[zoneI];
394     }
398 template<class Face>
399 void Foam::UnsortedMeshedSurface<Face>::remapFaces
401     const UList<label>& faceMap
404     // re-assign the zone Ids
405     if (&faceMap && faceMap.size())
406     {
407         if (zoneToc_.empty())
408         {
409             setOneZone();
410         }
411         else if (zoneToc_.size() == 1)
412         {
413             // optimized for single-zone case
414             zoneIds_ = 0;
415         }
416         else
417         {
418             List<label> newZones(faceMap.size());
420             forAll(faceMap, faceI)
421             {
422                 newZones[faceI] = zoneIds_[faceMap[faceI]];
423             }
424             zoneIds_.transfer(newZones);
425         }
426     }
430 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
432 template<class Face>
433 void Foam::UnsortedMeshedSurface<Face>::setSize(const label s)
435     this->storedFaces().setSize(s);
436     // if zones extend: set with last zoneId
437     zoneIds_.setSize(s, zoneToc_.size() - 1);
441 template<class Face>
442 void Foam::UnsortedMeshedSurface<Face>::clear()
444     ParentType::clear();
445     zoneIds_.clear();
446     zoneToc_.clear();
450 template<class Face>
451 Foam::surfZoneList Foam::UnsortedMeshedSurface<Face>::sortedZones
453     labelList& faceMap
454 ) const
456     // supply some zone names
457     Map<word> zoneNames;
458     forAll(zoneToc_, zoneI)
459     {
460         zoneNames.insert(zoneI, zoneToc_[zoneI].name());
461     }
463     // std::sort() really seems to mix up the order.
464     // and std::stable_sort() might take too long / too much memory
466     // Assuming that we have relatively fewer zones compared to the
467     // number of items, just do it ourselves
469     // step 1: get zone sizes and store (origId => zoneI)
470     Map<label> lookup;
471     forAll(zoneIds_, faceI)
472     {
473         const label origId = zoneIds_[faceI];
475         Map<label>::iterator fnd = lookup.find(origId);
476         if (fnd != lookup.end())
477         {
478             fnd()++;
479         }
480         else
481         {
482             lookup.insert(origId, 1);
483         }
484     }
486     // step 2: assign start/size (and name) to the newZones
487     // re-use the lookup to map (zoneId => zoneI)
488     surfZoneList zoneLst(lookup.size());
489     label start = 0;
490     label zoneI = 0;
491     forAllIter(Map<label>, lookup, iter)
492     {
493         label origId = iter.key();
495         word name;
496         Map<word>::const_iterator fnd = zoneNames.find(origId);
497         if (fnd != zoneNames.end())
498         {
499             name = fnd();
500         }
501         else
502         {
503             name = word("zone") + ::Foam::name(zoneI);
504         }
506         zoneLst[zoneI] = surfZone
507         (
508             name,
509             0,           // initialize with zero size
510             start,
511             zoneI
512         );
514         // increment the start for the next zone
515         // and save the (zoneId => zoneI) mapping
516         start += iter();
517         iter() = zoneI++;
518     }
521     // step 3: build the re-ordering
522     faceMap.setSize(zoneIds_.size());
524     forAll(zoneIds_, faceI)
525     {
526         label zoneI = lookup[zoneIds_[faceI]];
527         faceMap[faceI] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
528     }
530     // with reordered faces registered in faceMap
531     return zoneLst;
535 template<class Face>
536 Foam::UnsortedMeshedSurface<Face>
537 Foam::UnsortedMeshedSurface<Face>::subsetMesh
539     const labelHashSet& include,
540     labelList& pointMap,
541     labelList& faceMap
542 ) const
544     const pointField&  locPoints = this->localPoints();
545     const List<Face>&  locFaces  = this->localFaces();
547     // Fill pointMap, faceMap
548     PatchTools::subsetMap(*this, include, pointMap, faceMap);
550     // Create compact coordinate list and forward mapping array
551     pointField newPoints(pointMap.size());
552     labelList  oldToNew(locPoints.size());
553     forAll(pointMap, pointI)
554     {
555         newPoints[pointI] = locPoints[pointMap[pointI]];
556         oldToNew[pointMap[pointI]] = pointI;
557     }
559     // Renumber face node labels and compact
560     List<Face>  newFaces(faceMap.size());
561     List<label> newZones(faceMap.size());
563     forAll(faceMap, faceI)
564     {
565         const label origFaceI = faceMap[faceI];
566         newFaces[faceI] = Face(locFaces[origFaceI]);
568         // Renumber labels for face
569         Face& f = newFaces[faceI];
570         forAll(f, fp)
571         {
572             f[fp] = oldToNew[f[fp]];
573         }
575         newZones[faceI] = zoneIds_[origFaceI];
576     }
577     oldToNew.clear();
579     // construct a sub-surface
580     return UnsortedMeshedSurface
581     (
582         xferMove(newPoints),
583         xferMove(newFaces),
584         xferMove(newZones),
585         xferCopy(zoneToc_)
586     );
590 template<class Face>
591 Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
593     const labelHashSet& include
594 ) const
596     labelList pointMap, faceMap;
597     return subsetMesh(include, pointMap, faceMap);
601 template<class Face>
602 void Foam::UnsortedMeshedSurface<Face>::reset
604     const Xfer< pointField >& pointLst,
605     const Xfer< List<Face> >& faceLst,
606     const Xfer< List<label> >& zoneIds
609     ParentType::reset
610     (
611         pointLst,
612         faceLst,
613         Xfer<surfZoneList>()
614     );
616     if (&zoneIds)
617     {
618         zoneIds_.transfer(zoneIds());
619     }
623 template<class Face>
624 void Foam::UnsortedMeshedSurface<Face>::reset
626     const Xfer< List<point> >& pointLst,
627     const Xfer< List<Face> >& faceLst,
628     const Xfer< List<label> >& zoneIds
631     ParentType::reset
632     (
633         pointLst,
634         faceLst,
635         Xfer<surfZoneList>()
636     );
638     if (&zoneIds)
639     {
640         zoneIds_.transfer(zoneIds());
641     }
645 template<class Face>
646 void Foam::UnsortedMeshedSurface<Face>::transfer
648     UnsortedMeshedSurface<Face>& surf
651     ParentType::reset
652     (
653         xferMove(surf.storedPoints()),
654         xferMove(surf.storedFaces()),
655         Xfer<surfZoneList>()
656     );
658     zoneIds_.transfer(surf.zoneIds_);
659     zoneToc_.transfer(surf.zoneToc_);
661     surf.clear();
665 template<class Face>
666 void Foam::UnsortedMeshedSurface<Face>::transfer
668     MeshedSurface<Face>& surf
671     ParentType::reset
672     (
673         xferMove(surf.storedPoints()),
674         xferMove(surf.storedFaces()),
675         Xfer<surfZoneList>()
676     );
678     setZones(surf.surfZones());
679     surf.clear();
683 template<class Face>
684 Foam::Xfer< Foam::UnsortedMeshedSurface<Face> >
685 Foam::UnsortedMeshedSurface<Face>::xfer()
687     return xferMove(*this);
691 // Read from file, determine format from extension
692 template<class Face>
693 bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
695     word ext = name.ext();
696     if (ext == "gz")
697     {
698         fileName unzipName = name.lessExt();
699         return read(unzipName, unzipName.ext());
700     }
701     else
702     {
703         return read(name, ext);
704     }
708 // Read from file in given format
709 template<class Face>
710 bool Foam::UnsortedMeshedSurface<Face>::read
712     const fileName& name,
713     const word& ext
716     clear();
718     // read via use selector mechanism
719     transfer(New(name, ext)());
720     return true;
724 template<class Face>
725 void Foam::UnsortedMeshedSurface<Face>::write
727     const Time& t,
728     const word& surfName
729 ) const
731     MeshedSurfaceProxy<Face>(*this).write(t, surfName);
735 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
737 template<class Face>
738 void Foam::UnsortedMeshedSurface<Face>::operator=
740     const UnsortedMeshedSurface<Face>& surf
743     clear();
745     this->storedPoints() = surf.points();
746     this->storedFaces()  = surf.faces();
747     zoneIds_ = surf.zoneIds_;
748     zoneToc_ = surf.zoneToc_;
752 template<class Face>
753 Foam::UnsortedMeshedSurface<Face>::operator
754 Foam::MeshedSurfaceProxy<Face>() const
756     labelList faceMap;
757     List<surfZone> zoneLst = this->sortedZones(faceMap);
759     return MeshedSurfaceProxy<Face>
760     (
761         this->points(),
762         this->faces(),
763         zoneLst,
764         faceMap
765     );
769 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
771 #include "UnsortedMeshedSurfaceNew.C"
773 // ************************************************************************* //