processorFvPatchField.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-2020 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 "processorFvPatchField.H"
27 #include "processorFvPatch.H"
28 #include "demandDrivenData.H"
29 #include "transformField.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
33 template<class Type>
35 (
36  const fvPatch& p,
38 )
39 :
41  procPatch_(refCast<const processorFvPatch>(p)),
42  sendBuf_(0),
43  receiveBuf_(0),
44  outstandingSendRequest_(-1),
45  outstandingRecvRequest_(-1),
46  scalarSendBuf_(0),
47  scalarReceiveBuf_(0)
48 {}
49 
50 
51 template<class Type>
53 (
54  const fvPatch& p,
56  const Field<Type>& f
57 )
58 :
60  procPatch_(refCast<const processorFvPatch>(p)),
61  sendBuf_(0),
62  receiveBuf_(0),
63  outstandingSendRequest_(-1),
64  outstandingRecvRequest_(-1),
65  scalarSendBuf_(0),
66  scalarReceiveBuf_(0)
67 {}
68 
69 
70 template<class Type>
72 (
73  const fvPatch& p,
75  const dictionary& dict
76 )
77 :
78  coupledFvPatchField<Type>(p, iF, dict, dict.found("value")),
79  procPatch_(refCast<const processorFvPatch>(p)),
80  sendBuf_(0),
81  receiveBuf_(0),
82  outstandingSendRequest_(-1),
83  outstandingRecvRequest_(-1),
84  scalarSendBuf_(0),
85  scalarReceiveBuf_(0)
86 {
87  if (!isA<processorFvPatch>(p))
88  {
90  (
91  dict
92  ) << "\n patch type '" << p.type()
93  << "' not constraint type '" << typeName << "'"
94  << "\n for patch " << p.name()
95  << " of field " << this->internalField().name()
96  << " in file " << this->internalField().objectPath()
97  << exit(FatalIOError);
98  }
99 
100  // If the value is not supplied set to the internal field
101  if (!dict.found("value"))
102  {
103  fvPatchField<Type>::operator=(this->patchInternalField());
104  }
105 }
106 
107 
108 template<class Type>
110 (
111  const processorFvPatchField<Type>& ptf,
112  const fvPatch& p,
114  const fvPatchFieldMapper& mapper
115 )
116 :
117  coupledFvPatchField<Type>(ptf, p, iF, mapper),
118  procPatch_(refCast<const processorFvPatch>(p)),
119  sendBuf_(0),
120  receiveBuf_(0),
121  outstandingSendRequest_(-1),
122  outstandingRecvRequest_(-1),
123  scalarSendBuf_(0),
124  scalarReceiveBuf_(0)
125 {
126  if (!isA<processorFvPatch>(this->patch()))
127  {
129  << "' not constraint type '" << typeName << "'"
130  << "\n for patch " << p.name()
131  << " of field " << this->internalField().name()
132  << " in file " << this->internalField().objectPath()
133  << exit(FatalIOError);
134  }
135  if (debug && !ptf.ready())
136  {
138  << "On patch " << procPatch_.name() << " outstanding request."
139  << abort(FatalError);
140  }
141 }
142 
143 
144 template<class Type>
146 (
147  const processorFvPatchField<Type>& ptf
148 )
149 :
152  procPatch_(refCast<const processorFvPatch>(ptf.patch())),
153  sendBuf_(move(ptf.sendBuf_)),
154  receiveBuf_(move(ptf.receiveBuf_)),
155  outstandingSendRequest_(-1),
156  outstandingRecvRequest_(-1),
157  scalarSendBuf_(move(ptf.scalarSendBuf_)),
158  scalarReceiveBuf_(move(ptf.scalarReceiveBuf_))
159 {
160  if (debug && !ptf.ready())
161  {
163  << "On patch " << procPatch_.name() << " outstanding request."
164  << abort(FatalError);
165  }
166 }
167 
168 
169 template<class Type>
171 (
172  const processorFvPatchField<Type>& ptf,
174 )
175 :
176  coupledFvPatchField<Type>(ptf, iF),
177  procPatch_(refCast<const processorFvPatch>(ptf.patch())),
178  sendBuf_(0),
179  receiveBuf_(0),
180  outstandingSendRequest_(-1),
181  outstandingRecvRequest_(-1),
182  scalarSendBuf_(0),
183  scalarReceiveBuf_(0)
184 {
185  if (debug && !ptf.ready())
186  {
188  << "On patch " << procPatch_.name() << " outstanding request."
189  << abort(FatalError);
190  }
191 }
192 
193 
194 // * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
195 
196 template<class Type>
198 {}
199 
200 
201 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
202 
203 template<class Type>
206 {
207  if (debug && !this->ready())
208  {
210  << "On patch " << procPatch_.name()
211  << " outstanding request."
212  << abort(FatalError);
213  }
214  return *this;
215 }
216 
217 
218 template<class Type>
220 (
221  const Pstream::commsTypes commsType
222 )
223 {
224  if (Pstream::parRun())
225  {
226  this->patchInternalField(sendBuf_);
227 
228  if
229  (
230  commsType == Pstream::commsTypes::nonBlocking
231  && !Pstream::floatTransfer
232  )
233  {
234  // Fast path. Receive into *this
235  this->setSize(sendBuf_.size());
236  outstandingRecvRequest_ = UPstream::nRequests();
238  (
239  Pstream::commsTypes::nonBlocking,
240  procPatch_.neighbProcNo(),
241  reinterpret_cast<char*>(this->begin()),
242  this->byteSize(),
243  procPatch_.tag(),
244  procPatch_.comm()
245  );
246 
247  outstandingSendRequest_ = UPstream::nRequests();
249  (
250  Pstream::commsTypes::nonBlocking,
251  procPatch_.neighbProcNo(),
252  reinterpret_cast<const char*>(sendBuf_.begin()),
253  this->byteSize(),
254  procPatch_.tag(),
255  procPatch_.comm()
256  );
257  }
258  else
259  {
260  procPatch_.compressedSend(commsType, sendBuf_);
261  }
262  }
263 }
264 
265 
266 template<class Type>
268 (
269  const Pstream::commsTypes commsType
270 )
271 {
272  if (Pstream::parRun())
273  {
274  if
275  (
276  commsType == Pstream::commsTypes::nonBlocking
277  && !Pstream::floatTransfer
278  )
279  {
280  // Fast path. Received into *this
281 
282  if
283  (
284  outstandingRecvRequest_ >= 0
285  && outstandingRecvRequest_ < Pstream::nRequests()
286  )
287  {
288  UPstream::waitRequest(outstandingRecvRequest_);
289  }
290  outstandingSendRequest_ = -1;
291  outstandingRecvRequest_ = -1;
292  }
293  else
294  {
295  procPatch_.compressedReceive<Type>(commsType, *this);
296  }
297 
298  procPatch_.transform().transform(*this, *this);
299  }
300 }
301 
302 
303 template<class Type>
306 (
307  const scalarField& deltaCoeffs
308 ) const
309 {
310  return deltaCoeffs*(*this - this->patchInternalField());
311 }
312 
313 
314 template<class Type>
316 (
317  scalarField&,
318  const scalarField& psiInternal,
319  const scalarField&,
320  const direction,
321  const Pstream::commsTypes commsType
322 ) const
323 {
324  this->patch().patchInternalField(psiInternal, scalarSendBuf_);
325 
326  if
327  (
328  commsType == Pstream::commsTypes::nonBlocking
329  && !Pstream::floatTransfer
330  )
331  {
332  // Fast path.
333  if (debug && !this->ready())
334  {
336  << "On patch " << procPatch_.name()
337  << " outstanding request."
338  << abort(FatalError);
339  }
340 
341 
342  scalarReceiveBuf_.setSize(scalarSendBuf_.size());
343  outstandingRecvRequest_ = UPstream::nRequests();
345  (
346  Pstream::commsTypes::nonBlocking,
347  procPatch_.neighbProcNo(),
348  reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
349  scalarReceiveBuf_.byteSize(),
350  procPatch_.tag(),
351  procPatch_.comm()
352  );
353 
354  outstandingSendRequest_ = UPstream::nRequests();
356  (
357  Pstream::commsTypes::nonBlocking,
358  procPatch_.neighbProcNo(),
359  reinterpret_cast<const char*>(scalarSendBuf_.begin()),
360  scalarSendBuf_.byteSize(),
361  procPatch_.tag(),
362  procPatch_.comm()
363  );
364  }
365  else
366  {
367  procPatch_.compressedSend(commsType, scalarSendBuf_);
368  }
369 
370  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
371 }
372 
373 
374 template<class Type>
376 (
377  scalarField& result,
378  const scalarField&,
379  const scalarField& coeffs,
380  const direction cmpt,
381  const Pstream::commsTypes commsType
382 ) const
383 {
384  if (this->updatedMatrix())
385  {
386  return;
387  }
388 
389  const labelUList& faceCells = this->patch().faceCells();
390 
391  if
392  (
393  commsType == Pstream::commsTypes::nonBlocking
394  && !Pstream::floatTransfer
395  )
396  {
397  // Fast path.
398  if
399  (
400  outstandingRecvRequest_ >= 0
401  && outstandingRecvRequest_ < Pstream::nRequests()
402  )
403  {
404  UPstream::waitRequest(outstandingRecvRequest_);
405  }
406  // Recv finished so assume sending finished as well.
407  outstandingSendRequest_ = -1;
408  outstandingRecvRequest_ = -1;
409 
410  // Consume straight from scalarReceiveBuf_
411 
412  // Transform according to the transformation tensor
413  transformCoupleField(scalarReceiveBuf_, cmpt);
414 
415  // Multiply the field by coefficients and add into the result
416  forAll(faceCells, elemI)
417  {
418  result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI];
419  }
420  }
421  else
422  {
423  scalarField pnf
424  (
425  procPatch_.compressedReceive<scalar>(commsType, this->size())()
426  );
427 
428  // Transform according to the transformation tensor
429  transformCoupleField(pnf, cmpt);
430 
431  // Multiply the field by coefficients and add into the result
432  forAll(faceCells, elemI)
433  {
434  result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
435  }
436  }
437 
438  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
439 }
440 
441 
442 template<class Type>
444 (
445  Field<Type>&,
446  const Field<Type>& psiInternal,
447  const scalarField&,
448  const Pstream::commsTypes commsType
449 ) const
450 {
451  this->patch().patchInternalField(psiInternal, sendBuf_);
452 
453  if
454  (
455  commsType == Pstream::commsTypes::nonBlocking
456  && !Pstream::floatTransfer
457  )
458  {
459  // Fast path.
460  if (debug && !this->ready())
461  {
463  << "On patch " << procPatch_.name()
464  << " outstanding request."
465  << abort(FatalError);
466  }
467 
468 
469  receiveBuf_.setSize(sendBuf_.size());
470  outstandingRecvRequest_ = UPstream::nRequests();
472  (
473  Pstream::commsTypes::nonBlocking,
474  procPatch_.neighbProcNo(),
475  reinterpret_cast<char*>(receiveBuf_.begin()),
476  receiveBuf_.byteSize(),
477  procPatch_.tag(),
478  procPatch_.comm()
479  );
480 
481  outstandingSendRequest_ = UPstream::nRequests();
483  (
484  Pstream::commsTypes::nonBlocking,
485  procPatch_.neighbProcNo(),
486  reinterpret_cast<const char*>(sendBuf_.begin()),
487  sendBuf_.byteSize(),
488  procPatch_.tag(),
489  procPatch_.comm()
490  );
491  }
492  else
493  {
494  procPatch_.compressedSend(commsType, sendBuf_);
495  }
496 
497  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
498 }
499 
500 
501 template<class Type>
503 (
504  Field<Type>& result,
505  const Field<Type>&,
506  const scalarField& coeffs,
507  const Pstream::commsTypes commsType
508 ) const
509 {
510  if (this->updatedMatrix())
511  {
512  return;
513  }
514 
515  const labelUList& faceCells = this->patch().faceCells();
516 
517  if
518  (
519  commsType == Pstream::commsTypes::nonBlocking
520  && !Pstream::floatTransfer
521  )
522  {
523  // Fast path.
524  if
525  (
526  outstandingRecvRequest_ >= 0
527  && outstandingRecvRequest_ < Pstream::nRequests()
528  )
529  {
530  UPstream::waitRequest(outstandingRecvRequest_);
531  }
532  // Recv finished so assume sending finished as well.
533  outstandingSendRequest_ = -1;
534  outstandingRecvRequest_ = -1;
535 
536  // Consume straight from receiveBuf_
537 
538  // Transform according to the transformation tensor
539  transformCoupleField(receiveBuf_);
540 
541  // Multiply the field by coefficients and add into the result
542  forAll(faceCells, elemI)
543  {
544  result[faceCells[elemI]] -= coeffs[elemI]*receiveBuf_[elemI];
545  }
546  }
547  else
548  {
549  Field<Type> pnf
550  (
551  procPatch_.compressedReceive<Type>(commsType, this->size())()
552  );
553 
554  // Transform according to the transformation tensor
555  transformCoupleField(pnf);
556 
557  // Multiply the field by coefficients and add into the result
558  forAll(faceCells, elemI)
559  {
560  result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
561  }
562  }
563 
564  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
565 }
566 
567 
568 template<class Type>
570 {
571  if
572  (
573  outstandingSendRequest_ >= 0
574  && outstandingSendRequest_ < Pstream::nRequests()
575  )
576  {
577  bool finished = UPstream::finishedRequest(outstandingSendRequest_);
578  if (!finished)
579  {
580  return false;
581  }
582  }
583  outstandingSendRequest_ = -1;
584 
585  if
586  (
587  outstandingRecvRequest_ >= 0
588  && outstandingRecvRequest_ < Pstream::nRequests()
589  )
590  {
591  bool finished = UPstream::finishedRequest(outstandingRecvRequest_);
592  if (!finished)
593  {
594  return false;
595  }
596  }
597  outstandingRecvRequest_ = -1;
598 
599  return true;
600 }
601 
602 
603 // ************************************************************************* //
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
bool updatedMatrix() const
Whether matrix has been updated.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
error FatalError
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:158
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
commsTypes
Types of communications.
Definition: UPstream.H:64
uint8_t direction
Definition: direction.H:45
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:61
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: fvPatchField.H:66
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
virtual void initInterfaceMatrixUpdate(scalarField &result, const scalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Initialise neighbour matrix update.
points setSize(newPointi)
Spatial transformation functions for primitive fields.
Abstract base class for processor coupled interfaces.
Pre-declare SubField and related Field type.
Definition: Field.H:56
Foam::fvPatchFieldMapper.
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
virtual bool ready() const
Is all data available.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Abstract base class for coupled patches.
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
const fvPatch & patch() const
Return patch.
Definition: fvPatchField.H:325
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
labelList f(nPoints)
Template functions to aid in the implementation of demand driven data.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:331
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
virtual void updateInterfaceMatrix(scalarField &result, const scalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Update result field based on interface functionality.
This boundary condition enables processor communication across patches.
volScalarField & p
A class for managing temporary objects.
Definition: PtrList.H:53
virtual bool ready() const
Is all data available.
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour field given internal field.
virtual tmp< Field< Type > > snGrad() const
Return patch-normal gradient.
processorFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
IOerror FatalIOError