1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2009 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
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 "channelIndex.H"
28 #include <OpenFOAM/boolList.H>
29 #include <OpenFOAM/syncTools.H>
30 #include <OpenFOAM/OFstream.H>
31 #include <meshTools/meshTools.H>
32 #include <OpenFOAM/Time.H>
33 #include <OpenFOAM/SortableList.H>
35 // * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * * //
38 const char* Foam::NamedEnum<Foam::vector::components, 3>::names[] =
45 const Foam::NamedEnum<Foam::vector::components, 3>
46 Foam::channelIndex::vectorComponentsNames_;
49 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
51 // Determines face blocking
52 void Foam::channelIndex::walkOppositeFaces
55 const labelList& startFaces,
59 const cellList& cells = mesh.cells();
60 const faceList& faces = mesh.faces();
61 label nBnd = mesh.nFaces() - mesh.nInternalFaces();
63 DynamicList<label> frontFaces(startFaces);
66 label faceI = frontFaces[i];
67 blockedFace[faceI] = true;
70 while (returnReduce(frontFaces.size(), sumOp<label>()) > 0)
73 boolList isFrontBndFace(nBnd, false);
76 label faceI = frontFaces[i];
78 if (!mesh.isInternalFace(faceI))
80 isFrontBndFace[faceI-mesh.nInternalFaces()] = true;
83 syncTools::swapBoundaryFaceList(mesh, isFrontBndFace, false);
86 forAll(isFrontBndFace, i)
88 label faceI = mesh.nInternalFaces()+i;
89 if (isFrontBndFace[i] && !blockedFace[faceI])
91 blockedFace[faceI] = true;
92 frontFaces.append(faceI);
96 // Transfer across cells
97 DynamicList<label> newFrontFaces(frontFaces.size());
101 label faceI = frontFaces[i];
104 const cell& ownCell = cells[mesh.faceOwner()[faceI]];
106 label oppositeFaceI = ownCell.opposingFaceLabel(faceI, faces);
108 if (oppositeFaceI == -1)
110 FatalErrorIn("channelIndex::walkOppositeFaces(..)")
111 << "Face:" << faceI << " owner cell:" << ownCell
112 << " is not a hex?" << abort(FatalError);
116 if (!blockedFace[oppositeFaceI])
118 blockedFace[oppositeFaceI] = true;
119 newFrontFaces.append(oppositeFaceI);
124 if (mesh.isInternalFace(faceI))
126 const cell& neiCell = mesh.cells()[mesh.faceNeighbour()[faceI]];
128 label oppositeFaceI = neiCell.opposingFaceLabel(faceI, faces);
130 if (oppositeFaceI == -1)
132 FatalErrorIn("channelIndex::walkOppositeFaces(..)")
133 << "Face:" << faceI << " neighbour cell:" << neiCell
134 << " is not a hex?" << abort(FatalError);
138 if (!blockedFace[oppositeFaceI])
140 blockedFace[oppositeFaceI] = true;
141 newFrontFaces.append(oppositeFaceI);
147 frontFaces.transfer(newFrontFaces);
152 // Calculate regions.
153 void Foam::channelIndex::calcLayeredRegions
155 const polyMesh& mesh,
156 const labelList& startFaces
159 boolList blockedFace(mesh.nFaces(), false);
170 OFstream str(mesh.time().path()/"blockedFaces.obj");
172 forAll(blockedFace, faceI)
174 if (blockedFace[faceI])
176 const face& f = mesh.faces()[faceI];
179 meshTools::writeOBJ(str, mesh.points()[f[fp]]);
184 str << ' ' << vertI+fp+1;
193 // Do analysis for connected regions
194 cellRegion_.reset(new regionSplit(mesh, blockedFace));
196 Info<< "Detected " << cellRegion_().nRegions() << " layers." << nl << endl;
198 // Sum number of entries per region
199 regionCount_ = regionSum(scalarField(mesh.nCells(), 1.0));
201 // Average cell centres to determine ordering.
204 regionSum(mesh.cellCentres())
208 SortableList<scalar> sortComponent(regionCc.component(dir_));
210 sortMap_ = sortComponent.indices();
216 y_.setSize(cellRegion_().nRegions()/2);
221 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
223 Foam::channelIndex::channelIndex
225 const polyMesh& mesh,
226 const dictionary& dict
229 symmetric_(readBool(dict.lookup("symmetric"))),
230 dir_(vectorComponentsNames_.read(dict.lookup("component")))
232 const polyBoundaryMesh& patches = mesh.boundaryMesh();
234 const wordList patchNames(dict.lookup("patches"));
238 forAll(patchNames, i)
240 label patchI = patches.findPatchID(patchNames[i]);
244 FatalErrorIn("channelIndex::channelIndex(const polyMesh&)")
245 << "Illegal patch " << patchNames[i]
246 << ". Valid patches are " << patches.name()
250 nFaces += patches[patchI].size();
253 labelList startFaces(nFaces);
256 forAll(patchNames, i)
258 const polyPatch& pp = patches[patches.findPatchID(patchNames[i])];
262 startFaces[nFaces++] = pp.start()+j;
266 // Calculate regions.
267 calcLayeredRegions(mesh, startFaces);
271 Foam::channelIndex::channelIndex
273 const polyMesh& mesh,
274 const labelList& startFaces,
275 const bool symmetric,
279 symmetric_(symmetric),
282 // Calculate regions.
283 calcLayeredRegions(mesh, startFaces);
287 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
290 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
293 // ************************ vim: set sw=4 sts=4 et: ************************ //