edgeInterpolationScheme.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) 2016-2017 Wikki Ltd
9  Copyright (C) 2019-2021 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 "areaFields.H"
31 #include "edgeFields.H"
32 #include "faPatchFields.H"
33 #include "coupledFaPatchField.H"
34 #include "transform.H"
35 
36 // * * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * //
37 
38 template<class Type>
41 (
42  const faMesh& mesh,
43  Istream& schemeData
44 )
45 {
47  {
49  << "constructing edgeInterpolationScheme<Type>"
50  << endl;
51  }
52 
53  if (schemeData.eof())
54  {
55  FatalIOErrorInFunction(schemeData)
56  << "Discretisation scheme not specified" << nl << nl
57  << "Valid schemes are :" << nl
58  << MeshConstructorTablePtr_->sortedToc()
59  << exit(FatalIOError);
60  }
61 
62  const word schemeName(schemeData);
63 
64  auto* ctorPtr = MeshConstructorTable(schemeName);
65 
66  if (!ctorPtr)
67  {
69  (
70  schemeData,
71  "discretisation",
72  schemeName,
73  *MeshConstructorTablePtr_
74  ) << exit(FatalIOError);
75  }
76 
77  return ctorPtr(mesh, schemeData);
78 }
79 
80 
81 template<class Type>
84 (
85  const faMesh& mesh,
86  const edgeScalarField& faceFlux,
87  Istream& schemeData
88 )
89 {
91  {
93  << "constructing edgeInterpolationScheme<Type>"
94  << endl;
95  }
96 
97  if (schemeData.eof())
98  {
99  FatalIOErrorInFunction(schemeData)
100  << "Discretisation scheme not specified"
101  << endl << endl
102  << "Valid schemes are :" << endl
103  << MeshConstructorTablePtr_->sortedToc()
104  << exit(FatalIOError);
105  }
106 
107  const word schemeName(schemeData);
108 
109  auto* ctorPtr = MeshFluxConstructorTable(schemeName);
110 
111  if (!ctorPtr)
112  {
114  (
115  schemeData,
116  "discretisation",
117  schemeName,
118  *MeshFluxConstructorTablePtr_
119  ) << exit(FatalIOError);
120  }
121 
122  return ctorPtr(mesh, faceFlux, schemeData);
123 }
124 
125 
126 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
127 
128 template<class Type>
130 {}
131 
132 
133 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
134 
135 template<class Type>
138 (
140  const tmp<edgeScalarField>& tlambdas,
141  const tmp<edgeScalarField>& tys
142 )
143 {
145  {
147  << "interpolating "
148  << vf.type() << " "
149  << vf.name()
150  << " from areas to edges "
151  "without explicit correction"
152  << endl;
153  }
154 
155  const edgeScalarField& lambdas = tlambdas();
156  const edgeScalarField& ys = tys();
157 
158  const Field<Type>& vfi = vf.internalField();
159  const scalarField& lambda = lambdas.internalField();
160  const scalarField& y = ys.internalField();
161 
162  const faMesh& mesh = vf.mesh();
163  const labelUList& P = mesh.owner();
164  const labelUList& N = mesh.neighbour();
165 
167  (
169  (
170  IOobject
171  (
172  "interpolate("+vf.name()+')',
173  vf.instance(),
174  vf.db()
175  ),
176  mesh,
177  vf.dimensions()
178  )
179  );
181 
182  Field<Type>& sfi = sf.primitiveFieldRef();
183 
184  for (label fi=0; fi<P.size(); ++fi)
185  {
186  const tensorField& curT = mesh.edgeTransformTensors()[fi];
187 
188  const tensor& Te = curT[0];
189  const tensor& TP = curT[1];
190  const tensor& TN = curT[2];
191 
192  sfi[fi] =
193  transform
194  (
195  Te.T(),
196  lambda[fi]*transform(TP, vfi[P[fi]])
197  + y[fi]*transform(TN, vfi[N[fi]])
198  );
199  }
200 
201 
202  // Interpolate across coupled patches using given lambdas and ys
203 
204  forAll(lambdas.boundaryField(), pi)
205  {
206  const faePatchScalarField& pLambda = lambdas.boundaryField()[pi];
207  const faePatchScalarField& pY = ys.boundaryField()[pi];
208 
209  if (vf.boundaryField()[pi].coupled())
210  {
211  label size = vf.boundaryField()[pi].patch().size();
212  label start = vf.boundaryField()[pi].patch().start();
213 
214  Field<Type> pOwnVf = vf.boundaryField()[pi].patchInternalField();
215  Field<Type> pNgbVf = vf.boundaryField()[pi].patchNeighbourField();
216 
217  Field<Type>& pSf = sf.boundaryFieldRef()[pi];
218 
219  for (label i=0; i<size; ++i)
220  {
221  const tensorField& curT =
222  mesh.edgeTransformTensors()[start + i];
223 
224  const tensor& Te = curT[0];
225  const tensor& TP = curT[1];
226  const tensor& TN = curT[2];
227 
228  pSf[i] =
229  transform
230  (
231  Te.T(),
232  pLambda[i]*transform(TP, pOwnVf[i])
233  + pY[i]*transform(TN, pNgbVf[i])
234  );
235  }
236 
237 // sf.boundaryFieldRef()[pi] =
238 // pLambda*vf.boundaryField()[pi].patchInternalField()
239 // + pY*vf.boundaryField()[pi].patchNeighbourField();
240  }
241  else
242  {
243  sf.boundaryFieldRef()[pi] = vf.boundaryField()[pi];
244  }
245  }
246 
247  tlambdas.clear();
248  tys.clear();
249 
250  return tsf;
251 }
252 
253 
254 template<class Type>
257 (
259  const tmp<edgeScalarField>& tlambdas
260 )
261 {
263  {
265  << "interpolating "
266  << vf.type() << " "
267  << vf.name()
268  << " from area to edges "
269  "without explicit correction"
270  << endl;
271  }
272 
273  const edgeScalarField& lambdas = tlambdas();
274 
275  const Field<Type>& vfi = vf.internalField();
276  const scalarField& lambda = lambdas.internalField();
277 
278  const faMesh& mesh = vf.mesh();
279  const labelUList& P = mesh.owner();
280  const labelUList& N = mesh.neighbour();
281 
283  (
285  (
286  IOobject
287  (
288  "interpolate("+vf.name()+')',
289  vf.instance(),
290  vf.db()
291  ),
292  mesh,
293  vf.dimensions()
294  )
295  );
297 
298  Field<Type>& sfi = sf.primitiveFieldRef();
299 
300  for (label eI = 0; eI < P.size(); ++eI)
301  {
302  const tensorField& curT = mesh.edgeTransformTensors()[eI];
303 
304  const tensor& Te = curT[0];
305  const tensor& TP = curT[1];
306  const tensor& TN = curT[2];
307 
308  sfi[eI] =
309  transform
310  (
311  Te.T(),
312  lambda[eI]*transform(TP, vfi[P[eI]])
313  + (1 - lambda[eI])*transform(TN, vfi[N[eI]])
314  );
315  }
316 
317 
318  // Interpolate across coupled patches using given lambdas
319 
321  vfb = vf.boundaryField();
322 
323  forAll(lambdas.boundaryField(), pi)
324  {
325  const faePatchScalarField& pLambda = lambdas.boundaryField()[pi];
326 
327  if (vf.boundaryField()[pi].coupled())
328  {
329  label size = vfb[pi].patch().size();
330  label start = vfb[pi].patch().start();
331 
332  Field<Type> pOwnVf(vfb[pi].patchInternalField());
333  Field<Type> pNgbVf(vfb[pi].patchNeighbourField());
334 
335  Field<Type>& pSf = sf.boundaryFieldRef()[pi];
336 
337  for (label i=0; i<size; ++i)
338  {
339  const tensorField& curT =
340  mesh.edgeTransformTensors()[start + i];
341 
342  const tensor& Te = curT[0];
343  const tensor& TP = curT[1];
344  const tensor& TN = curT[2];
345 
346  pSf[i] =
347  transform
348  (
349  Te.T(),
350  pLambda[i]*transform(TP, pOwnVf[i])
351  + (1 - pLambda[i])*transform(TN, pNgbVf[i])
352  );
353  }
354 
355 // tsf().boundaryFieldRef()[pi] =
356 // pLambda*vf.boundaryField()[pi].patchInternalField()
357 // + (1 - pLambda)*vf.boundaryField()[pi].patchNeighbourField();
358  }
359  else
360  {
361  sf.boundaryFieldRef()[pi] = vf.boundaryField()[pi];
362  }
363  }
364 
365  tlambdas.clear();
366 
367  return tsf;
368 }
369 
370 
371 template<class Type>
374 (
376  const tmp<edgeScalarField>& tlambdas
377 )
378 {
380  {
382  << "interpolating "
383  << vf.type() << " "
384  << vf.name()
385  << " from area to edges "
386  "without explicit correction"
387  << endl;
388  }
389 
390  const edgeScalarField& lambdas = tlambdas();
391 
392  const Field<Type>& vfi = vf.internalField();
393  const scalarField& lambda = lambdas.internalField();
394 
395  const faMesh& mesh = vf.mesh();
396  const labelUList& P = mesh.owner();
397  const labelUList& N = mesh.neighbour();
398 
400  (
402  (
403  IOobject
404  (
405  "interpolate("+vf.name()+')',
406  vf.instance(),
407  vf.db()
408  ),
409  mesh,
410  vf.dimensions()
411  )
412  );
414 
415  Field<Type>& sfi = sf.primitiveFieldRef();
416 
417  for (label eI = 0; eI < P.size(); ++eI)
418  {
419  sfi[eI] = lambda[eI]*vfi[P[eI]] + (1 - lambda[eI])*vfi[N[eI]];
420  }
421 
422 
423  // Interpolate across coupled patches using given lambdas
424 
425  forAll(lambdas.boundaryField(), pi)
426  {
427  const faePatchScalarField& pLambda = lambdas.boundaryField()[pi];
428 
429  if (vf.boundaryField()[pi].coupled())
430  {
431  tsf.ref().boundaryFieldRef()[pi] =
432  pLambda*vf.boundaryField()[pi].patchInternalField()
433  + (1.0 - pLambda)*vf.boundaryField()[pi].patchNeighbourField();
434  }
435  else
436  {
437  sf.boundaryFieldRef()[pi] = vf.boundaryField()[pi];
438  }
439  }
440 
441  tlambdas.clear();
442 
443  return tsf;
444 }
445 
446 
447 template<class Type>
450 (
452 ) const
453 {
455  {
457  << "interpolating "
458  << vf.type() << " "
459  << vf.name()
460  << " from areas to edges"
461  << endl;
462  }
463 
465  interpolate(vf, weights(vf));
466 
467  if (corrected())
468  {
469  tsf.ref() += correction(vf);
470  }
471 
472  return tsf;
473 }
474 
475 
476 template<class Type>
479 (
481 ) const
482 {
484  {
486  << "interpolating "
487  << vf.type() << " "
488  << vf.name()
489  << " from area to edges "
490  << endl;
491  }
492 
494  euclidianInterpolate(vf, weights(vf));
495 
496  return tsf;
497 }
498 
499 
500 template<class Type>
503 (
505 ) const
506 {
508  interpolate(tvf());
509  tvf.clear();
510  return tinterpVf;
511 }
512 
513 
514 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::Tensor< scalar >
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:350
edgeInterpolationScheme.H
Foam::edgeInterpolationScheme::euclidianInterpolate
static tmp< GeometricField< Type, faePatchField, edgeMesh > > euclidianInterpolate(const GeometricField< Type, faPatchField, areaMesh > &, const tmp< edgeScalarField > &)
Return the euclidian edge-interpolate of the given area field.
Definition: edgeInterpolationScheme.C:374
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::tmp::clear
void clear() const noexcept
Definition: tmpI.H:287
Foam::faePatchField
faePatchField<Type> abstract base class. This class gives a fat-interface to all derived classes cove...
Definition: edgeFieldsFwd.H:49
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::correction
tmp< fvMatrix< Type > > correction(const fvMatrix< Type > &)
Foam::GeometricField::internalField
const Internal & internalField() const
Return a const-reference to the dimensioned internal field.
Definition: GeometricFieldI.H:43
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:521
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::tmp::ref
T & ref() const
Definition: tmpI.H:227
FatalIOErrorInLookup
#define FatalIOErrorInLookup(ios, lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalIOError.
Definition: error.H:478
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
edgeFields.H
Foam::IOstream::eof
bool eof() const noexcept
True if end of input seen.
Definition: IOstream.H:239
coupledFaPatchField.H
areaFields.H
lambda
dimensionedScalar lambda("lambda", dimTime/sqr(dimLength), laminarTransport)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::GeometricField::primitiveFieldRef
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field.
Definition: GeometricField.C:766
Foam::edgeInterpolationScheme::interpolate
static tmp< GeometricField< Type, faePatchField, edgeMesh > > interpolate(const GeometricField< Type, faPatchField, areaMesh > &, const tmp< edgeScalarField > &, const tmp< edgeScalarField > &)
Return the face-interpolate of the given cell field.
Definition: edgeInterpolationScheme.C:138
Foam::GeometricField::Boundary
The boundary fields.
Definition: GeometricField.H:115
Foam::constant::mathematical::pi
constexpr scalar pi(M_PI)
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::GeometricField::boundaryFieldRef
Boundary & boundaryFieldRef(const bool updateAccessTime=true)
Return a reference to the boundary field.
Definition: GeometricField.C:783
Foam::UList< label >
Foam::Tensor::T
Tensor< Cmpt > T() const
Return non-Hermitian transpose.
Definition: TensorI.H:504
faPatchFields.H
Foam::faMesh
Finite area mesh. Used for 2-D non-Euclidian finite area method.
Definition: faMesh.H:82
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
N
const Vector< label > N(dict.get< Vector< label >>("N"))
transform.H
3D tensor transformation operations.
Foam::GeometricField< scalar, faePatchField, edgeMesh >
Foam::edgeInterpolationScheme::New
static tmp< edgeInterpolationScheme< Type > > New(const faMesh &mesh, Istream &schemeData)
Return new tmp interpolation scheme.
Definition: edgeInterpolationScheme.C:41
Foam::fac::interpolate
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.
Foam::edgeInterpolationScheme::~edgeInterpolationScheme
virtual ~edgeInterpolationScheme()
Definition: edgeInterpolationScheme.C:129
Foam::GeometricField::boundaryField
const Boundary & boundaryField() const
Return const-reference to the boundary field.
Definition: GeometricFieldI.H:62
y
scalar y
Definition: LISASMDCalcMethod1.H:14