cellLimitedGrad.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) 2018-2022 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 "cellLimitedGrad.H"
27 #include "gaussGrad.H"
28 
29 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
30 
31 template<class Type, class Limiter>
33 (
34  const Field<scalar>& limiter,
35  Field<vector>& gIf
36 ) const
37 {
38  gIf *= limiter;
39 }
40 
41 
42 template<class Type, class Limiter>
44 (
45  const Field<vector>& limiter,
46  Field<tensor>& gIf
47 ) const
48 {
49  forAll(gIf, celli)
50  {
51  gIf[celli] = tensor
52  (
53  cmptMultiply(limiter[celli], gIf[celli].x()),
54  cmptMultiply(limiter[celli], gIf[celli].y()),
55  cmptMultiply(limiter[celli], gIf[celli].z())
56  );
57  }
58 }
59 
60 
61 template<class Type, class Limiter>
63 <
65 >
67 (
68  const VolField<Type>& vsf,
69  const word& name
70 ) const
71 {
72  const fvMesh& mesh = vsf.mesh();
73 
75  tGrad = basicGradScheme_().calcGrad(vsf, name);
76 
77  if (k_ < small)
78  {
79  return tGrad;
80  }
81 
83 
84  const labelUList& owner = mesh.owner();
85  const labelUList& neighbour = mesh.neighbour();
86 
87  const volVectorField& C = mesh.C();
88  const surfaceVectorField& Cf = mesh.Cf();
89 
90  Field<Type> maxVsf(vsf.primitiveField());
91  Field<Type> minVsf(vsf.primitiveField());
92 
93  forAll(owner, facei)
94  {
95  label own = owner[facei];
96  label nei = neighbour[facei];
97 
98  const Type& vsfOwn = vsf[own];
99  const Type& vsfNei = vsf[nei];
100 
101  maxVsf[own] = max(maxVsf[own], vsfNei);
102  minVsf[own] = min(minVsf[own], vsfNei);
103 
104  maxVsf[nei] = max(maxVsf[nei], vsfOwn);
105  minVsf[nei] = min(minVsf[nei], vsfOwn);
106  }
107 
108 
109  const typename VolField<Type>::Boundary& bsf =
110  vsf.boundaryField();
111 
112  forAll(bsf, patchi)
113  {
114  const fvPatchField<Type>& psf = bsf[patchi];
115  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
116 
117  if (psf.coupled())
118  {
119  const Field<Type> psfNei(psf.patchNeighbourField());
120 
121  forAll(pOwner, pFacei)
122  {
123  label own = pOwner[pFacei];
124  const Type& vsfNei = psfNei[pFacei];
125 
126  maxVsf[own] = max(maxVsf[own], vsfNei);
127  minVsf[own] = min(minVsf[own], vsfNei);
128  }
129  }
130  else
131  {
132  forAll(pOwner, pFacei)
133  {
134  label own = pOwner[pFacei];
135  const Type& vsfNei = psf[pFacei];
136 
137  maxVsf[own] = max(maxVsf[own], vsfNei);
138  minVsf[own] = min(minVsf[own], vsfNei);
139  }
140  }
141  }
142 
143  maxVsf -= vsf;
144  minVsf -= vsf;
145 
146  if (k_ < 1.0)
147  {
148  const Field<Type> maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
149  maxVsf += maxMinVsf;
150  minVsf -= maxMinVsf;
151  }
152 
153 
154  // Create limiter initialised to 1
155  // Note: the limiter is not permitted to be > 1
156  Field<Type> limiter(vsf.primitiveField().size(), pTraits<Type>::one);
157 
158  forAll(owner, facei)
159  {
160  label own = owner[facei];
161  label nei = neighbour[facei];
162 
163  // owner side
164  limitFace
165  (
166  limiter[own],
167  maxVsf[own],
168  minVsf[own],
169  (Cf[facei] - C[own]) & g[own]
170  );
171 
172  // neighbour side
173  limitFace
174  (
175  limiter[nei],
176  maxVsf[nei],
177  minVsf[nei],
178  (Cf[facei] - C[nei]) & g[nei]
179  );
180  }
181 
182  forAll(bsf, patchi)
183  {
184  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
185  const vectorField& pCf = Cf.boundaryField()[patchi];
186 
187  forAll(pOwner, pFacei)
188  {
189  label own = pOwner[pFacei];
190 
191  limitFace
192  (
193  limiter[own],
194  maxVsf[own],
195  minVsf[own],
196  ((pCf[pFacei] - C[own]) & g[own])
197  );
198  }
199  }
200 
201  if (fv::debug)
202  {
203  Info<< "gradient limiter for: " << vsf.name()
204  << " max = " << gMax(limiter)
205  << " min = " << gMin(limiter)
206  << " average: " << gAverage(limiter) << endl;
207  }
208 
209  limitGradient(limiter, g);
210  g.correctBoundaryConditions();
212 
213  return tGrad;
214 }
215 
216 
217 // ************************************************************************* //
static const Foam::dimensionedScalar C("C", Foam::dimTemperature, 234.5)
scalar y
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
Generic GeometricField class.
cellLimitedGrad gradient scheme applied to a runTime selected base gradient scheme.
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
volVectorField vectorField(fieldObject, mesh)
label patchi
U correctBoundaryConditions()
void limiter(surfaceScalarField &lambda, const RdeltaTType &rDeltaT, const RhoType &rho, const volScalarField &psi, const surfaceScalarField &phiBD, const surfaceScalarField &phiCorr, const SpType &Sp, const SuType &Su, const PsiMaxType &psiMax, const PsiMinType &psiMin)
VolField< vector > volVectorField
Definition: volFieldsFwd.H:62
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
Tensor< scalar > tensor
Tensor of scalars.
Definition: tensor.H:51
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
word name(const bool)
Return a word representation of a bool.
Definition: boolIO.C:39
messageStream Info
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
Type gAverage(const FieldField< Field, Type > &f)
Type gMin(const FieldField< Field, Type > &f)
SurfaceField< vector > surfaceVectorField
UList< label > labelUList
Definition: UList.H:65
Type gMax(const FieldField< Field, Type > &f)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488