processorFvPatchField.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-2017 OpenFOAM Foundation
9  Copyright (C) 2019-2020 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 
29 #include "processorFvPatchField.H"
30 #include "processorFvPatch.H"
31 #include "demandDrivenData.H"
32 #include "transformField.H"
33 
34 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
35 
36 template<class Type>
38 (
39  const fvPatch& p,
41 )
42 :
44  procPatch_(refCast<const processorFvPatch>(p)),
45  sendBuf_(0),
46  receiveBuf_(0),
47  outstandingSendRequest_(-1),
48  outstandingRecvRequest_(-1),
49  scalarSendBuf_(0),
50  scalarReceiveBuf_(0)
51 {}
52 
53 
54 template<class Type>
56 (
57  const fvPatch& p,
59  const Field<Type>& f
60 )
61 :
63  procPatch_(refCast<const processorFvPatch>(p)),
64  sendBuf_(0),
65  receiveBuf_(0),
66  outstandingSendRequest_(-1),
67  outstandingRecvRequest_(-1),
68  scalarSendBuf_(0),
69  scalarReceiveBuf_(0)
70 {}
71 
72 
73 template<class Type>
75 (
76  const fvPatch& p,
78  const dictionary& dict
79 )
80 :
81  coupledFvPatchField<Type>(p, iF, dict, dict.found("value")),
82  procPatch_(refCast<const processorFvPatch>(p, dict)),
83  sendBuf_(0),
84  receiveBuf_(0),
85  outstandingSendRequest_(-1),
86  outstandingRecvRequest_(-1),
87  scalarSendBuf_(0),
88  scalarReceiveBuf_(0)
89 {
90  if (!isA<processorFvPatch>(p))
91  {
93  << "\n patch type '" << p.type()
94  << "' not constraint type '" << typeName << "'"
95  << "\n for patch " << p.name()
96  << " of field " << this->internalField().name()
97  << " in file " << this->internalField().objectPath()
98  << exit(FatalIOError);
99  }
100 
101  // If the value is not supplied set to the internal field
102  if (!dict.found("value"))
103  {
104  fvPatchField<Type>::operator=(this->patchInternalField());
105  }
106 }
107 
108 
109 template<class Type>
111 (
112  const processorFvPatchField<Type>& ptf,
113  const fvPatch& p,
115  const fvPatchFieldMapper& mapper
116 )
117 :
118  coupledFvPatchField<Type>(ptf, p, iF, mapper),
119  procPatch_(refCast<const processorFvPatch>(p)),
120  sendBuf_(0),
121  receiveBuf_(0),
122  outstandingSendRequest_(-1),
123  outstandingRecvRequest_(-1),
124  scalarSendBuf_(0),
125  scalarReceiveBuf_(0)
126 {
127  if (!isA<processorFvPatch>(this->patch()))
128  {
130  << "' not constraint type '" << typeName << "'"
131  << "\n for patch " << p.name()
132  << " of field " << this->internalField().name()
133  << " in file " << this->internalField().objectPath()
134  << exit(FatalIOError);
135  }
136  if (debug && !ptf.ready())
137  {
139  << "On patch " << procPatch_.name() << " outstanding request."
140  << abort(FatalError);
141  }
142 }
143 
144 
145 template<class Type>
147 (
148  const processorFvPatchField<Type>& ptf
149 )
150 :
153  procPatch_(refCast<const processorFvPatch>(ptf.patch())),
154  sendBuf_(std::move(ptf.sendBuf_)),
155  receiveBuf_(std::move(ptf.receiveBuf_)),
156  outstandingSendRequest_(-1),
157  outstandingRecvRequest_(-1),
158  scalarSendBuf_(std::move(ptf.scalarSendBuf_)),
159  scalarReceiveBuf_(std::move(ptf.scalarReceiveBuf_))
160 {
161  if (debug && !ptf.ready())
162  {
164  << "On patch " << procPatch_.name() << " outstanding request."
165  << abort(FatalError);
166  }
167 }
168 
169 
170 template<class Type>
172 (
173  const processorFvPatchField<Type>& ptf,
175 )
176 :
177  coupledFvPatchField<Type>(ptf, iF),
178  procPatch_(refCast<const processorFvPatch>(ptf.patch())),
179  sendBuf_(0),
180  receiveBuf_(0),
181  outstandingSendRequest_(-1),
182  outstandingRecvRequest_(-1),
183  scalarSendBuf_(0),
184  scalarReceiveBuf_(0)
185 {
186  if (debug && !ptf.ready())
187  {
189  << "On patch " << procPatch_.name() << " outstanding request."
190  << abort(FatalError);
191  }
192 }
193 
194 
195 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
196 
197 template<class Type>
200 {
201  if (debug && !this->ready())
202  {
204  << "On patch " << procPatch_.name()
205  << " outstanding request."
206  << abort(FatalError);
207  }
208  return *this;
209 }
210 
211 
212 template<class Type>
214 (
215  const Pstream::commsTypes commsType
216 )
217 {
218  if (Pstream::parRun())
219  {
220  this->patchInternalField(sendBuf_);
221 
222  if
223  (
224  commsType == Pstream::commsTypes::nonBlocking
225  && !Pstream::floatTransfer
226  )
227  {
228  // Fast path. Receive into *this
229  this->setSize(sendBuf_.size());
230  outstandingRecvRequest_ = UPstream::nRequests();
232  (
233  Pstream::commsTypes::nonBlocking,
234  procPatch_.neighbProcNo(),
235  reinterpret_cast<char*>(this->data()),
236  this->byteSize(),
237  procPatch_.tag(),
238  procPatch_.comm()
239  );
240 
241  outstandingSendRequest_ = UPstream::nRequests();
243  (
244  Pstream::commsTypes::nonBlocking,
245  procPatch_.neighbProcNo(),
246  reinterpret_cast<const char*>(sendBuf_.cdata()),
247  sendBuf_.byteSize(),
248  procPatch_.tag(),
249  procPatch_.comm()
250  );
251  }
252  else
253  {
254  procPatch_.compressedSend(commsType, sendBuf_);
255  }
256  }
257 }
258 
259 
260 template<class Type>
262 (
263  const Pstream::commsTypes commsType
264 )
265 {
266  if (Pstream::parRun())
267  {
268  if
269  (
270  commsType == Pstream::commsTypes::nonBlocking
271  && !Pstream::floatTransfer
272  )
273  {
274  // Fast path. Received into *this
275 
276  if
277  (
278  outstandingRecvRequest_ >= 0
279  && outstandingRecvRequest_ < Pstream::nRequests()
280  )
281  {
282  UPstream::waitRequest(outstandingRecvRequest_);
283  }
284  outstandingSendRequest_ = -1;
285  outstandingRecvRequest_ = -1;
286  }
287  else
288  {
289  procPatch_.compressedReceive<Type>(commsType, *this);
290  }
291 
292  if (doTransform())
293  {
294  transform(*this, procPatch_.forwardT(), *this);
295  }
296  }
297 }
298 
299 
300 template<class Type>
303 (
304  const scalarField& deltaCoeffs
305 ) const
306 {
307  return deltaCoeffs*(*this - this->patchInternalField());
308 }
309 
310 
311 template<class Type>
313 (
315  const bool add,
316  const solveScalarField& psiInternal,
317  const scalarField&,
318  const direction,
319  const Pstream::commsTypes commsType
320 ) const
321 {
322  this->patch().patchInternalField(psiInternal, scalarSendBuf_);
323 
324  if
325  (
326  commsType == Pstream::commsTypes::nonBlocking
327  && !Pstream::floatTransfer
328  )
329  {
330  // Fast path.
331  if (debug && !this->ready())
332  {
334  << "On patch " << procPatch_.name()
335  << " outstanding request."
336  << abort(FatalError);
337  }
338 
339 
340  scalarReceiveBuf_.setSize(scalarSendBuf_.size());
341  outstandingRecvRequest_ = UPstream::nRequests();
343  (
344  Pstream::commsTypes::nonBlocking,
345  procPatch_.neighbProcNo(),
346  reinterpret_cast<char*>(scalarReceiveBuf_.data()),
347  scalarReceiveBuf_.byteSize(),
348  procPatch_.tag(),
349  procPatch_.comm()
350  );
351 
352  outstandingSendRequest_ = UPstream::nRequests();
354  (
355  Pstream::commsTypes::nonBlocking,
356  procPatch_.neighbProcNo(),
357  reinterpret_cast<const char*>(scalarSendBuf_.cdata()),
358  scalarSendBuf_.byteSize(),
359  procPatch_.tag(),
360  procPatch_.comm()
361  );
362  }
363  else
364  {
365  procPatch_.compressedSend(commsType, scalarSendBuf_);
366  }
367 
368  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
369 }
370 
371 
372 template<class Type>
374 (
375  solveScalarField& result,
376  const bool add,
377  const solveScalarField&,
378  const scalarField& coeffs,
379  const direction cmpt,
380  const Pstream::commsTypes commsType
381 ) const
382 {
383  if (this->updatedMatrix())
384  {
385  return;
386  }
387 
388  if
389  (
390  commsType == Pstream::commsTypes::nonBlocking
391  && !Pstream::floatTransfer
392  )
393  {
394  // Fast path.
395  if
396  (
397  outstandingRecvRequest_ >= 0
398  && outstandingRecvRequest_ < Pstream::nRequests()
399  )
400  {
401  UPstream::waitRequest(outstandingRecvRequest_);
402  }
403  // Recv finished so assume sending finished as well.
404  outstandingSendRequest_ = -1;
405  outstandingRecvRequest_ = -1;
406  // Consume straight from scalarReceiveBuf_
407 
408  if (!std::is_arithmetic<Type>::value)
409  {
410  // Transform non-scalar data according to the transformation tensor
411  transformCoupleField(scalarReceiveBuf_, cmpt);
412  }
413 
414  // Multiply the field by coefficients and add into the result
415  this->addToInternalField(result, !add, coeffs, scalarReceiveBuf_);
416  }
417  else
418  {
419  solveScalarField pnf
420  (
421  procPatch_.compressedReceive<solveScalar>
422  (
423  commsType,
424  this->size()
425  )()
426  );
427 
428  if (!std::is_arithmetic<Type>::value)
429  {
430  // Transform non-scalar data according to the transformation tensor
431  transformCoupleField(pnf, cmpt);
432  }
433 
434  // Multiply the field by coefficients and add into the result
435  this->addToInternalField(result, !add, coeffs, pnf);
436  }
437 
438  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
439 }
440 
441 
442 template<class Type>
444 (
445  Field<Type>&,
446  const bool add,
447  const Field<Type>& psiInternal,
448  const scalarField&,
449  const Pstream::commsTypes commsType
450 ) const
451 {
452  this->patch().patchInternalField(psiInternal, sendBuf_);
453 
454  if
455  (
456  commsType == Pstream::commsTypes::nonBlocking
457  && !Pstream::floatTransfer
458  )
459  {
460  // Fast path.
461  if (debug && !this->ready())
462  {
464  << "On patch " << procPatch_.name()
465  << " outstanding request."
466  << abort(FatalError);
467  }
468 
469 
470  receiveBuf_.setSize(sendBuf_.size());
471  outstandingRecvRequest_ = UPstream::nRequests();
473  (
474  Pstream::commsTypes::nonBlocking,
475  procPatch_.neighbProcNo(),
476  reinterpret_cast<char*>(receiveBuf_.data()),
477  receiveBuf_.byteSize(),
478  procPatch_.tag(),
479  procPatch_.comm()
480  );
481 
482  outstandingSendRequest_ = UPstream::nRequests();
484  (
485  Pstream::commsTypes::nonBlocking,
486  procPatch_.neighbProcNo(),
487  reinterpret_cast<const char*>(sendBuf_.cdata()),
488  sendBuf_.byteSize(),
489  procPatch_.tag(),
490  procPatch_.comm()
491  );
492  }
493  else
494  {
495  procPatch_.compressedSend(commsType, sendBuf_);
496  }
497 
498  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
499 }
500 
501 
502 template<class Type>
504 (
505  Field<Type>& result,
506  const bool add,
507  const Field<Type>&,
508  const scalarField& coeffs,
509  const Pstream::commsTypes commsType
510 ) const
511 {
512  if (this->updatedMatrix())
513  {
514  return;
515  }
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  this->addToInternalField(result, !add, coeffs, receiveBuf_);
543  }
544  else
545  {
546  Field<Type> pnf
547  (
548  procPatch_.compressedReceive<Type>(commsType, this->size())()
549  );
550 
551  // Transform according to the transformation tensor
552  transformCoupleField(pnf);
553 
554  // Multiply the field by coefficients and add into the result
555  this->addToInternalField(result, !add, coeffs, pnf);
556  }
557 
558  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
559 }
560 
561 
562 template<class Type>
564 {
565  if
566  (
567  outstandingSendRequest_ >= 0
568  && outstandingSendRequest_ < Pstream::nRequests()
569  )
570  {
571  bool finished = UPstream::finishedRequest(outstandingSendRequest_);
572  if (!finished)
573  {
574  return false;
575  }
576  }
577  outstandingSendRequest_ = -1;
578 
579  if
580  (
581  outstandingRecvRequest_ >= 0
582  && outstandingRecvRequest_ < Pstream::nRequests()
583  )
584  {
585  bool finished = UPstream::finishedRequest(outstandingRecvRequest_);
586  if (!finished)
587  {
588  return false;
589  }
590  }
591  outstandingRecvRequest_ = -1;
592 
593  return true;
594 }
595 
596 
597 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::fvPatchField
Abstract base class with a fat-interface to all derived classes covering all possible ways in which t...
Definition: volSurfaceMapping.H:50
setSize
points setSize(newPointi)
p
volScalarField & p
Definition: createFieldRefs.H:8
processorFvPatch.H
processorFvPatchField.H
Foam::processorFvPatchField::processorFvPatchField
processorFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
Definition: processorFvPatchField.C:38
Foam::processorFvPatchField
This boundary condition enables processor communication across patches.
Definition: processorFvPatchField.H:66
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::FatalIOError
IOerror FatalIOError
Foam::processorFvPatchField::initEvaluate
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
Definition: processorFvPatchField.C:214
Foam::transform
dimensionSet transform(const dimensionSet &ds)
Return the argument; transformations do not change the dimensions.
Definition: dimensionSet.C:519
transformField.H
Spatial transformation functions for primitive fields.
Foam::Field
Generic templated field type.
Definition: Field.H:63
Foam::processorFvPatchField::evaluate
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
Definition: processorFvPatchField.C:262
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:65
Foam::blockMeshTools::read
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
Definition: blockMeshTools.C:33
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
Foam::lduInterfaceField::updatedMatrix
bool updatedMatrix() const
Whether matrix has been updated.
Definition: lduInterfaceField.H:119
Foam::processorFvPatchField::updateInterfaceMatrix
virtual void updateInterfaceMatrix(solveScalarField &result, const bool add, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Update result field based on interface functionality.
Definition: processorFvPatchField.C:374
Foam::add
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Definition: FieldFieldFunctions.C:939
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::processorFvPatchField::initInterfaceMatrixUpdate
virtual void initInterfaceMatrixUpdate(solveScalarField &result, const bool add, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Initialise neighbour matrix update.
Definition: processorFvPatchField.C:313
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::processorFvPatchField::patchNeighbourField
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour field given internal field.
Definition: processorFvPatchField.C:199
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:69
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
f
labelList f(nPoints)
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
Foam::coupledFvPatchField
Abstract base class for coupled patches.
Definition: coupledFvPatchField.H:57
Foam::processorFvPatchField::ready
virtual bool ready() const
Is all data available.
Definition: processorFvPatchField.C:563
Foam::direction
uint8_t direction
Definition: direction.H:52
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
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::fvPatchFieldMapper
Foam::fvPatchFieldMapper.
Definition: fvPatchFieldMapper.H:47
Foam::fvPatchField::patch
const fvPatch & patch() const
Return patch.
Definition: fvPatchField.H:343
Foam::coupledFvPatchField::snGrad
virtual tmp< Field< Type > > snGrad() const
Return patch-normal gradient.
Definition: coupledFvPatchField.H:151
Foam::processorLduInterfaceField
Abstract base class for processor coupled interfaces.
Definition: processorLduInterfaceField.H:52
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:55
Foam::DimensionedField
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: DimensionedField.H:54