faceLimitedGrads.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2026 OpenFOAM Foundation
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 "faceLimitedGrad.H"
27 #include "gaussGrad.H"
28 #include "fvMesh.H"
29 #include "volFields.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 makeFvGradScheme(faceLimitedGrad)
35 
36 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
37 
38 template<>
41 (
42  const volScalarField& vsf,
43  const word& name
44 ) const
45 {
46  const fvMesh& mesh = vsf.mesh();
47 
48  tmp<volVectorField> tGrad = basicGradScheme_().calcGrad(vsf, name);
49 
50  if (k_ < small)
51  {
52  return tGrad;
53  }
54 
55  volVectorField& g = tGrad.ref();
56 
57  const labelUList& owner = mesh.owner();
58  const labelUList& neighbour = mesh.neighbour();
59 
60  const volVectorField& C = mesh.C();
61  const surfaceVectorField& Cf = mesh.Cf();
62 
63  // create limiter
64  scalarField limiter(vsf.primitiveField().size(), 1.0);
65 
66  scalar rk = (1.0/k_ - 1.0);
67 
68  forAll(owner, facei)
69  {
70  label own = owner[facei];
71  label nei = neighbour[facei];
72 
73  scalar vsfOwn = vsf[own];
74  scalar vsfNei = vsf[nei];
75 
76  scalar maxFace = max(vsfOwn, vsfNei);
77  scalar minFace = min(vsfOwn, vsfNei);
78  scalar maxMinFace = rk*(maxFace - minFace);
79  maxFace += maxMinFace;
80  minFace -= maxMinFace;
81 
82  // owner side
83  limitFace
84  (
85  limiter[own],
86  maxFace - vsfOwn, minFace - vsfOwn,
87  (Cf[facei] - C[own]) & g[own]
88  );
89 
90  // neighbour side
91  limitFace
92  (
93  limiter[nei],
94  maxFace - vsfNei, minFace - vsfNei,
95  (Cf[facei] - C[nei]) & g[nei]
96  );
97  }
98 
99  const volScalarField::Boundary& bsf = vsf.boundaryField();
100 
101  forAll(bsf, patchi)
102  {
103  const fvPatchScalarField& psf = bsf[patchi];
104 
105  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
106  const vectorField& pCf = Cf.boundaryField()[patchi];
107 
108  if (psf.coupled())
109  {
110  const scalarField psfNei(psf.patchNeighbourField());
111 
112  forAll(pOwner, pFacei)
113  {
114  label own = pOwner[pFacei];
115 
116  scalar vsfOwn = vsf[own];
117  scalar vsfNei = psfNei[pFacei];
118 
119  scalar maxFace = max(vsfOwn, vsfNei);
120  scalar minFace = min(vsfOwn, vsfNei);
121  scalar maxMinFace = rk*(maxFace - minFace);
122  maxFace += maxMinFace;
123  minFace -= maxMinFace;
124 
125  limitFace
126  (
127  limiter[own],
128  maxFace - vsfOwn, minFace - vsfOwn,
129  (pCf[pFacei] - C[own]) & g[own]
130  );
131  }
132  }
133  else if (psf.fixesValue())
134  {
135  forAll(pOwner, pFacei)
136  {
137  label own = pOwner[pFacei];
138 
139  scalar vsfOwn = vsf[own];
140  scalar vsfNei = psf[pFacei];
141 
142  scalar maxFace = max(vsfOwn, vsfNei);
143  scalar minFace = min(vsfOwn, vsfNei);
144  scalar maxMinFace = rk*(maxFace - minFace);
145  maxFace += maxMinFace;
146  minFace -= maxMinFace;
147 
148  limitFace
149  (
150  limiter[own],
151  maxFace - vsfOwn, minFace - vsfOwn,
152  (pCf[pFacei] - C[own]) & g[own]
153  );
154  }
155  }
156  }
157 
158  if (fv::debug)
159  {
160  Info<< "gradient limiter for: " << vsf.name()
161  << " max = " << gMax(limiter)
162  << " min = " << gMin(limiter)
163  << " average: " << gAverage(limiter) << endl;
164  }
165 
166  g.primitiveFieldRef() *= limiter;
167  g.correctBoundaryConditions();
169 
170  return tGrad;
171 }
172 
173 
174 template<>
177 (
178  const volVectorField& vvf,
179  const word& name
180 ) const
181 {
182  const fvMesh& mesh = vvf.mesh();
183 
184  tmp<volTensorField> tGrad = basicGradScheme_().calcGrad(vvf, name);
185 
186  if (k_ < small)
187  {
188  return tGrad;
189  }
190 
191  volTensorField& g = tGrad.ref();
192 
193  const labelUList& owner = mesh.owner();
194  const labelUList& neighbour = mesh.neighbour();
195 
196  const volVectorField& C = mesh.C();
197  const surfaceVectorField& Cf = mesh.Cf();
198 
199  // create limiter
200  scalarField limiter(vvf.primitiveField().size(), 1.0);
201 
202  scalar rk = (1.0/k_ - 1.0);
203 
204  forAll(owner, facei)
205  {
206  label own = owner[facei];
207  label nei = neighbour[facei];
208 
209  vector vvfOwn = vvf[own];
210  vector vvfNei = vvf[nei];
211 
212  // owner side
213  vector gradf = (Cf[facei] - C[own]) & g[own];
214 
215  scalar vsfOwn = gradf & vvfOwn;
216  scalar vsfNei = gradf & vvfNei;
217 
218  scalar maxFace = max(vsfOwn, vsfNei);
219  scalar minFace = min(vsfOwn, vsfNei);
220  scalar maxMinFace = rk*(maxFace - minFace);
221  maxFace += maxMinFace;
222  minFace -= maxMinFace;
223 
224  limitFace
225  (
226  limiter[own],
227  maxFace - vsfOwn, minFace - vsfOwn,
228  magSqr(gradf)
229  );
230 
231 
232  // neighbour side
233  gradf = (Cf[facei] - C[nei]) & g[nei];
234 
235  vsfOwn = gradf & vvfOwn;
236  vsfNei = gradf & vvfNei;
237 
238  maxFace = max(vsfOwn, vsfNei);
239  minFace = min(vsfOwn, vsfNei);
240 
241  limitFace
242  (
243  limiter[nei],
244  maxFace - vsfNei, minFace - vsfNei,
245  magSqr(gradf)
246  );
247  }
248 
249 
250  const volVectorField::Boundary& bvf = vvf.boundaryField();
251 
252  forAll(bvf, patchi)
253  {
254  const fvPatchVectorField& psf = bvf[patchi];
255 
256  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
257  const vectorField& pCf = Cf.boundaryField()[patchi];
258 
259  if (psf.coupled())
260  {
261  const vectorField psfNei(psf.patchNeighbourField());
262 
263  forAll(pOwner, pFacei)
264  {
265  label own = pOwner[pFacei];
266 
267  vector vvfOwn = vvf[own];
268  vector vvfNei = psfNei[pFacei];
269 
270  vector gradf = (pCf[pFacei] - C[own]) & g[own];
271 
272  scalar vsfOwn = gradf & vvfOwn;
273  scalar vsfNei = gradf & vvfNei;
274 
275  scalar maxFace = max(vsfOwn, vsfNei);
276  scalar minFace = min(vsfOwn, vsfNei);
277  scalar maxMinFace = rk*(maxFace - minFace);
278  maxFace += maxMinFace;
279  minFace -= maxMinFace;
280 
281  limitFace
282  (
283  limiter[own],
284  maxFace - vsfOwn, minFace - vsfOwn,
285  magSqr(gradf)
286  );
287  }
288  }
289  else if (psf.fixesValue())
290  {
291  forAll(pOwner, pFacei)
292  {
293  label own = pOwner[pFacei];
294 
295  vector vvfOwn = vvf[own];
296  vector vvfNei = psf[pFacei];
297 
298  vector gradf = (pCf[pFacei] - C[own]) & g[own];
299 
300  scalar vsfOwn = gradf & vvfOwn;
301  scalar vsfNei = gradf & vvfNei;
302 
303  scalar maxFace = max(vsfOwn, vsfNei);
304  scalar minFace = min(vsfOwn, vsfNei);
305  scalar maxMinFace = rk*(maxFace - minFace);
306  maxFace += maxMinFace;
307  minFace -= maxMinFace;
308 
309  limitFace
310  (
311  limiter[own],
312  maxFace - vsfOwn, minFace - vsfOwn,
313  magSqr(gradf)
314  );
315  }
316  }
317  }
318 
319  if (fv::debug)
320  {
321  Info<< "gradient limiter for: " << vvf.name()
322  << " max = " << gMax(limiter)
323  << " min = " << gMin(limiter)
324  << " average: " << gAverage(limiter) << endl;
325  }
326 
327  g.primitiveFieldRef() *= limiter;
330 
331  return tGrad;
332 }
333 
334 
335 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Graphite solid properties.
Definition: C.H:51
const GeoMesh & mesh() const
Return mesh.
Generic GeometricBoundaryField class.
Generic GeometricField class.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Internal::FieldType & primitiveFieldRef()
Return a reference to the primitive field.
const Internal::FieldType & primitiveField() const
Return a const-reference to the primitive field.
void correctBoundaryConditions()
Correct boundary field.
const word & name() const
Return name.
Definition: IOobject.H:307
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:98
const volVectorField & C() const
Return cell centres.
const labelUList & owner() const
Internal face owner.
Definition: fvMesh.H:490
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:932
const surfaceVectorField & Cf() const
Return face centres.
const labelUList & neighbour() const
Internal face neighbour.
Definition: fvMesh.H:496
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:90
virtual bool fixesValue() const
Return true if this patch field fixes a value.
Definition: fvPatchField.H:326
virtual bool coupled() const
Return true if this patch field is coupled.
Definition: fvPatchField.H:339
virtual tmp< Field< Type > > patchNeighbourField(const Pstream::commsTypes commsType=Pstream::commsTypes::blocking) const
Return patchField on the opposite patch of a coupled patch.
Definition: fvPatchField.H:447
virtual tmp< VolField< typename outerProduct< vector, Type >::type > > calcGrad(const VolField< Type > &vsf, const word &name) const
Return the gradient of the given field to the gradScheme::grad.
A class for managing temporary objects.
Definition: tmp.H:55
T & ref() const
Return non-const reference or generate a fatal error.
Definition: tmpI.H:197
A class for handling words, derived from string.
Definition: word.H:63
Foam::fvMesh mesh(Foam::IOobject(regionName, runTime.name(), runTime, Foam::IOobject::MUST_READ), false)
makeFvGradScheme(faceLimitedGrad)
volScalarField scalarField(fieldObject, mesh)
volVectorField vectorField(fieldObject, mesh)
label patchi
U correctBoundaryConditions()
void limiter(const control &controls, surfaceScalarField &lambda, const RdeltaTType &rDeltaT, const RhoType &rho, const volScalarField &psi, const scalarField &SuCorr, const surfaceScalarField &phi, const surfaceScalarField &phiCorr, const SpType &Sp, const PsiMaxType &psiMax, const PsiMinType &psiMin)
Definition: MULESlimiter.C:42
static const coefficient C("C", dimTemperature, 234.5)
Type gMin(const UList< Type > &f, const label comm)
VolField< vector > volVectorField
Definition: volFieldsFwd.H:63
Type gAverage(const UList< Type > &f, const label comm)
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Type gMax(const UList< Type > &f, const label comm)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
SurfaceField< vector > surfaceVectorField
tmp< DimensionedField< scalar, GeoMesh, Field > > magSqr(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
UList< label > labelUList
Definition: UList.H:65
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
fvPatchField< scalar > fvPatchScalarField