surfaceInterpolationScheme.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
30 #include "volFields.H"
31 #include "surfaceFields.H"
32 #include "geometricOneField.H"
34 
35 // * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
36 
37 template<class Type>
40 (
41  const fvMesh& mesh,
42  Istream& schemeData
43 )
44 {
45  if (schemeData.eof())
46  {
47  FatalIOErrorInFunction(schemeData)
48  << "Discretisation scheme not specified\n\n"
49  << "Valid schemes:\n"
50  << MeshConstructorTablePtr_->sortedToc()
51  << exit(FatalIOError);
52  }
53 
54  const word schemeName(schemeData);
55 
57  {
58  InfoInFunction << "Discretisation scheme = " << schemeName << endl;
59  }
60 
61  auto* ctorPtr = MeshConstructorTable(schemeName);
62 
63  if (!ctorPtr)
64  {
66  (
67  schemeData,
68  "discretisation",
69  schemeName,
70  *MeshConstructorTablePtr_
71  ) << exit(FatalIOError);
72  }
73 
74  return ctorPtr(mesh, schemeData);
75 }
76 
77 
78 template<class Type>
81 (
82  const fvMesh& mesh,
83  const surfaceScalarField& faceFlux,
84  Istream& schemeData
85 )
86 {
87  if (schemeData.eof())
88  {
89  FatalIOErrorInFunction(schemeData)
90  << "Discretisation scheme not specified"
91  << endl << endl
92  << "Valid schemes are :" << endl
93  << MeshConstructorTablePtr_->sortedToc()
94  << exit(FatalIOError);
95  }
96 
97  const word schemeName(schemeData);
98 
100  {
101  InfoInFunction << "Discretisation scheme = " << schemeName << endl;
102  }
103 
104  auto* ctorPtr = MeshFluxConstructorTable(schemeName);
105 
106  if (!ctorPtr)
107  {
109  (
110  schemeData,
111  "discretisation",
112  schemeName,
113  *MeshFluxConstructorTablePtr_
114  ) << exit(FatalIOError);
115  }
116 
117  return ctorPtr(mesh, faceFlux, schemeData);
118 }
120 
121 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
122 
123 template<class Type>
126 (
128  const tmp<surfaceScalarField>& tlambdas,
129  const tmp<surfaceScalarField>& tys
130 )
131 {
133  {
135  << "Interpolating "
136  << vf.type() << " "
137  << vf.name()
138  << " from cells to faces without explicit correction"
139  << endl;
140  }
141 
142  const surfaceScalarField& lambdas = tlambdas();
143  const surfaceScalarField& ys = tys();
144 
145  const Field<Type>& vfi = vf;
146  const scalarField& lambda = lambdas;
147  const scalarField& y = ys;
148 
149  const fvMesh& mesh = vf.mesh();
150  const labelUList& P = mesh.owner();
151  const labelUList& N = mesh.neighbour();
152 
154  (
156  (
157  IOobject
158  (
159  "interpolate("+vf.name()+')',
160  vf.instance(),
161  vf.db()
162  ),
163  mesh,
164  vf.dimensions()
165  )
166  );
168 
169  Field<Type>& sfi = sf.primitiveFieldRef();
170 
171  for (label fi=0; fi<P.size(); fi++)
172  {
173  sfi[fi] = lambda[fi]*vfi[P[fi]] + y[fi]*vfi[N[fi]];
174  }
175 
176 
177  // Interpolate across coupled patches using given lambdas and ys
179  Boundary& sfbf = sf.boundaryFieldRef();
180 
181  forAll(lambdas.boundaryField(), pi)
182  {
183  const fvsPatchScalarField& pLambda = lambdas.boundaryField()[pi];
184  const fvsPatchScalarField& pY = ys.boundaryField()[pi];
185 
186  if (vf.boundaryField()[pi].coupled())
187  {
188  sfbf[pi] =
189  pLambda*vf.boundaryField()[pi].patchInternalField()
190  + pY*vf.boundaryField()[pi].patchNeighbourField();
191  }
192  else
193  {
194  sfbf[pi] = vf.boundaryField()[pi];
195  }
196  }
197 
198  tlambdas.clear();
199  tys.clear();
200 
201  return tsf;
202 }
203 
204 
205 template<class Type>
206 template<class SFType>
207 Foam::tmp
208 <
210  <
214  >
215 >
217 (
218  const SFType& Sf,
220  const tmp<surfaceScalarField>& tlambdas
221 )
222 {
224  {
226  << "Interpolating "
227  << vf.type() << " "
228  << vf.name()
229  << " from cells to faces without explicit correction"
230  << endl;
231  }
232 
234  RetType;
235 
236  const surfaceScalarField& lambdas = tlambdas();
237 
238  const Field<Type>& vfi = vf;
239  const scalarField& lambda = lambdas;
240 
241  const fvMesh& mesh = vf.mesh();
242  const labelUList& P = mesh.owner();
243  const labelUList& N = mesh.neighbour();
244 
245  tmp<GeometricField<RetType, fvsPatchField, surfaceMesh>> tsf
246  (
247  new GeometricField<RetType, fvsPatchField, surfaceMesh>
248  (
249  IOobject
250  (
251  "interpolate("+vf.name()+')',
252  vf.instance(),
253  vf.db()
254  ),
255  mesh,
256  Sf.dimensions()*vf.dimensions()
257  )
258  );
259  GeometricField<RetType, fvsPatchField, surfaceMesh>& sf = tsf.ref();
260 
261  Field<RetType>& sfi = sf.primitiveFieldRef();
262 
263  const typename SFType::Internal& Sfi = Sf.internalField();
264 
265  for (label fi=0; fi<P.size(); fi++)
266  {
267  // Same as:
268  // sfi[fi] = Sfi[fi] & lerp(vfi[N[fi]], vfi[P[fi]], lambda[fi]);
269  // but maybe the compiler notices the fused multiply add form
270  sfi[fi] = Sfi[fi] & (lambda[fi]*(vfi[P[fi]] - vfi[N[fi]]) + vfi[N[fi]]);
271  }
272 
273  // Interpolate across coupled patches using given lambdas
274 
275  typename GeometricField<RetType, fvsPatchField, surfaceMesh>::
276  Boundary& sfbf = sf.boundaryFieldRef();
277 
278  forAll(lambdas.boundaryField(), pi)
279  {
280  const fvsPatchScalarField& pLambda = lambdas.boundaryField()[pi];
281  const typename SFType::Patch& pSf = Sf.boundaryField()[pi];
282  fvsPatchField<RetType>& psf = sfbf[pi];
283 
284  if (vf.boundaryField()[pi].coupled())
285  {
286  psf =
287  pSf
288  & lerp
289  (
290  vf.boundaryField()[pi].patchNeighbourField(),
291  vf.boundaryField()[pi].patchInternalField(),
292  pLambda
293  );
294  }
295  else
296  {
297  psf = pSf & vf.boundaryField()[pi];
298  }
299  }
300 
301  tlambdas.clear();
302 
303 // tsf.ref().oriented() = Sf.oriented();
304 
305  return tsf;
306 }
307 
308 
309 template<class Type>
312 (
314  const tmp<surfaceScalarField>& tlambdas
315 )
316 {
317  return dotInterpolate(geometricOneField(), vf, tlambdas);
318 }
319 
320 
321 template<class Type>
322 Foam::tmp
323 <
325  <
329  >
330 >
332 (
333  const surfaceVectorField& Sf,
334  const GeometricField<Type, fvPatchField, volMesh>& vf
335 ) const
336 {
338  {
340  << "Interpolating "
341  << vf.type() << " "
342  << vf.name()
343  << " from cells to faces"
344  << endl;
345  }
346 
347  tmp
348  <
349  GeometricField
350  <
352  fvsPatchField,
353  surfaceMesh
354  >
355  > tsf = dotInterpolate(Sf, vf, weights(vf));
356 
357  tsf.ref().oriented() = Sf.oriented();
358 
359  if (corrected())
360  {
361  tsf.ref() += Sf & correction(vf);
362  }
363 
364  return tsf;
365 }
366 
367 
368 template<class Type>
369 Foam::tmp
370 <
372  <
376  >
377 >
379 (
380  const surfaceVectorField& Sf,
381  const tmp<GeometricField<Type, fvPatchField, volMesh>>& tvf
382 ) const
383 {
384  tmp
385  <
386  GeometricField
387  <
389  fvsPatchField,
390  surfaceMesh
391  >
392  > tSfDotinterpVf = dotInterpolate(Sf, tvf());
393 
394  tvf.clear();
395  return tSfDotinterpVf;
396 }
397 
398 
399 template<class Type>
402 (
404 ) const
405 {
407  {
409  << "Interpolating "
410  << vf.type() << " "
411  << vf.name()
412  << " from cells to faces"
413  << endl;
414  }
415 
416  tmp<GeometricField<Type, fvsPatchField, surfaceMesh>> tsf
417  = interpolate(vf, weights(vf));
418 
419  if (corrected())
420  {
421  tsf.ref() += correction(vf);
422  }
423 
424  return tsf;
425 }
426 
427 
428 template<class Type>
431 (
433 ) const
434 {
436  = interpolate(tvf());
437  tvf.clear();
438  return tinterpVf;
439 }
440 
441 
442 // ************************************************************************* //
Foam::surfaceFields.
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Return the correction form of the given matrix by subtracting the matrix multiplied by the current fi...
fvsPatchField< scalar > fvsPatchScalarField
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Mesh data needed to do the Finite Volume discretisation.
Definition: surfaceMesh.H:43
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:195
T & ref() const
Return non-const reference to the contents of a non-null managed pointer.
Definition: tmpI.H:235
static tmp< GeometricField< Type, faePatchField, edgeMesh > > interpolate(const GeometricField< Type, faPatchField, areaMesh > &tvf, const edgeScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
static tmp< GeometricField< typename innerProduct< vector, Type >::type, fvsPatchField, surfaceMesh > > dotInterpolate(const surfaceVectorField &Sf, const GeometricField< Type, fvPatchField, volMesh > &tvf)
Interpolate field onto faces.
GeometricField< vector, fvsPatchField, surfaceMesh > surfaceVectorField
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
scalar y
dynamicFvMesh & mesh
A class representing the concept of a GeometricField of 1 used to avoid unnecessary manipulations for...
Generic templated field type.
Definition: Field.H:62
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
A class for handling words, derived from Foam::string.
Definition: word.H:63
static tmp< surfaceInterpolationScheme< Type > > New(const fvMesh &mesh, Istream &schemeData)
Return new tmp interpolation scheme.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:450
constexpr scalar pi(M_PI)
static tmp< GeometricField< typename innerProduct< typename SFType::value_type, Type >::type, fvsPatchField, surfaceMesh > > dotInterpolate(const SFType &Sf, const GeometricField< Type, fvPatchField, volMesh > &vf, const tmp< surfaceScalarField > &tlambdas)
Return the face-interpolate of the given cell field.
const Mesh & mesh() const noexcept
Return mesh.
int debug
Static debugging option.
dimensioned< Type > lerp(const dimensioned< Type > &a, const dimensioned< Type > &b, const scalar t)
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &, const tmp< surfaceScalarField > &, const tmp< surfaceScalarField > &)
Return the face-interpolate of the given cell field.
const fileName & instance() const noexcept
Read access to instance path component.
Definition: IOobjectI.H:266
const Vector< label > N(dict.get< Vector< label >>("N"))
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
void clear() const noexcept
If object pointer points to valid object: delete object and set pointer to nullptr.
Definition: tmpI.H:289
A class for managing temporary objects.
Definition: HashPtrTable.H:50
GeometricField< scalar, fvsPatchField, surfaceMesh > surfaceScalarField
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:172
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:635
typeOfRank< typename pTraits< arg1 >::cmptType, direction(pTraits< arg1 >::rank)+direction(pTraits< arg2 >::rank) - 2 >::type type
Definition: products.H:155
Abstract base class for surface interpolation schemes.
An abstract base class with a fat-interface to all derived classes covering all possible ways in whic...
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
bool eof() const noexcept
True if end of input seen.
Definition: IOstream.H:289
const dimensionSet & dimensions() const noexcept
Return dimensions.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
#define InfoInFunction
Report an information message using Foam::Info.