cellMDLimitedGrads.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 "cellMDLimitedGrad.H"
27 #include "gaussGrad.H"
28 #include "fvMesh.H"
29 #include "volFields.H"
31 
32 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 
34 makeFvGradScheme(cellMDLimitedGrad)
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  scalarField maxVsf(vsf.primitiveField());
64  scalarField minVsf(vsf.primitiveField());
65 
66  forAll(owner, facei)
67  {
68  label own = owner[facei];
69  label nei = neighbour[facei];
70 
71  scalar vsfOwn = vsf[own];
72  scalar vsfNei = vsf[nei];
73 
74  maxVsf[own] = max(maxVsf[own], vsfNei);
75  minVsf[own] = min(minVsf[own], vsfNei);
76 
77  maxVsf[nei] = max(maxVsf[nei], vsfOwn);
78  minVsf[nei] = min(minVsf[nei], vsfOwn);
79  }
80 
81 
82  const volScalarField::Boundary& bsf = vsf.boundaryField();
83 
84  forAll(bsf, patchi)
85  {
86  const fvPatchScalarField& psf = bsf[patchi];
87 
88  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
89 
90  if (psf.coupled())
91  {
92  const scalarField psfNei(psf.patchNeighbourField());
93 
94  forAll(pOwner, pFacei)
95  {
96  label own = pOwner[pFacei];
97  scalar vsfNei = psfNei[pFacei];
98 
99  maxVsf[own] = max(maxVsf[own], vsfNei);
100  minVsf[own] = min(minVsf[own], vsfNei);
101  }
102  }
103  else
104  {
105  forAll(pOwner, pFacei)
106  {
107  label own = pOwner[pFacei];
108  scalar vsfNei = psf[pFacei];
109 
110  maxVsf[own] = max(maxVsf[own], vsfNei);
111  minVsf[own] = min(minVsf[own], vsfNei);
112  }
113  }
114  }
115 
116  maxVsf -= vsf;
117  minVsf -= vsf;
118 
119  if (k_ < 1.0)
120  {
121  const scalarField maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
122  maxVsf += maxMinVsf;
123  minVsf -= maxMinVsf;
124 
125  // maxVsf *= 1.0/k_;
126  // minVsf *= 1.0/k_;
127  }
128 
129 
130  forAll(owner, facei)
131  {
132  label own = owner[facei];
133  label nei = neighbour[facei];
134 
135  // owner side
136  limitFace
137  (
138  g[own],
139  maxVsf[own],
140  minVsf[own],
141  Cf[facei] - C[own]
142  );
143 
144  // neighbour side
145  limitFace
146  (
147  g[nei],
148  maxVsf[nei],
149  minVsf[nei],
150  Cf[facei] - C[nei]
151  );
152  }
153 
154 
155  forAll(bsf, patchi)
156  {
157  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
158  const vectorField& pCf = Cf.boundaryField()[patchi];
159 
160  forAll(pOwner, pFacei)
161  {
162  label own = pOwner[pFacei];
163 
164  limitFace
165  (
166  g[own],
167  maxVsf[own],
168  minVsf[own],
169  pCf[pFacei] - C[own]
170  );
171  }
172  }
173 
174  g.correctBoundaryConditions();
176 
177  return tGrad;
178 }
179 
180 
181 template<>
184 (
185  const volVectorField& vsf,
186  const word& name
187 ) const
188 {
189  const fvMesh& mesh = vsf.mesh();
190 
191  tmp<volTensorField> tGrad = basicGradScheme_().calcGrad(vsf, name);
192 
193  if (k_ < small)
194  {
195  return tGrad;
196  }
197 
198  volTensorField& g = tGrad.ref();
199 
200  const labelUList& owner = mesh.owner();
201  const labelUList& neighbour = mesh.neighbour();
202 
203  const volVectorField& C = mesh.C();
204  const surfaceVectorField& Cf = mesh.Cf();
205 
206  vectorField maxVsf(vsf.primitiveField());
207  vectorField minVsf(vsf.primitiveField());
208 
209  forAll(owner, facei)
210  {
211  label own = owner[facei];
212  label nei = neighbour[facei];
213 
214  const vector& vsfOwn = vsf[own];
215  const vector& vsfNei = vsf[nei];
216 
217  maxVsf[own] = max(maxVsf[own], vsfNei);
218  minVsf[own] = min(minVsf[own], vsfNei);
219 
220  maxVsf[nei] = max(maxVsf[nei], vsfOwn);
221  minVsf[nei] = min(minVsf[nei], vsfOwn);
222  }
223 
224 
225  const volVectorField::Boundary& bsf = vsf.boundaryField();
226 
227  forAll(bsf, patchi)
228  {
229  const fvPatchVectorField& psf = bsf[patchi];
230  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
231 
232  if (psf.coupled())
233  {
234  const vectorField psfNei(psf.patchNeighbourField());
235 
236  forAll(pOwner, pFacei)
237  {
238  label own = pOwner[pFacei];
239  const vector& vsfNei = psfNei[pFacei];
240 
241  maxVsf[own] = max(maxVsf[own], vsfNei);
242  minVsf[own] = min(minVsf[own], vsfNei);
243  }
244  }
245  else
246  {
247  forAll(pOwner, pFacei)
248  {
249  label own = pOwner[pFacei];
250  const vector& vsfNei = psf[pFacei];
251 
252  maxVsf[own] = max(maxVsf[own], vsfNei);
253  minVsf[own] = min(minVsf[own], vsfNei);
254  }
255  }
256  }
257 
258  maxVsf -= vsf;
259  minVsf -= vsf;
260 
261  if (k_ < 1.0)
262  {
263  const vectorField maxMinVsf((1.0/k_ - 1.0)*(maxVsf - minVsf));
264  maxVsf += maxMinVsf;
265  minVsf -= maxMinVsf;
266 
267  // maxVsf *= 1.0/k_;
268  // minVsf *= 1.0/k_;
269  }
270 
271 
272  forAll(owner, facei)
273  {
274  label own = owner[facei];
275  label nei = neighbour[facei];
276 
277  // owner side
278  limitFace
279  (
280  g[own],
281  maxVsf[own],
282  minVsf[own],
283  Cf[facei] - C[own]
284  );
285 
286  // neighbour side
287  limitFace
288  (
289  g[nei],
290  maxVsf[nei],
291  minVsf[nei],
292  Cf[facei] - C[nei]
293  );
294  }
295 
296 
297  forAll(bsf, patchi)
298  {
299  const labelUList& pOwner = mesh.boundary()[patchi].faceCells();
300  const vectorField& pCf = Cf.boundaryField()[patchi];
301 
302  forAll(pOwner, pFacei)
303  {
304  label own = pOwner[pFacei];
305 
306  limitFace
307  (
308  g[own],
309  maxVsf[own],
310  minVsf[own],
311  pCf[pFacei] - C[own]
312  );
313  }
314  }
315 
318 
319  return tGrad;
320 }
321 
322 
323 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
makeFvGradScheme(cellMDLimitedGrad)
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.
const Internal::FieldType & primitiveField() const
Return a const-reference to the primitive field.
void correctBoundaryConditions()
Correct boundary field.
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 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)
volScalarField scalarField(fieldObject, mesh)
volVectorField vectorField(fieldObject, mesh)
label patchi
U correctBoundaryConditions()
static const coefficient C("C", dimTemperature, 234.5)
VolField< vector > volVectorField
Definition: volFieldsFwd.H:63
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
VolField< scalar > volScalarField
Definition: volFieldsFwd.H:62
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
word name(const LagrangianState state)
Return a string representation of a Lagrangian state enumeration.
SurfaceField< vector > surfaceVectorField
UList< label > labelUList
Definition: UList.H:65
dimensioned< Type > max(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
fvPatchField< scalar > fvPatchScalarField