FreeFOAM The Cross-Platform CFD Toolkit
smoothDelta.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 1991-2010 OpenCFD Ltd.
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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
19  for more details.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "smoothDelta.H"
28 #include <OpenFOAM/FaceCellWave.H>
29 
30 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
31 
32 namespace Foam
33 {
34 
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 
37 defineTypeNameAndDebug(smoothDelta, 0);
38 addToRunTimeSelectionTable(LESdelta, smoothDelta, dictionary);
39 
40 scalar smoothDelta::deltaData::maxDeltaRatio = 1.2;
41 
42 
43 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
44 
45 // Fill changedFaces (with face labels) and changedFacesInfo (with delta)
46 // This is the initial set of faces from which to start the waves.
47 // Since there might be lots of places with delta jumps we can follow various
48 // strategies for this initial 'seed'.
49 // - start from single cell/face and let FaceCellWave pick up all others
50 // from there. might be quite a few waves before everything settles.
51 // - start from all faces. Lots of initial transfers.
52 // We do something inbetween:
53 // - start from all faces where there is a jump. Since we cannot easily
54 // determine this across coupled patches (cyclic, processor) introduce
55 // all faces of these and let FaceCellWave sort it out.
56 void smoothDelta::setChangedFaces
57 (
58  const polyMesh& mesh,
59  const volScalarField& delta,
60  DynamicList<label>& changedFaces,
61  DynamicList<deltaData>& changedFacesInfo
62 )
63 {
64  for (label faceI = 0; faceI < mesh.nInternalFaces(); faceI++)
65  {
66  scalar ownDelta = delta[mesh.faceOwner()[faceI]];
67 
68  scalar neiDelta = delta[mesh.faceNeighbour()[faceI]];
69 
70  // Check if owner delta much larger than neighbour delta or vice versa
71 
72  if (ownDelta > deltaData::maxDeltaRatio * neiDelta)
73  {
74  changedFaces.append(faceI);
75  changedFacesInfo.append(deltaData(ownDelta));
76  }
77  else if (neiDelta > deltaData::maxDeltaRatio * ownDelta)
78  {
79  changedFaces.append(faceI);
80  changedFacesInfo.append(deltaData(neiDelta));
81  }
82  }
83 
84  // Insert all faces of coupled patches no matter what. Let FaceCellWave
85  // sort it out.
86  forAll(mesh.boundaryMesh(), patchI)
87  {
88  const polyPatch& patch = mesh.boundaryMesh()[patchI];
89 
90  if (patch.coupled())
91  {
92  forAll(patch, patchFaceI)
93  {
94  label meshFaceI = patch.start() + patchFaceI;
95 
96  scalar ownDelta = delta[mesh.faceOwner()[meshFaceI]];
97 
98  changedFaces.append(meshFaceI);
99  changedFacesInfo.append(deltaData(ownDelta));
100  }
101  }
102  }
103 
104  changedFaces.shrink();
105  changedFacesInfo.shrink();
106 }
107 
108 
109 void smoothDelta::calcDelta()
110 {
111  deltaData::maxDeltaRatio = maxDeltaRatio_;
112  const volScalarField& geometricDelta = geometricDelta_();
113 
114  // Fill changed faces with info
115  DynamicList<label> changedFaces(mesh_.nFaces()/100 + 100);
116  DynamicList<deltaData> changedFacesInfo(changedFaces.size());
117 
118  setChangedFaces(mesh_, geometricDelta, changedFaces, changedFacesInfo);
119 
120  // Set initial field on cells.
121  List<deltaData> cellDeltaData(mesh_.nCells());
122 
123  forAll(geometricDelta, cellI)
124  {
125  cellDeltaData[cellI] = geometricDelta[cellI];
126  }
127 
128  // Set initial field on faces.
129  List<deltaData> faceDeltaData(mesh_.nFaces());
130 
131 
132  // Propagate information over whole domain.
133  FaceCellWave<deltaData> deltaCalc
134  (
135  mesh_,
136  changedFaces,
137  changedFacesInfo,
138  faceDeltaData,
139  cellDeltaData,
140  mesh_.globalData().nTotalCells() // max iterations
141  );
142 
143  forAll(delta_, cellI)
144  {
145  delta_[cellI] = cellDeltaData[cellI].delta();
146  }
147 }
148 
149 
150 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
151 
152 smoothDelta::smoothDelta
153 (
154  const word& name,
155  const fvMesh& mesh,
156  const dictionary& dd
157 )
158 :
159  LESdelta(name, mesh),
160  geometricDelta_
161  (
162  LESdelta::New("geometricDelta", mesh, dd.subDict(type() + "Coeffs"))
163  ),
164  maxDeltaRatio_
165  (
166  readScalar(dd.subDict(type() + "Coeffs").lookup("maxDeltaRatio"))
167  )
168 {
169  calcDelta();
170 }
171 
172 
173 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
174 
176 {
177  const dictionary& dd(d.subDict(type() + "Coeffs"));
178 
179  geometricDelta_().read(dd);
180  dd.lookup("maxDeltaRatio") >> maxDeltaRatio_;
181  calcDelta();
182 }
183 
184 
186 {
187  geometricDelta_().correct();
188 
189  if (mesh_.changing())
190  {
191  calcDelta();
192  }
193 }
194 
195 
196 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
197 
198 } // End namespace Foam
199 
200 // ************************ vim: set sw=4 sts=4 et: ************************ //