linearUpwindVTemplates.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-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 "linearUpwindV.H"
27 
28 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
29 
30 template<class Type>
32 (
33  const fvMesh& mesh,
34  const surfaceScalarField& faceFlux
35 )
36 :
37  upwind<Type>(mesh, faceFlux),
38  gradSchemeName_("grad"),
39  gradScheme_
40  (
41  new fv::gaussGrad<Type>(mesh)
42  )
43 {}
44 
45 
46 template<class Type>
48 (
49  const fvMesh& mesh,
50  Istream& schemeData
51 )
52 :
53  upwind<Type>(mesh, schemeData),
54  gradSchemeName_(schemeData),
55  gradScheme_
56  (
58  (
59  mesh,
60  mesh.schemes().grad(gradSchemeName_)
61  )
62  )
63 {}
64 
65 
66 template<class Type>
68 (
69  const fvMesh& mesh,
70  const surfaceScalarField& faceFlux,
71  Istream& schemeData
72 )
73 :
74  upwind<Type>(mesh, faceFlux, schemeData),
75  gradSchemeName_(schemeData),
76  gradScheme_
77  (
79  (
80  mesh,
81  mesh.schemes().grad(gradSchemeName_)
82  )
83  )
84 {}
85 
86 
87 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
88 
89 template<class Type>
92 (
94 ) const
95 {
96  const fvMesh& mesh = this->mesh();
97 
99  (
101  (
102  "linearUpwindV::correction(" + vf.name() + ')',
103  mesh,
105  (
106  vf.name(),
107  vf.dimensions(),
108  Zero
109  )
110  )
111  );
112 
114 
115  const surfaceScalarField& faceFlux = this->faceFlux_;
116  const surfaceScalarField& w = mesh.weights();
117 
118  const labelList& own = mesh.owner();
119  const labelList& nei = mesh.neighbour();
120 
121  const volVectorField& C = mesh.C();
122  const surfaceVectorField& Cf = mesh.Cf();
123 
124  tmp
125  <
127  <
129  fvPatchField,
130  volMesh
131  >
132  > tgradVf = gradScheme_().grad(vf, gradSchemeName_);
133 
134  const GeometricField
135  <
136  typename outerProduct<vector, Type>::type,
137  fvPatchField,
138  volMesh
139  >& gradVf = tgradVf();
140 
141  forAll(faceFlux, facei)
142  {
143  vector maxCorr;
144 
145  if (faceFlux[facei] > 0.0)
146  {
147  maxCorr =
148  (1.0 - w[facei])*(vf[nei[facei]] - vf[own[facei]]);
149 
150  sfCorr[facei] =
151  (Cf[facei] - C[own[facei]]) & gradVf[own[facei]];
152  }
153  else
154  {
155  maxCorr =
156  w[facei]*(vf[own[facei]] - vf[nei[facei]]);
157 
158  sfCorr[facei] =
159  (Cf[facei] - C[nei[facei]]) & gradVf[nei[facei]];
160  }
161 
162  scalar sfCorrs = magSqr(sfCorr[facei]);
163  scalar maxCorrs = sfCorr[facei] & maxCorr;
164 
165  if (sfCorrs > 0)
166  {
167  if (maxCorrs < 0)
168  {
169  sfCorr[facei] = Zero;
170  }
171  else if (sfCorrs > maxCorrs)
172  {
173  sfCorr[facei] *= maxCorrs/(sfCorrs + vSmall);
174  }
175  }
176  }
177 
178 
180  Boundary& bSfCorr = sfCorr.boundaryFieldRef();
181 
182  forAll(bSfCorr, patchi)
183  {
184  fvsPatchField<Type>& pSfCorr = bSfCorr[patchi];
185 
186  if (pSfCorr.coupled())
187  {
188  const labelUList& pOwner =
189  mesh.boundary()[patchi].faceCells();
190 
191  const vectorField& pCf = Cf.boundaryField()[patchi];
192  const scalarField& pW = w.boundaryField()[patchi];
193 
194  const scalarField& pFaceFlux = faceFlux.boundaryField()[patchi];
195 
197  (
198  gradVf.boundaryField()[patchi].patchNeighbourField()
199  );
200 
201  const Field<Type> pVfNei
202  (
203  vf.boundaryField()[patchi].patchNeighbourField()
204  );
205 
206  // Build the d-vectors
207  vectorField pd(Cf.boundaryField()[patchi].patch().delta());
208 
209  forAll(pOwner, facei)
210  {
211  label own = pOwner[facei];
212 
213  vector maxCorr;
214 
215  if (pFaceFlux[facei] > 0)
216  {
217  pSfCorr[facei] = (pCf[facei] - C[own]) & gradVf[own];
218 
219  maxCorr = (1.0 - pW[facei])*(pVfNei[facei] - vf[own]);
220  }
221  else
222  {
223  pSfCorr[facei] =
224  (pCf[facei] - pd[facei] - C[own]) & pGradVfNei[facei];
225 
226  maxCorr = pW[facei]*(vf[own] - pVfNei[facei]);
227  }
228 
229  scalar pSfCorrs = magSqr(pSfCorr[facei]);
230  scalar maxCorrs = pSfCorr[facei] & maxCorr;
231 
232  if (pSfCorrs > 0)
233  {
234  if (maxCorrs < 0)
235  {
236  pSfCorr[facei] = Zero;
237  }
238  else if (pSfCorrs > maxCorrs)
239  {
240  pSfCorr[facei] *= maxCorrs/(pSfCorrs + vSmall);
241  }
242  }
243  }
244  }
245  }
246 
247  return tsfCorr;
248 }
249 
250 
251 // ************************************************************************* //
Graphite solid properties.
Definition: C.H:48
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
const word & name() const
Return name.
Definition: IOobject.H:315
const surfaceVectorField & Cf() const
Return face centres.
const Boundary & boundaryField() const
Return const-reference to the boundary field.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
linearUpwindV(const fvMesh &mesh, const surfaceScalarField &faceFlux)
Construct from faceFlux.
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:66
typeOfRank< typename pTraits< arg1 >::cmptType, direction(pTraits< arg1 >::rank)+direction(pTraits< arg2 >::rank) >::type type
Definition: products.H:90
Basic second-order gradient scheme using face-interpolation and Gauss&#39; theorem.
Definition: gaussGrad.H:57
Generic dimensioned Type class.
fvMesh & mesh
const labelUList & neighbour() const
Internal face neighbour.
Definition: fvMesh.H:423
virtual tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > correction(const GeometricField< Type, fvPatchField, volMesh > &) const
Return the explicit correction to the face-interpolate.
const dimensionSet & dimensions() const
Return dimensions.
Mesh data needed to do the Finite Volume discretisation.
Definition: volMesh.H:53
const surfaceScalarField & weights() const
Return reference to linear difference weighting factors.
virtual bool coupled() const
Return true if this patch field is coupled.
static const zero Zero
Definition: zero.H:97
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
dimensioned< scalar > magSqr(const dimensioned< Type > &)
const labelUList & owner() const
Internal face owner.
Definition: fvMesh.H:417
Internal & ref()
Return a reference to the dimensioned internal field.
label patchi
Abstract base class for gradient schemes.
Definition: gradScheme.H:60
Upwind interpolation scheme class.
Definition: upwind.H:51
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:95
const volVectorField & C() const
Return cell centres.
A class for managing temporary objects.
Definition: PtrList.H:53
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
Definition: fvsPatchField.H:65
const fvBoundaryMesh & boundary() const
Return reference to boundary mesh.
Definition: fvMesh.C:800