1 /*---------------------------------------------------------------------------*\
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 -------------------------------------------------------------------------------
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 "channelIndex.H"
28 #include "syncTools.H"
30 #include "meshTools.H"
32 #include "SortableList.H"
34 // * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
37 const char* Foam::NamedEnum<Foam::vector::components, 3>::names[] =
44 const Foam::NamedEnum<Foam::vector::components, 3>
45 Foam::channelIndex::vectorComponentsNames_;
48 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
50 // Determines face blocking
51 void Foam::channelIndex::walkOppositeFaces
54 const labelList& startFaces,
58 const cellList& cells = mesh.cells();
59 const faceList& faces = mesh.faces();
60 label nBnd = mesh.nFaces() - mesh.nInternalFaces();
62 DynamicList<label> frontFaces(startFaces);
65 label faceI = frontFaces[i];
66 blockedFace[faceI] = true;
69 while (returnReduce(frontFaces.size(), sumOp<label>()) > 0)
72 boolList isFrontBndFace(nBnd, false);
75 label faceI = frontFaces[i];
77 if (!mesh.isInternalFace(faceI))
79 isFrontBndFace[faceI-mesh.nInternalFaces()] = true;
82 syncTools::swapBoundaryFaceList(mesh, isFrontBndFace, false);
85 forAll(isFrontBndFace, i)
87 label faceI = mesh.nInternalFaces()+i;
88 if (isFrontBndFace[i] && !blockedFace[faceI])
90 blockedFace[faceI] = true;
91 frontFaces.append(faceI);
95 // Transfer across cells
96 DynamicList<label> newFrontFaces(frontFaces.size());
100 label faceI = frontFaces[i];
103 const cell& ownCell = cells[mesh.faceOwner()[faceI]];
105 label oppositeFaceI = ownCell.opposingFaceLabel(faceI, faces);
107 if (oppositeFaceI == -1)
109 FatalErrorIn("channelIndex::walkOppositeFaces(..)")
110 << "Face:" << faceI << " owner cell:" << ownCell
111 << " is not a hex?" << abort(FatalError);
115 if (!blockedFace[oppositeFaceI])
117 blockedFace[oppositeFaceI] = true;
118 newFrontFaces.append(oppositeFaceI);
123 if (mesh.isInternalFace(faceI))
125 const cell& neiCell = mesh.cells()[mesh.faceNeighbour()[faceI]];
127 label oppositeFaceI = neiCell.opposingFaceLabel(faceI, faces);
129 if (oppositeFaceI == -1)
131 FatalErrorIn("channelIndex::walkOppositeFaces(..)")
132 << "Face:" << faceI << " neighbour cell:" << neiCell
133 << " is not a hex?" << abort(FatalError);
137 if (!blockedFace[oppositeFaceI])
139 blockedFace[oppositeFaceI] = true;
140 newFrontFaces.append(oppositeFaceI);
146 frontFaces.transfer(newFrontFaces);
151 // Calculate regions.
152 void Foam::channelIndex::calcLayeredRegions
154 const polyMesh& mesh,
155 const labelList& startFaces
158 boolList blockedFace(mesh.nFaces(), false);
169 OFstream str(mesh.time().path()/"blockedFaces.obj");
171 forAll(blockedFace, faceI)
173 if (blockedFace[faceI])
175 const face& f = mesh.faces()[faceI];
178 meshTools::writeOBJ(str, mesh.points()[f[fp]]);
183 str << ' ' << vertI+fp+1;
192 // Do analysis for connected regions
193 cellRegion_.reset(new regionSplit(mesh, blockedFace));
195 Info<< "Detected " << cellRegion_().nRegions() << " layers." << nl << endl;
197 // Sum number of entries per region
198 regionCount_ = regionSum(scalarField(mesh.nCells(), 1.0));
200 // Average cell centres to determine ordering.
203 regionSum(mesh.cellCentres())
207 SortableList<scalar> sortComponent(regionCc.component(dir_));
209 sortMap_ = sortComponent.indices();
215 y_.setSize(cellRegion_().nRegions()/2);
220 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
222 Foam::channelIndex::channelIndex
224 const polyMesh& mesh,
225 const dictionary& dict
228 symmetric_(readBool(dict.lookup("symmetric"))),
229 dir_(vectorComponentsNames_.read(dict.lookup("component")))
231 const polyBoundaryMesh& patches = mesh.boundaryMesh();
233 const wordList patchNames(dict.lookup("patches"));
237 forAll(patchNames, i)
239 label patchI = patches.findPatchID(patchNames[i]);
243 FatalErrorIn("channelIndex::channelIndex(const polyMesh&)")
244 << "Illegal patch " << patchNames[i]
245 << ". Valid patches are " << patches.name()
249 nFaces += patches[patchI].size();
252 labelList startFaces(nFaces);
255 forAll(patchNames, i)
257 const polyPatch& pp = patches[patches.findPatchID(patchNames[i])];
261 startFaces[nFaces++] = pp.start()+j;
265 // Calculate regions.
266 calcLayeredRegions(mesh, startFaces);
270 Foam::channelIndex::channelIndex
272 const polyMesh& mesh,
273 const labelList& startFaces,
274 const bool symmetric,
278 symmetric_(symmetric),
281 // Calculate regions.
282 calcLayeredRegions(mesh, startFaces);
286 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
289 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
292 // ************************************************************************* //