Sampled.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) 2018 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "fvMesh.H"
29 #include "volFields.H"
30 #include "interpolationCell.H"
31 
32 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33 
34 template<class Type>
36 (
37  const dictionary& dict,
38  const bool mandatory
39 )
40 {
41  if (mandatory)
42  {
43  return dict.get<Type>("average");
44  }
45 
46  return Zero;
47 }
48 
49 
50 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
51 
52 template<class Type>
54 (
55  const polyPatch& pp,
56  const word& type,
57  const word& entryName,
58  const dictionary& dict,
59  const bool faceValues
60 )
61 :
62  PatchFunction1<Type>(pp, entryName, dict, faceValues),
63  mappedPatchBase(pp, dict),
64  fieldName_(dict.get<word>("field")),
65  setAverage_(dict.lookupOrDefault("setAverage", false)),
66  average_(getAverage(dict, setAverage_)),
67  interpolationScheme_(interpolationCell<Type>::typeName)
68 {
69  if (this->mode() == mappedPatchBase::NEARESTCELL)
70  {
71  dict.readEntry("interpolationScheme", interpolationScheme_);
72  }
73 }
74 
75 
76 template<class Type>
78 (
79  const Sampled<Type>& ut
80 )
81 :
83  mappedPatchBase(ut),
84  fieldName_(ut.fieldName_),
85  setAverage_(ut.setAverage_),
86  average_(ut.average_),
87  interpolationScheme_(ut.interpolationScheme_)
88 {}
89 
90 
91 template<class Type>
93 (
94  const Sampled<Type>& ut,
95  const polyPatch& pp
96 )
97 :
98  PatchFunction1<Type>(ut, pp),
99  mappedPatchBase(pp, ut),
100  fieldName_(ut.fieldName_),
101  setAverage_(ut.setAverage_),
102  average_(ut.average_),
103  interpolationScheme_(ut.interpolationScheme_)
104 {}
105 
106 
107 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
108 
109 template<class Type>
112 {
114 
115  if (this->sameRegion())
116  {
117  const polyMesh& thisMesh =
118  this->mappedPatchBase::patch_.boundaryMesh().mesh();
119  return thisMesh.template lookupObject<fieldType>(fieldName_);
120  }
121  else
122  {
123  const fvMesh& nbrMesh = refCast<const fvMesh>(this->sampleMesh());
124  return nbrMesh.template lookupObject<fieldType>(fieldName_);
125  }
126 }
127 
128 
129 template<class Type>
131 {
133 
134  if (this->sameRegion())
135  {
136  const polyMesh& thisMesh =
137  this->mappedPatchBase::patch_.boundaryMesh().mesh();
138  return thisMesh.template foundObject<fieldType>(fieldName_);
139  }
140  else
141  {
142  const fvMesh& nbrMesh = refCast<const fvMesh>(this->sampleMesh());
143  return nbrMesh.template foundObject<fieldType>(fieldName_);
144  }
145 }
146 
147 
148 template<class Type>
151 (
152  const scalar x
153 ) const
154 {
156 
157  // Since we're inside initEvaluate/evaluate there might be processor
158  // comms underway. Change the tag we use.
159  int oldTag = UPstream::msgType();
160  UPstream::msgType() = oldTag + 1;
161 
162  const fvMesh& thisMesh = refCast<const fvMesh>
163  (
164  this->mappedPatchBase::patch_.boundaryMesh().mesh()
165  );
166  const fvMesh& nbrMesh = refCast<const fvMesh>(this->sampleMesh());
167 
168 
169  // Result of obtaining remote values
170  auto tnewValues = tmp<Field<Type>>::New();
171  auto& newValues = tnewValues.ref();
172 
173  if (!haveSampleField())
174  {
175  // Restore tag
176  UPstream::msgType() = oldTag;
177  newValues.setSize(this->mappedPatchBase::patch_.size());
178  newValues = Zero;
179  return this->transform(tnewValues);
180  }
181 
182  switch (this->mode())
183  {
184  case mappedPatchBase::NEARESTCELL:
185  {
186  const mapDistribute& distMap = this->map();
187 
188  if (interpolationScheme_ != interpolationCell<Type>::typeName)
189  {
190  // Send back sample points to the processor that holds the cell
191  vectorField samples(this->samplePoints());
192  distMap.reverseDistribute
193  (
194  (
195  this->sameRegion()
196  ? thisMesh.nCells()
197  : nbrMesh.nCells()
198  ),
199  point::max,
200  samples
201  );
202 
203  auto interpolator =
205  (
206  interpolationScheme_,
207  sampleField()
208  );
209 
210  const auto& interp = *interpolator;
211 
212  newValues.setSize(samples.size(), pTraits<Type>::max);
213  forAll(samples, celli)
214  {
215  if (samples[celli] != point::max)
216  {
217  newValues[celli] = interp.interpolate
218  (
219  samples[celli],
220  celli
221  );
222  }
223  }
224  }
225  else
226  {
227  newValues = sampleField();
228  }
229  distMap.distribute(newValues);
230 
231  break;
232  }
233  case mappedPatchBase::NEARESTPATCHFACE:
234  case mappedPatchBase::NEARESTPATCHFACEAMI:
235  {
236  const label nbrPatchID =
237  nbrMesh.boundaryMesh().findPatchID(this->samplePatch());
238 
239  if (nbrPatchID < 0)
240  {
242  << "Unable to find sample patch " << this->samplePatch()
243  << " in region " << this->sampleRegion()
244  << " for patch " << this->mappedPatchBase::patch_.name() << nl
245  << abort(FatalError);
246  }
247 
248  const fieldType& nbrField = sampleField();
249 
250  newValues = nbrField.boundaryField()[nbrPatchID];
251  this->distribute(newValues);
252 
253  break;
254  }
255  case mappedPatchBase::NEARESTFACE:
256  {
257  Field<Type> allValues(nbrMesh.nFaces(), Zero);
258 
259  const fieldType& nbrField = sampleField();
260 
261  for (const fvPatchField<Type>& pf : nbrField.boundaryField())
262  {
263  label faceStart = pf.patch().start();
264 
265  forAll(pf, facei)
266  {
267  allValues[faceStart++] = pf[facei];
268  }
269  }
270 
271  this->distribute(allValues);
272  newValues.transfer(allValues);
273 
274  break;
275  }
276  default:
277  {
279  << "Unknown sampling mode: " << this->mode() << nl
280  << abort(FatalError);
281  }
282  }
283 
284  // Enforce average. Either by scaling (if scaling factor > 0.5) or by
285  // offsetting.
286  if (setAverage_ && returnReduce(newValues.size(), sumOp<label>()))
287  {
288  Type averagePsi;
289  if (this->faceValues_)
290  {
291  const scalarField magSf
292  (
293  mag(this->mappedPatchBase::patch_.faceAreas())
294  );
295  averagePsi = gSum(magSf*newValues)/gSum(magSf);
296  }
297  else
298  {
299  averagePsi = gAverage(newValues);
300  }
301 
302  if (mag(averagePsi)/mag(average_) > 0.5)
303  {
304  newValues *= mag(average_)/mag(averagePsi);
305  }
306  else
307  {
308  newValues += (average_ - averagePsi);
309  }
310  }
311 
312  // Restore tag
313  UPstream::msgType() = oldTag;
314 
315  return this->transform(tnewValues);
316 }
317 
318 
319 template<class Type>
322 (
323  const scalar x1,
324  const scalar x2
325 ) const
326 {
328  return tmp<Field<Type>>(nullptr);
329 }
330 
331 
332 template<class Type>
334 (
335  Ostream& os
336 ) const
337 {
339 
340  os.writeEntry(this->name(), type());
341 
343 
344  os.writeEntry("field", fieldName_);
345  if (setAverage_)
346  {
347  os.writeEntry("setAverage", "true");
348  os.writeEntry("average", average_);
349  }
350 
351  os.writeEntry("interpolationScheme", interpolationScheme_);
352 }
353 
354 
355 // ************************************************************************* //
Foam::fvPatchField
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: volSurfaceMapping.H:50
volFields.H
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::PatchFunction1Types::Sampled::setAverage_
const bool setAverage_
If true adjust the mapped field to maintain average value average_.
Definition: Sampled.H:161
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:59
Foam::Zero
static constexpr const zero Zero
Global zero.
Definition: zero.H:128
Foam::gAverage
Type gAverage(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:604
Foam::PatchFunction1Types::Sampled::sampleField
const GeometricField< Type, fvPatchField, volMesh > & sampleField() const
Field to sample. Either on my or nbr mesh.
Definition: Sampled.C:111
Foam::primitiveMesh::nFaces
label nFaces() const
Number of mesh faces.
Definition: primitiveMeshI.H:90
interpolationCell.H
Foam::PatchFunction1Types::Sampled::Sampled
Sampled(const polyPatch &pp, const word &type, const word &entryName, const dictionary &dict, const bool faceValues=true)
Construct from entry name and dictionary.
Definition: Sampled.C:54
writeData
const bool writeData(pdfDictionary.get< bool >("writeData"))
Foam::PatchFunction1Types::Sampled::interpolationScheme_
word interpolationScheme_
Interpolation scheme to use for nearestcell mode.
Definition: Sampled.H:168
Foam::polyMesh::boundaryMesh
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
Definition: polyMesh.H:435
Foam::gSum
Type gSum(const FieldField< Field, Type > &f)
Definition: FieldFieldFunctions.C:594
Foam::mappedPatchBase
Determines a mapping between patch face centres and mesh cell or face centres and processors they're ...
Definition: mappedPatchBase.H:105
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::PatchFunction1Types::Sampled::fieldName_
word fieldName_
Name of the field.
Definition: Sampled.H:158
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::interpolationCell
Uses the cell value for any point in the cell.
Definition: interpolationCell.H:50
Foam::mode
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Definition: MSwindows.C:564
Foam::PatchFunction1Types::Sampled::integrate
virtual tmp< Field< Type > > integrate(const scalar x1, const scalar x2) const
Integrate between two values.
Definition: Sampled.C:322
NotImplemented
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:419
Foam::PatchFunction1Types::Sampled::haveSampleField
bool haveSampleField() const
Field to sample. Either on my or nbr mesh.
Definition: Sampled.C:130
Foam::primitiveMesh::nCells
label nCells() const
Number of mesh cells.
Definition: primitiveMeshI.H:96
Foam::label
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:62
Foam::Field< vector >
Foam::polyPatch
A patch is a list of labels that address the faces in the global face list.
Definition: polyPatch.H:66
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:163
Foam::PatchFunction1Types::Sampled::writeData
virtual void writeData(Ostream &os) const
Write in dictionary format.
Definition: Sampled.C:334
samples
scalarField samples(nIntervals, Zero)
Foam::polyBoundaryMesh::mesh
const polyMesh & mesh() const
Return the mesh reference.
Definition: polyBoundaryMesh.H:144
Foam::polyBoundaryMesh::findPatchID
label findPatchID(const word &patchName, const bool allowNotFound=true) const
Find patch index given a name, return -1 if not found.
Definition: polyBoundaryMesh.C:766
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::mapDistribute::distribute
void distribute(List< T > &fld, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Distribute data using default commsType.
Definition: mapDistributeTemplates.C:152
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:121
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::PatchFunction1
Top level data entry class for use in dictionaries. Provides a mechanism to specify a variable as a c...
Definition: PatchFunction1.H:63
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:84
fvMesh.H
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:137
Foam::New
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
Global function forwards to reuseTmpDimensionedField::New.
Definition: DimensionedFieldReuseFunctions.H:105
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::pTraits
Traits class for primitives.
Definition: pTraits.H:52
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::PatchFunction1Types::Sampled::value
virtual tmp< Field< Type > > value(const scalar x) const
Return sampled value.
Definition: Sampled.C:151
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:219
Foam::vtk::write
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Definition: foamVtkOutputTemplates.C:35
Foam::roots::type
type
Types of root.
Definition: Roots.H:54
Foam::mapDistribute::reverseDistribute
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
Definition: mapDistributeTemplates.C:182
Foam::boundaryMesh
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
Definition: boundaryMesh.H:61
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::GeometricField< Type, Foam::fvPatchField, Foam::volMesh >
Foam::PatchFunction1Types::Sampled
PatchFunction1 to sample an existing field.
Definition: Sampled.H:142
Foam::PatchFunction1Types::Sampled::average_
const Type average_
Definition: Sampled.H:165