FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

UnsortedMeshedSurface.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include <surfMesh/MeshedSurface.H>
00027 #include "UnsortedMeshedSurface.H"
00028 #include <surfMesh/MeshedSurfaceProxy.H>
00029 #include <OpenFOAM/IFstream.H>
00030 #include <OpenFOAM/OFstream.H>
00031 #include <OpenFOAM/Time.H>
00032 #include <OpenFOAM/polyBoundaryMesh.H>
00033 #include <OpenFOAM/polyMesh.H>
00034 
00035 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
00036 
00037 template<class Face>
00038 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::readTypes()
00039 {
00040     return wordHashSet(*fileExtensionConstructorTablePtr_);
00041 }
00042 
00043 
00044 template<class Face>
00045 Foam::wordHashSet Foam::UnsortedMeshedSurface<Face>::writeTypes()
00046 {
00047     return wordHashSet(*writefileExtensionMemberFunctionTablePtr_);
00048 }
00049 
00050 
00051 template<class Face>
00052 bool Foam::UnsortedMeshedSurface<Face>::canReadType
00053 (
00054     const word& ext,
00055     const bool verbose
00056 )
00057 {
00058    return checkSupport
00059    (
00060        readTypes() | ParentType::readTypes(),
00061        ext,
00062        verbose,
00063        "reading"
00064    );
00065 }
00066 
00067 
00068 template<class Face>
00069 bool Foam::UnsortedMeshedSurface<Face>::canWriteType
00070 (
00071     const word& ext,
00072     const bool verbose
00073 )
00074 {
00075     return checkSupport
00076     (
00077         writeTypes(),
00078         ext,
00079         verbose,
00080         "writing"
00081     );
00082 }
00083 
00084 
00085 template<class Face>
00086 bool Foam::UnsortedMeshedSurface<Face>::canRead
00087 (
00088     const fileName& name,
00089     const bool verbose
00090 )
00091 {
00092     word ext = name.ext();
00093     if (ext == "gz")
00094     {
00095         ext = name.lessExt().ext();
00096     }
00097     return canReadType(ext, verbose);
00098 }
00099 
00100 
00101 template<class Face>
00102 void Foam::UnsortedMeshedSurface<Face>::write
00103 (
00104     const fileName& name,
00105     const UnsortedMeshedSurface<Face>& surf
00106 )
00107 {
00108     if (debug)
00109     {
00110         Info<< "UnsortedMeshedSurface::write"
00111             "(const fileName&, const UnsortedMeshedSurface&) : "
00112             "writing to " << name
00113             << endl;
00114     }
00115 
00116     const word ext = name.ext();
00117 
00118     typename writefileExtensionMemberFunctionTable::iterator mfIter =
00119         writefileExtensionMemberFunctionTablePtr_->find(ext);
00120 
00121     if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
00122     {
00123         // no direct writer, delegate to proxy if possible
00124         wordHashSet supported = ProxyType::writeTypes();
00125 
00126         if (supported.found(ext))
00127         {
00128             MeshedSurfaceProxy<Face>(surf).write(name);
00129         }
00130         else
00131         {
00132             FatalErrorIn
00133             (
00134                 "UnsortedMeshedSurface::write"
00135                 "(const fileName&, const UnsortedMeshedSurface&)"
00136             )   << "Unknown file extension " << ext << nl << nl
00137                 << "Valid types are :" << endl
00138                 << (supported | writeTypes())
00139                 << exit(FatalError);
00140         }
00141     }
00142     else
00143     {
00144         mfIter()(name, surf);
00145     }
00146 }
00147 
00148 
00149 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00150 
00151 template<class Face>
00152 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface()
00153 :
00154     ParentType()
00155 {}
00156 
00157 
00158 template<class Face>
00159 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00160 (
00161     const Xfer< pointField >& pointLst,
00162     const Xfer< List<Face> >& faceLst,
00163     const Xfer< List<label> >& zoneIds,
00164     const Xfer< surfZoneIdentifierList >& zoneTofc
00165 )
00166 :
00167     ParentType(pointLst, faceLst),
00168     zoneIds_(zoneIds),
00169     zoneToc_(zoneTofc)
00170 {}
00171 
00172 
00173 template<class Face>
00174 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00175 (
00176     const Xfer< pointField >& pointLst,
00177     const Xfer< List<Face> >& faceLst,
00178     const UList<label>& zoneSizes,
00179     const UList<word>& zoneNames
00180 )
00181 :
00182     ParentType(pointLst, faceLst)
00183 {
00184     if (zoneSizes.size())
00185     {
00186         if (zoneNames.size())
00187         {
00188             setZones(zoneSizes, zoneNames);
00189         }
00190         else
00191         {
00192             setZones(zoneSizes);
00193         }
00194     }
00195     else
00196     {
00197         setOneZone();
00198     }
00199 }
00200 
00201 
00202 template<class Face>
00203 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00204 (
00205     const UnsortedMeshedSurface<Face>& surf
00206 )
00207 :
00208     ParentType
00209     (
00210         xferCopy(surf.points()),
00211         xferCopy(surf.faces())
00212     ),
00213     zoneIds_(surf.zoneIds()),
00214     zoneToc_(surf.zoneToc())
00215 {}
00216 
00217 
00218 template<class Face>
00219 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00220 (
00221     const MeshedSurface<Face>& surf
00222 )
00223 :
00224     ParentType
00225     (
00226         xferCopy(surf.points()),
00227         xferCopy(surf.faces())
00228     )
00229 {
00230     setZones(surf.surfZones());
00231 }
00232 
00233 
00234 template<class Face>
00235 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00236 (
00237     const Xfer< UnsortedMeshedSurface<Face> >& surf
00238 )
00239 :
00240     ParentType()
00241 {
00242     transfer(surf());
00243 }
00244 
00245 
00246 template<class Face>
00247 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00248 (
00249     const Xfer< MeshedSurface<Face> >& surf
00250 )
00251 :
00252     ParentType()
00253 {
00254     transfer(surf());
00255 }
00256 
00257 
00258 template<class Face>
00259 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00260 (
00261     const fileName& name,
00262     const word& ext
00263 )
00264 :
00265     ParentType()
00266 {
00267     read(name, ext);
00268 }
00269 
00270 
00271 template<class Face>
00272 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
00273 :
00274     ParentType()
00275 {
00276     read(name);
00277 }
00278 
00279 
00280 template<class Face>
00281 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
00282 (
00283     const Time& t,
00284     const word& surfName
00285 )
00286 :
00287     ParentType()
00288 {
00289     MeshedSurface<Face> surf(t, surfName);
00290     transfer(surf);
00291 }
00292 
00293 
00294 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00295 
00296 template<class Face>
00297 Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
00298 {}
00299 
00300 
00301 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
00302 
00303 template<class Face>
00304 void Foam::UnsortedMeshedSurface<Face>::setOneZone()
00305 {
00306     zoneIds_.setSize(size());
00307     zoneIds_ = 0;
00308 
00309     word zoneName;
00310     if (zoneToc_.size())
00311     {
00312         zoneName = zoneToc_[0].name();
00313     }
00314     if (zoneName.empty())
00315     {
00316         zoneName = "zone0";
00317     }
00318 
00319     // set single default zone
00320     zoneToc_.setSize(1);
00321     zoneToc_[0] = surfZoneIdentifier(zoneName, 0);
00322 }
00323 
00324 
00325 template<class Face>
00326 void Foam::UnsortedMeshedSurface<Face>::setZones
00327 (
00328     const surfZoneList& zoneLst
00329 )
00330 {
00331     zoneIds_.setSize(size());
00332     zoneToc_.setSize(zoneLst.size());
00333 
00334     forAll(zoneToc_, zoneI)
00335     {
00336         const surfZone& zone = zoneLst[zoneI];
00337         zoneToc_[zoneI] = zone;
00338 
00339         // assign sub-zone Ids
00340         SubList<label> subZone(zoneIds_, zone.size(), zone.start());
00341         subZone = zoneI;
00342     }
00343 }
00344 
00345 
00346 template<class Face>
00347 void Foam::UnsortedMeshedSurface<Face>::setZones
00348 (
00349     const UList<label>& sizes,
00350     const UList<word>& names
00351 )
00352 {
00353     zoneIds_.setSize(size());
00354     zoneToc_.setSize(sizes.size());
00355 
00356     label start = 0;
00357     forAll(zoneToc_, zoneI)
00358     {
00359         zoneToc_[zoneI] = surfZoneIdentifier(names[zoneI], zoneI);
00360 
00361         // assign sub-zone Ids
00362         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
00363         subZone = zoneI;
00364 
00365         start += sizes[zoneI];
00366     }
00367 }
00368 
00369 
00370 template<class Face>
00371 void Foam::UnsortedMeshedSurface<Face>::setZones
00372 (
00373     const UList<label>& sizes
00374 )
00375 {
00376     zoneIds_.setSize(size());
00377     zoneToc_.setSize(sizes.size());
00378 
00379     label start = 0;
00380     forAll(zoneToc_, zoneI)
00381     {
00382         zoneToc_[zoneI] = surfZoneIdentifier
00383         (
00384             word("zone") + ::Foam::name(zoneI),
00385             zoneI
00386         );
00387 
00388         // assign sub-zone Ids
00389         SubList<label> subZone(zoneIds_, sizes[zoneI], start);
00390         subZone = zoneI;
00391 
00392         start += sizes[zoneI];
00393     }
00394 }
00395 
00396 
00397 template<class Face>
00398 void Foam::UnsortedMeshedSurface<Face>::remapFaces
00399 (
00400     const UList<label>& faceMap
00401 )
00402 {
00403     // re-assign the zone Ids
00404     if (&faceMap && faceMap.size())
00405     {
00406         if (zoneToc_.empty())
00407         {
00408             setOneZone();
00409         }
00410         else if (zoneToc_.size() == 1)
00411         {
00412             // optimized for single-zone case
00413             zoneIds_ = 0;
00414         }
00415         else
00416         {
00417             List<label> newZones(faceMap.size());
00418 
00419             forAll(faceMap, faceI)
00420             {
00421                 newZones[faceI] = zoneIds_[faceMap[faceI]];
00422             }
00423             zoneIds_.transfer(newZones);
00424         }
00425     }
00426 }
00427 
00428 
00429 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00430 
00431 template<class Face>
00432 void Foam::UnsortedMeshedSurface<Face>::setSize(const label s)
00433 {
00434     this->storedFaces().setSize(s);
00435     // if zones extend: set with last zoneId
00436     zoneIds_.setSize(s, zoneToc_.size() - 1);
00437 }
00438 
00439 
00440 template<class Face>
00441 void Foam::UnsortedMeshedSurface<Face>::clear()
00442 {
00443     ParentType::clear();
00444     zoneIds_.clear();
00445     zoneToc_.clear();
00446 }
00447 
00448 
00449 template<class Face>
00450 Foam::surfZoneList Foam::UnsortedMeshedSurface<Face>::sortedZones
00451 (
00452     labelList& faceMap
00453 ) const
00454 {
00455     // supply some zone names
00456     Map<word> zoneNames;
00457     forAll(zoneToc_, zoneI)
00458     {
00459         zoneNames.insert(zoneI, zoneToc_[zoneI].name());
00460     }
00461 
00462     // std::sort() really seems to mix up the order.
00463     // and std::stable_sort() might take too long / too much memory
00464 
00465     // Assuming that we have relatively fewer zones compared to the
00466     // number of items, just do it ourselves
00467 
00468     // step 1: get zone sizes and store (origId => zoneI)
00469     Map<label> lookup;
00470     forAll(zoneIds_, faceI)
00471     {
00472         const label origId = zoneIds_[faceI];
00473 
00474         Map<label>::iterator fnd = lookup.find(origId);
00475         if (fnd != lookup.end())
00476         {
00477             fnd()++;
00478         }
00479         else
00480         {
00481             lookup.insert(origId, 1);
00482         }
00483     }
00484 
00485     // step 2: assign start/size (and name) to the newZones
00486     // re-use the lookup to map (zoneId => zoneI)
00487     surfZoneList zoneLst(lookup.size());
00488     label start = 0;
00489     label zoneI = 0;
00490     forAllIter(Map<label>, lookup, iter)
00491     {
00492         label origId = iter.key();
00493 
00494         word name;
00495         Map<word>::const_iterator fnd = zoneNames.find(origId);
00496         if (fnd != zoneNames.end())
00497         {
00498             name = fnd();
00499         }
00500         else
00501         {
00502             name = word("zone") + ::Foam::name(zoneI);
00503         }
00504 
00505         zoneLst[zoneI] = surfZone
00506         (
00507             name,
00508             0,           // initialize with zero size
00509             start,
00510             zoneI
00511         );
00512 
00513         // increment the start for the next zone
00514         // and save the (zoneId => zoneI) mapping
00515         start += iter();
00516         iter() = zoneI++;
00517     }
00518 
00519 
00520     // step 3: build the re-ordering
00521     faceMap.setSize(zoneIds_.size());
00522 
00523     forAll(zoneIds_, faceI)
00524     {
00525         label zoneI = lookup[zoneIds_[faceI]];
00526         faceMap[faceI] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
00527     }
00528 
00529     // with reordered faces registered in faceMap
00530     return zoneLst;
00531 }
00532 
00533 
00534 template<class Face>
00535 Foam::UnsortedMeshedSurface<Face>
00536 Foam::UnsortedMeshedSurface<Face>::subsetMesh
00537 (
00538     const labelHashSet& include,
00539     labelList& pointMap,
00540     labelList& faceMap
00541 ) const
00542 {
00543     const pointField&  locPoints = this->localPoints();
00544     const List<Face>&  locFaces  = this->localFaces();
00545 
00546     // Fill pointMap, faceMap
00547     PatchTools::subsetMap(*this, include, pointMap, faceMap);
00548 
00549     // Create compact coordinate list and forward mapping array
00550     pointField newPoints(pointMap.size());
00551     labelList  oldToNew(locPoints.size());
00552     forAll(pointMap, pointI)
00553     {
00554         newPoints[pointI] = locPoints[pointMap[pointI]];
00555         oldToNew[pointMap[pointI]] = pointI;
00556     }
00557 
00558     // Renumber face node labels and compact
00559     List<Face>  newFaces(faceMap.size());
00560     List<label> newZones(faceMap.size());
00561 
00562     forAll(faceMap, faceI)
00563     {
00564         const label origFaceI = faceMap[faceI];
00565         newFaces[faceI] = Face(locFaces[origFaceI]);
00566 
00567         // Renumber labels for face
00568         Face& f = newFaces[faceI];
00569         forAll(f, fp)
00570         {
00571             f[fp] = oldToNew[f[fp]];
00572         }
00573 
00574         newZones[faceI] = zoneIds_[origFaceI];
00575     }
00576     oldToNew.clear();
00577 
00578     // construct a sub-surface
00579     return UnsortedMeshedSurface
00580     (
00581         xferMove(newPoints),
00582         xferMove(newFaces),
00583         xferMove(newZones),
00584         xferCopy(zoneToc_)
00585     );
00586 }
00587 
00588 
00589 template<class Face>
00590 Foam::UnsortedMeshedSurface<Face> Foam::UnsortedMeshedSurface<Face>::subsetMesh
00591 (
00592     const labelHashSet& include
00593 ) const
00594 {
00595     labelList pointMap, faceMap;
00596     return subsetMesh(include, pointMap, faceMap);
00597 }
00598 
00599 
00600 template<class Face>
00601 void Foam::UnsortedMeshedSurface<Face>::reset
00602 (
00603     const Xfer< pointField >& pointLst,
00604     const Xfer< List<Face> >& faceLst,
00605     const Xfer< List<label> >& zoneIds
00606 )
00607 {
00608     ParentType::reset
00609     (
00610         pointLst,
00611         faceLst,
00612         Xfer<surfZoneList>()
00613     );
00614 
00615     if (&zoneIds)
00616     {
00617         zoneIds_.transfer(zoneIds());
00618     }
00619 }
00620 
00621 
00622 template<class Face>
00623 void Foam::UnsortedMeshedSurface<Face>::reset
00624 (
00625     const Xfer< List<point> >& pointLst,
00626     const Xfer< List<Face> >& faceLst,
00627     const Xfer< List<label> >& zoneIds
00628 )
00629 {
00630     ParentType::reset
00631     (
00632         pointLst,
00633         faceLst,
00634         Xfer<surfZoneList>()
00635     );
00636 
00637     if (&zoneIds)
00638     {
00639         zoneIds_.transfer(zoneIds());
00640     }
00641 }
00642 
00643 
00644 template<class Face>
00645 void Foam::UnsortedMeshedSurface<Face>::transfer
00646 (
00647     UnsortedMeshedSurface<Face>& surf
00648 )
00649 {
00650     ParentType::reset
00651     (
00652         xferMove(surf.storedPoints()),
00653         xferMove(surf.storedFaces()),
00654         Xfer<surfZoneList>()
00655     );
00656 
00657     zoneIds_.transfer(surf.zoneIds_);
00658     zoneToc_.transfer(surf.zoneToc_);
00659 
00660     surf.clear();
00661 }
00662 
00663 
00664 template<class Face>
00665 void Foam::UnsortedMeshedSurface<Face>::transfer
00666 (
00667     MeshedSurface<Face>& surf
00668 )
00669 {
00670     ParentType::reset
00671     (
00672         xferMove(surf.storedPoints()),
00673         xferMove(surf.storedFaces()),
00674         Xfer<surfZoneList>()
00675     );
00676 
00677     setZones(surf.surfZones());
00678     surf.clear();
00679 }
00680 
00681 
00682 template<class Face>
00683 Foam::Xfer< Foam::UnsortedMeshedSurface<Face> >
00684 Foam::UnsortedMeshedSurface<Face>::xfer()
00685 {
00686     return xferMove(*this);
00687 }
00688 
00689 
00690 // Read from file, determine format from extension
00691 template<class Face>
00692 bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
00693 {
00694     word ext = name.ext();
00695     if (ext == "gz")
00696     {
00697         fileName unzipName = name.lessExt();
00698         return read(unzipName, unzipName.ext());
00699     }
00700     else
00701     {
00702         return read(name, ext);
00703     }
00704 }
00705 
00706 
00707 // Read from file in given format
00708 template<class Face>
00709 bool Foam::UnsortedMeshedSurface<Face>::read
00710 (
00711     const fileName& name,
00712     const word& ext
00713 )
00714 {
00715     clear();
00716 
00717     // read via use selector mechanism
00718     transfer(New(name, ext)());
00719     return true;
00720 }
00721 
00722 
00723 template<class Face>
00724 void Foam::UnsortedMeshedSurface<Face>::write
00725 (
00726     const Time& t,
00727     const word& surfName
00728 ) const
00729 {
00730     MeshedSurfaceProxy<Face>(*this).write(t, surfName);
00731 }
00732 
00733 
00734 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
00735 
00736 template<class Face>
00737 void Foam::UnsortedMeshedSurface<Face>::operator=
00738 (
00739     const UnsortedMeshedSurface<Face>& surf
00740 )
00741 {
00742     clear();
00743 
00744     this->storedPoints() = surf.points();
00745     this->storedFaces()  = surf.faces();
00746     zoneIds_ = surf.zoneIds_;
00747     zoneToc_ = surf.zoneToc_;
00748 }
00749 
00750 
00751 template<class Face>
00752 Foam::UnsortedMeshedSurface<Face>::operator
00753 Foam::MeshedSurfaceProxy<Face>() const
00754 {
00755     labelList faceMap;
00756     List<surfZone> zoneLst = this->sortedZones(faceMap);
00757 
00758     return MeshedSurfaceProxy<Face>
00759     (
00760         this->points(),
00761         this->faces(),
00762         zoneLst,
00763         faceMap
00764     );
00765 }
00766 
00767 
00768 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00769 
00770 #include "UnsortedMeshedSurfaceNew.C"
00771 
00772 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines