Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / mesh / cfMesh / utilities / meshes / polyMeshGen / polyMeshGenFaces.C
blob5fbbc60a35724c6bf88f770aaf80a51f858ddcbe
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | cfMesh: A library for mesh generation
4    \\    /   O peration     |
5     \\  /    A nd           | Author: Franjo Juretic (franjo.juretic@c-fields.com)
6      \\/     M anipulation  | Copyright (C) Creative Fields, Ltd.
7 -------------------------------------------------------------------------------
8 License
9     This file is part of cfMesh.
11     cfMesh 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     cfMesh 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 cfMesh.  If not, see <http://www.gnu.org/licenses/>.
24 Description
26 \*---------------------------------------------------------------------------*/
28 #include "polyMeshGenFaces.H"
29 #include "faceIOList.H"
30 #include "IOPtrList.H"
31 #include "IOobjectList.H"
32 #include "faceSet.H"
33 #include "demandDrivenData.H"
34 #include "stringListOps.H"
36 namespace Foam
39 // * * * * * * * * * * Private member functions * * * * * * * * * * * * * * * //
41 void polyMeshGenFaces::clearOut() const
43     deleteDemandDrivenData(ownerPtr_);
44     deleteDemandDrivenData(neighbourPtr_);
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 // Constructors
49 //- Null constructor
50 polyMeshGenFaces::polyMeshGenFaces(const Time& runTime)
52     polyMeshGenPoints(runTime),
53     faces_
54     (
55         IOobject
56         (
57             "faces",
58             runTime.constant(),
59             "polyMesh",
60             runTime
61         ),
62         0
63     ),
64     procBoundaries_(),
65     boundaries_(),
66     faceSubsets_(),
67     nIntFaces_(0),
68     ownerPtr_(NULL),
69     neighbourPtr_(NULL)
72 //- Construct from components without the boundary
73 polyMeshGenFaces::polyMeshGenFaces
75     const Time& runTime,
76     const pointField& points,
77     const faceList& faces
80     polyMeshGenPoints(runTime, points),
81     faces_
82     (
83         IOobject
84         (
85             "faces",
86             runTime.constant(),
87             "polyMesh",
88             runTime
89         ),
90         faces
91     ),
92     procBoundaries_(),
93     boundaries_(),
94     faceSubsets_(),
95     nIntFaces_(0),
96     ownerPtr_(NULL),
97     neighbourPtr_(NULL)
100 //- Construct from components with the boundary
101 polyMeshGenFaces::polyMeshGenFaces
103     const Time& runTime,
104     const pointField& points,
105     const faceList& faces,
106     const wordList& patchNames,
107     const labelList& patchStart,
108     const labelList& nFacesInPatch
111     polyMeshGenPoints(runTime, points),
112     faces_
113     (
114         IOobject
115         (
116             "faces",
117             runTime.constant(),
118             "polyMesh",
119             runTime
120         ),
121         faces
122     ),
123     procBoundaries_(),
124     boundaries_(),
125     faceSubsets_(),
126     nIntFaces_(0),
127     ownerPtr_(NULL),
128     neighbourPtr_(NULL)
130     if( Pstream::parRun() )
131         FatalErrorIn
132         (
133             "polyMeshGenFaces::polyMeshGenFaces("
134             "const Time& runTime,"
135             "const pointField& points,"
136             "const faceList& faces,"
137             "const wordList& patchNames,"
138             "const labelList& patchStart,"
139             "const labelList& nFacesInPatch)"
140         ) << "Cannot do this in parallel!" << exit(FatalError);
142     boundaries_.setSize(patchNames.size());
143     forAll(patchNames, patchI)
144     {
145         boundaries_.set
146         (
147             patchI,
148             new boundaryPatch
149             (
150                 patchNames[patchI],
151                 "patch",
152                 nFacesInPatch[patchI],
153                 patchStart[patchI]
154             )
155         );
156     }
159 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
160 // Destructor
161 polyMeshGenFaces::~polyMeshGenFaces()
163     clearOut();
166 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
168 label polyMeshGenFaces::faceIsInProcPatch(const label faceLabel) const
170     const label i = procBoundaries_.size() - 1;
171     if(
172         (i < 0) ||
173         (
174             faceLabel >=
175             (
176                 procBoundaries_[i].patchStart() +
177                 procBoundaries_[i].patchSize()
178             )
179         )
180     )
181         return -1;
183     forAllReverse(procBoundaries_, patchI)
184         if( faceLabel >= procBoundaries_[patchI].patchStart() )
185             return patchI;
187     return -1;
190 label polyMeshGenFaces::faceIsInPatch(const label faceLabel) const
192     const label i = boundaries_.size() - 1;
193     if( faceLabel >= (boundaries_[i].patchStart()+boundaries_[i].patchSize()) )
194         return -1;
196     forAllReverse(boundaries_, patchI)
197         if( faceLabel >= boundaries_[patchI].patchStart() )
198             return patchI;
200     return -1;
203 wordList polyMeshGenFaces::patchNames() const
205     wordList t(boundaries_.size());
207     forAll(boundaries_, patchI)
208     {
209         t[patchI] = boundaries_[patchI].patchName();
210     }
212     return t;
215 label polyMeshGenFaces::getPatchID(const word& patchName) const
217     forAll(boundaries_, patchI)
218     {
219         if(boundaries_.set(patchI))
220         {
221             if(boundaries_[patchI].patchName() == patchName)
222             {
223                 return patchI;
224             }
225         }
226     }
228     // If the code gets here, it implies that the patch was not found.
229     // return a -1 in this case
230     return -1;
233 word polyMeshGenFaces::getPatchName(const label patchID) const
235     if((patchID < 0) || (patchID >= boundaries_.size()))
236     {
237          FatalErrorIn
238          (
239              "polyMeshGenFaces::getPatchName(const label patchID) const"
240          )   << "invalid patch ID supplied"
241              << abort(FatalError);
242     }
244     return boundaries_[patchID].patchName();
247 labelList polyMeshGenFaces::findPatches(const word& patchName) const
249     wordList allPatches = patchNames();
251     labelList patchIDs = findStrings(patchName, allPatches);
253     if(patchIDs.empty())
254     {
255         WarningIn("polyMeshGenFaces::findPatches(const word&)")
256             << "Cannot find any patch names matching " << patchName << endl;
257     }
259     return patchIDs;
262 label polyMeshGenFaces::addFaceSubset(const word& setName)
264     label id = faceSubsetIndex(setName);
265     if( id >= 0 )
266     {
267         Warning << "Face subset " << setName << " already exists!" << endl;
268         return id;
269     }
271     id = 0;
272     for
273     (
274         std::map<label, meshSubset>::const_iterator it=faceSubsets_.begin();
275         it!=faceSubsets_.end();
276         ++it
277     )
278         id = Foam::max(id, it->first+1);
280     faceSubsets_.insert
281     (
282         std::make_pair
283         (
284             id,
285             meshSubset(setName, meshSubset::FACESUBSET)
286         )
287     );
289     return id;
292 void polyMeshGenFaces::removeFaceSubset(const label setI)
294     if( faceSubsets_.find(setI) == faceSubsets_.end() )
295         return;
297     faceSubsets_.erase(setI);
300 word polyMeshGenFaces::faceSubsetName(const label setI) const
302     std::map<label, meshSubset>::const_iterator it =
303         faceSubsets_.find(setI);
304     if( it == faceSubsets_.end() )
305     {
306         Warning << "Subset " << setI << " is not a face subset" << endl;
307         return word();
308     }
310     return it->second.name();
313 label polyMeshGenFaces::faceSubsetIndex(const word& setName) const
315     std::map<label, meshSubset>::const_iterator it;
316     for(it=faceSubsets_.begin();it!=faceSubsets_.end();++it)
317     {
318         if( it->second.name() == setName )
319             return it->first;
320     }
322     return -1;
325 void polyMeshGenFaces::read()
327     polyMeshGenPoints::read();
329     faceIOList fcs
330     (
331         IOobject
332         (
333             "faces",
334             runTime_.constant(),
335             "polyMesh",
336             runTime_,
337             IOobject::MUST_READ
338         )
339     );
340     faces_ = fcs;
342     deleteDemandDrivenData(ownerPtr_);
343     deleteDemandDrivenData(neighbourPtr_);
345     ownerPtr_ =
346         new labelIOList
347         (
348             IOobject
349             (
350                 "owner",
351                 runTime_.constant(),
352                 "polyMesh",
353                 runTime_,
354                 IOobject::MUST_READ
355             )
356         );
358     neighbourPtr_ =
359         new labelIOList
360         (
361             IOobject
362             (
363                 "neighbour",
364                 runTime_.constant(),
365                 "polyMesh",
366                 runTime_,
367                 IOobject::MUST_READ
368             )
369         );
371     if( neighbourPtr_->size() != ownerPtr_->size() )
372         neighbourPtr_->setSize(ownerPtr_->size(), -1);
374     //- read boundary information
375     IOPtrList<boundaryPatchBase> patches
376     (
377         IOobject
378         (
379             "boundary",
380             runTime_.constant(),
381             "polyMesh",
382             runTime_,
383             IOobject::MUST_READ
384         )
385     );
387     label i(0);
388     forAll(patches, patchI)
389         if( patches[patchI].type() == "processor" )
390             ++i;
392     procBoundaries_.setSize(i);
393     boundaries_.setSize(patches.size()-i);
395     i=0;
396     forAll(patches, patchI)
397         if( patches[patchI].type() != "processor" )
398         {
399             boundaries_.set
400             (
401                 i,
402                 new boundaryPatch
403                 (
404                     patches[patchI].patchName(),
405                     patches[patchI].patchType(),
406                     patches[patchI].patchSize(),
407                     patches[patchI].patchStart()
408                 )
409             );
410             ++i;
411         }
413     i = 0;
414     forAll(patches, patchI)
415         if( patches[patchI].type() == "processor" )
416         {
417             procBoundaries_.set
418             (
419                 i++,
420                 new processorBoundaryPatch
421                 (
422                     patches[patchI].patchName(),
423                     patches[patchI].dict()
424                 )
425             );
426         }
428     nIntFaces_ = boundaries_[0].patchStart();
430     //- read face subsets
431     IOobjectList allSets
432     (
433         runTime_,
434         runTime_.constant(),
435         "polyMesh/sets"
436     );
438     wordList setNames = allSets.names("faceSet");
439     forAll(setNames, setI)
440     {
441         IOobject* obj = allSets.lookup(setNames[setI]);
443         faceSet fSet(*obj);
444         const labelList content = fSet.toc();
445         const label id = addFaceSubset(setNames[setI]);
447         faceSubsets_[id].updateSubset(content);
448     }
451 void polyMeshGenFaces::write() const
453     polyMeshGenPoints::write();
455     faces_.write();
457     if( !ownerPtr_ || !neighbourPtr_ )
458         calculateOwnersAndNeighbours();
459     ownerPtr_->write();
460     neighbourPtr_->write();
462     //- write boundary data
463     PtrList<boundaryPatchBase> ptchs
464     (
465         procBoundaries_.size() + boundaries_.size()
466     );
468     label i(0);
470     //- ordinary patches come first
471     forAll(boundaries_, patchI)
472     {
473         dictionary dict;
474         dict.add("type", boundaries_[patchI].patchType());
475         dict.add("nFaces", boundaries_[patchI].patchSize());
476         dict.add("startFace", boundaries_[patchI].patchStart());
477         ptchs.set
478         (
479             i++,
480             boundaryPatchBase::New
481             (
482                 boundaries_[patchI].patchName(),
483                 dict
484             )
485         );
486     }
488     //- processor patches are at the end
489     forAll(procBoundaries_, patchI)
490     {
491         ptchs.set
492         (
493             i++,
494             boundaryPatchBase::New
495             (
496                 procBoundaries_[patchI].patchName(),
497                 procBoundaries_[patchI].dict()
498             )
499         );
500     }
502     IOPtrList<boundaryPatchBase> patches
503     (
504         IOobject
505         (
506             "boundary",
507             runTime_.constant(),
508             "polyMesh",
509             runTime_,
510             IOobject::NO_READ,
511             IOobject::AUTO_WRITE
512         ),
513         ptchs
514     );
516     patches.write();
518     //- write face subsets
519     std::map<label, meshSubset>::const_iterator setIt;
520     for(setIt=faceSubsets_.begin();setIt!=faceSubsets_.end();++setIt)
521     {
522         faceSet set
523         (
524             IOobject
525             (
526                 setIt->second.name(),
527                 runTime_.constant(),
528                 "polyMesh/sets",
529                 runTime_,
530                 IOobject::NO_READ,
531                 IOobject::AUTO_WRITE
532             )
533         );
535         labelLongList containedElements;
536         setIt->second.containedElements(containedElements);
538         forAll(containedElements, i)
539             set.insert(containedElements[i]);
540         set.write();
541     }
544 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
546 } // End namespace Foam
548 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //