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 "singleCellFvMesh.H"
27 #include "syncTools.H"
28 #include "uindirectPrimitivePatch.H"
30 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 // Conversion is a two step process:
33 // - from original (fine) patch faces to agglomerations (aggloms might not
34 // be in correct patch order)
35 // - from agglomerations to coarse patch faces
36 void Foam::singleCellFvMesh::agglomerateMesh
39 const labelListList& agglom
42 const polyBoundaryMesh& oldPatches = mesh.boundaryMesh();
44 // Check agglomeration within patch face range and continuous
45 labelList nAgglom(oldPatches.size(), 0);
47 forAll(oldPatches, patchI)
49 const polyPatch& pp = oldPatches[patchI];
52 nAgglom[patchI] = max(agglom[patchI])+1;
56 if (agglom[patchI][i] < 0 || agglom[patchI][i] >= pp.size())
60 "singleCellFvMesh::agglomerateMesh(..)"
61 ) << "agglomeration on patch " << patchI
62 << " is out of range 0.." << pp.size()-1
69 // Check agglomeration is sync
71 // Get neighbouring agglomeration
72 labelList nbrAgglom(mesh.nFaces()-mesh.nInternalFaces());
73 forAll(oldPatches, patchI)
75 const polyPatch& pp = oldPatches[patchI];
79 label offset = pp.start()-mesh.nInternalFaces();
82 nbrAgglom[offset+i] = agglom[patchI][i];
86 syncTools::swapBoundaryFaceList(mesh, nbrAgglom);
89 // Get correspondence between this agglomeration and remote one
90 Map<label> localToNbr(nbrAgglom.size()/10);
92 forAll(oldPatches, patchI)
94 const polyPatch& pp = oldPatches[patchI];
98 label offset = pp.start()-mesh.nInternalFaces();
102 label bFaceI = offset+i;
103 label myZone = agglom[patchI][i];
104 label nbrZone = nbrAgglom[bFaceI];
106 Map<label>::const_iterator iter = localToNbr.find(myZone);
108 if (iter == localToNbr.end())
110 // First occurence of this zone. Store correspondence
111 // to remote zone number.
112 localToNbr.insert(myZone, nbrZone);
116 // Check that zone numbers are still the same.
117 if (iter() != nbrZone)
121 "singleCellFvMesh::agglomerateMesh(..)"
122 ) << "agglomeration is not synchronised across"
123 << " coupled patch " << pp.name()
125 << "Local agglomeration " << myZone
126 << ". Remote agglomeration " << nbrZone
137 forAll(nAgglom, patchI)
139 coarseI += nAgglom[patchI];
142 faceList patchFaces(coarseI);
143 // New patch start and size
144 labelList patchStarts(oldPatches.size());
145 labelList patchSizes(oldPatches.size());
147 // From new patch face back to agglomeration
148 patchFaceMap_.setSize(oldPatches.size());
150 // From fine face to coarse face (or -1)
151 reverseFaceMap_.setSize(mesh.nFaces());
152 reverseFaceMap_.labelList::operator=(-1);
158 forAll(oldPatches, patchI)
160 patchStarts[patchI] = coarseI;
162 const polyPatch& pp = oldPatches[patchI];
166 patchFaceMap_[patchI].setSize(nAgglom[patchI]);
168 // Patchfaces per agglomeration
169 labelListList agglomToPatch
171 invertOneToMany(nAgglom[patchI], agglom[patchI])
174 // From agglomeration to compact patch face
175 labelList agglomToFace(nAgglom[patchI], -1);
179 label myAgglom = agglom[patchI][i];
181 if (agglomToFace[myAgglom] == -1)
183 // Agglomeration not yet done. We now have:
184 // - coarseI : current coarse mesh face
185 // - patchStarts[patchI] : coarse mesh patch start
186 // - myAgglom : agglomeration
187 // - agglomToPatch[myAgglom] : fine mesh faces for zone
188 label coarsePatchFaceI = coarseI - patchStarts[patchI];
189 patchFaceMap_[patchI][coarsePatchFaceI] = myAgglom;
190 agglomToFace[myAgglom] = coarsePatchFaceI;
192 const labelList& fineFaces = agglomToPatch[myAgglom];
194 // Create overall map from fine mesh faces to coarseI.
195 forAll(fineFaces, fineI)
197 reverseFaceMap_[pp.start()+fineFaces[fineI]] = coarseI;
200 // Construct single face
201 uindirectPrimitivePatch upp
203 UIndirectList<face>(pp, fineFaces),
207 if (upp.edgeLoops().size() != 1)
211 "singleCellFvMesh::agglomerateMesh(..)"
212 ) << "agglomeration does not create a"
213 << " single, non-manifold"
214 << " face for agglomeration " << myAgglom
215 << " on patch " << patchI
219 patchFaces[coarseI++] = face
231 patchSizes[patchI] = coarseI-patchStarts[patchI];
234 //Pout<< "patchStarts:" << patchStarts << endl;
235 //Pout<< "patchSizes:" << patchSizes << endl;
237 // Compact numbering for points
238 reversePointMap_.setSize(mesh.nPoints());
239 reversePointMap_.labelList::operator=(-1);
242 forAll(patchFaces, coarseI)
244 face& f = patchFaces[coarseI];
248 if (reversePointMap_[f[fp]] == -1)
250 reversePointMap_[f[fp]] = newI++;
253 f[fp] = reversePointMap_[f[fp]];
257 pointMap_ = invert(newI, reversePointMap_);
259 // Subset used points
260 pointField boundaryPoints(mesh.points(), pointMap_);
262 // Add patches (on still zero sized mesh)
263 List<polyPatch*> newPatches(oldPatches.size());
264 forAll(oldPatches, patchI)
266 newPatches[patchI] = oldPatches[patchI].clone
274 addFvPatches(newPatches);
276 // Owner, neighbour is trivial
277 labelList owner(patchFaces.size(), 0);
278 labelList neighbour(0);
281 // actually change the mesh
284 xferMove(boundaryPoints),
285 xferMove(patchFaces),
296 cellZones().setSize(mesh.cellZones().size());
298 forAll(mesh.cellZones(), zoneI)
300 const cellZone& oldFz = mesh.cellZones()[zoneI];
302 DynamicList<label> newAddressing;
304 //Note: uncomment if you think it makes sense. Note that value
305 // of cell0 is the average.
306 //// Was old cell0 in this cellZone?
307 //if (oldFz.localID(0) != -1)
309 // newAddressing.append(0);
326 faceZones().setSize(mesh.faceZones().size());
328 forAll(mesh.faceZones(), zoneI)
330 const faceZone& oldFz = mesh.faceZones()[zoneI];
332 DynamicList<label> newAddressing(oldFz.size());
333 DynamicList<bool> newFlipMap(oldFz.size());
337 label newFaceI = reverseFaceMap_[oldFz[i]];
341 newAddressing.append(newFaceI);
342 newFlipMap.append(oldFz.flipMap()[i]);
361 pointZones().clear();
362 pointZones().setSize(mesh.pointZones().size());
364 forAll(mesh.pointZones(), zoneI)
366 const pointZone& oldFz = mesh.pointZones()[zoneI];
368 DynamicList<label> newAddressing(oldFz.size());
372 label newPointI = reversePointMap_[oldFz[i]];
375 newAddressing.append(newPointI);
394 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
396 Foam::singleCellFvMesh::singleCellFvMesh
405 xferCopy(pointField()), //points
406 xferCopy(faceList()), //faces
407 xferCopy(labelList()), //allOwner
408 xferCopy(labelList()), //allNeighbour
411 patchFaceAgglomeration_
415 "patchFaceAgglomeration",
435 mesh.boundaryMesh().size()
477 const polyBoundaryMesh& oldPatches = mesh.boundaryMesh();
479 labelListList agglom(oldPatches.size());
481 forAll(oldPatches, patchI)
483 agglom[patchI] = identity(oldPatches[patchI].size());
486 agglomerateMesh(mesh, agglom);
490 Foam::singleCellFvMesh::singleCellFvMesh
494 const labelListList& patchFaceAgglomeration
500 xferCopy(pointField()), //points
501 xferCopy(faceList()), //faces
502 xferCopy(labelList()), //allOwner
503 xferCopy(labelList()), //allNeighbour
506 patchFaceAgglomeration_
510 "patchFaceAgglomeration",
517 patchFaceAgglomeration
530 mesh.boundaryMesh().size()
572 agglomerateMesh(mesh, patchFaceAgglomeration);
576 Foam::singleCellFvMesh::singleCellFvMesh(const IOobject& io)
579 patchFaceAgglomeration_
583 "patchFaceAgglomeration",
642 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
646 // ************************************************************************* //