1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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, 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 * * * * * * * * * * * * * * //
39 const char* Foam::NamedEnum
41 Foam::vector::components,
51 const Foam::NamedEnum<Foam::vector::components, 3>
52 Foam::channelIndex::vectorComponentsNames_;
55 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
57 // Determines face blocking
58 void Foam::channelIndex::walkOppositeFaces
61 const labelList& startFaces,
65 const cellList& cells = mesh.cells();
66 const faceList& faces = mesh.faces();
67 label nBnd = mesh.nFaces() - mesh.nInternalFaces();
69 DynamicList<label> frontFaces(startFaces);
72 label faceI = frontFaces[i];
73 blockedFace[faceI] = true;
76 while (returnReduce(frontFaces.size(), sumOp<label>()) > 0)
79 boolList isFrontBndFace(nBnd, false);
82 label faceI = frontFaces[i];
84 if (!mesh.isInternalFace(faceI))
86 isFrontBndFace[faceI-mesh.nInternalFaces()] = true;
89 syncTools::swapBoundaryFaceList(mesh, isFrontBndFace);
92 forAll(isFrontBndFace, i)
94 label faceI = mesh.nInternalFaces()+i;
95 if (isFrontBndFace[i] && !blockedFace[faceI])
97 blockedFace[faceI] = true;
98 frontFaces.append(faceI);
102 // Transfer across cells
103 DynamicList<label> newFrontFaces(frontFaces.size());
105 forAll(frontFaces, i)
107 label faceI = frontFaces[i];
110 const cell& ownCell = cells[mesh.faceOwner()[faceI]];
112 label oppositeFaceI = ownCell.opposingFaceLabel(faceI, faces);
114 if (oppositeFaceI == -1)
116 FatalErrorIn("channelIndex::walkOppositeFaces(..)")
117 << "Face:" << faceI << " owner cell:" << ownCell
118 << " is not a hex?" << abort(FatalError);
122 if (!blockedFace[oppositeFaceI])
124 blockedFace[oppositeFaceI] = true;
125 newFrontFaces.append(oppositeFaceI);
130 if (mesh.isInternalFace(faceI))
132 const cell& neiCell = mesh.cells()[mesh.faceNeighbour()[faceI]];
134 label oppositeFaceI = neiCell.opposingFaceLabel(faceI, faces);
136 if (oppositeFaceI == -1)
138 FatalErrorIn("channelIndex::walkOppositeFaces(..)")
139 << "Face:" << faceI << " neighbour cell:" << neiCell
140 << " is not a hex?" << abort(FatalError);
144 if (!blockedFace[oppositeFaceI])
146 blockedFace[oppositeFaceI] = true;
147 newFrontFaces.append(oppositeFaceI);
153 frontFaces.transfer(newFrontFaces);
158 // Calculate regions.
159 void Foam::channelIndex::calcLayeredRegions
161 const polyMesh& mesh,
162 const labelList& startFaces
165 boolList blockedFace(mesh.nFaces(), false);
176 OFstream str(mesh.time().path()/"blockedFaces.obj");
178 forAll(blockedFace, faceI)
180 if (blockedFace[faceI])
182 const face& f = mesh.faces()[faceI];
185 meshTools::writeOBJ(str, mesh.points()[f[fp]]);
190 str << ' ' << vertI+fp+1;
199 // Do analysis for connected regions
200 cellRegion_.reset(new regionSplit(mesh, blockedFace));
202 Info<< "Detected " << cellRegion_().nRegions() << " layers." << nl << endl;
204 // Sum number of entries per region
205 regionCount_ = regionSum(scalarField(mesh.nCells(), 1.0));
207 // Average cell centres to determine ordering.
210 regionSum(mesh.cellCentres())
214 SortableList<scalar> sortComponent(regionCc.component(dir_));
216 sortMap_ = sortComponent.indices();
222 y_.setSize(cellRegion_().nRegions()/2);
227 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
229 Foam::channelIndex::channelIndex
231 const polyMesh& mesh,
232 const dictionary& dict
235 symmetric_(readBool(dict.lookup("symmetric"))),
236 dir_(vectorComponentsNames_.read(dict.lookup("component")))
238 const polyBoundaryMesh& patches = mesh.boundaryMesh();
240 const wordList patchNames(dict.lookup("patches"));
244 forAll(patchNames, i)
246 const label patchI = patches.findPatchID(patchNames[i]);
250 FatalErrorIn("channelIndex::channelIndex(const polyMesh&)")
251 << "Illegal patch " << patchNames[i]
252 << ". Valid patches are " << patches.name()
256 nFaces += patches[patchI].size();
259 labelList startFaces(nFaces);
262 forAll(patchNames, i)
264 const polyPatch& pp = patches[patchNames[i]];
268 startFaces[nFaces++] = pp.start()+j;
272 // Calculate regions.
273 calcLayeredRegions(mesh, startFaces);
277 Foam::channelIndex::channelIndex
279 const polyMesh& mesh,
280 const labelList& startFaces,
281 const bool symmetric,
285 symmetric_(symmetric),
288 // Calculate regions.
289 calcLayeredRegions(mesh, startFaces);
293 // ************************************************************************* //