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 | Copyright (C) 2011-2015 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 // Construct by mapping given processorFvPatchField<Type>
71 template<class Type>
73 (
74  const processorFvPatchField<Type>& ptf,
75  const fvPatch& p,
77  const fvPatchFieldMapper& mapper
78 )
79 :
80  coupledFvPatchField<Type>(ptf, p, iF, mapper),
81  procPatch_(refCast<const processorFvPatch>(p)),
82  sendBuf_(0),
83  receiveBuf_(0),
84  outstandingSendRequest_(-1),
85  outstandingRecvRequest_(-1),
86  scalarSendBuf_(0),
87  scalarReceiveBuf_(0)
88 {
89  if (!isA<processorFvPatch>(this->patch()))
90  {
92  << "' not constraint type '" << typeName << "'"
93  << "\n for patch " << p.name()
94  << " of field " << this->dimensionedInternalField().name()
95  << " in file " << this->dimensionedInternalField().objectPath()
96  << exit(FatalIOError);
97  }
98  if (debug && !ptf.ready())
99  {
101  << "On patch " << procPatch_.name() << " outstanding request."
102  << abort(FatalError);
103  }
104 }
105 
106 
107 template<class Type>
109 (
110  const fvPatch& p,
112  const dictionary& dict
113 )
114 :
116  procPatch_(refCast<const processorFvPatch>(p)),
117  sendBuf_(0),
118  receiveBuf_(0),
119  outstandingSendRequest_(-1),
120  outstandingRecvRequest_(-1),
121  scalarSendBuf_(0),
122  scalarReceiveBuf_(0)
123 {
124  if (!isA<processorFvPatch>(p))
125  {
127  (
128  dict
129  ) << "\n patch type '" << p.type()
130  << "' not constraint type '" << typeName << "'"
131  << "\n for patch " << p.name()
132  << " of field " << this->dimensionedInternalField().name()
133  << " in file " << this->dimensionedInternalField().objectPath()
134  << exit(FatalIOError);
135  }
136 }
137 
138 
139 template<class Type>
141 (
142  const processorFvPatchField<Type>& ptf
143 )
144 :
147  procPatch_(refCast<const processorFvPatch>(ptf.patch())),
148  sendBuf_(ptf.sendBuf_.xfer()),
149  receiveBuf_(ptf.receiveBuf_.xfer()),
150  outstandingSendRequest_(-1),
151  outstandingRecvRequest_(-1),
152  scalarSendBuf_(ptf.scalarSendBuf_.xfer()),
153  scalarReceiveBuf_(ptf.scalarReceiveBuf_.xfer())
154 {
155  if (debug && !ptf.ready())
156  {
158  << "On patch " << procPatch_.name() << " outstanding request."
159  << abort(FatalError);
160  }
161 }
162 
163 
164 template<class Type>
166 (
167  const processorFvPatchField<Type>& ptf,
169 )
170 :
171  coupledFvPatchField<Type>(ptf, iF),
172  procPatch_(refCast<const processorFvPatch>(ptf.patch())),
173  sendBuf_(0),
174  receiveBuf_(0),
175  outstandingSendRequest_(-1),
176  outstandingRecvRequest_(-1),
177  scalarSendBuf_(0),
178  scalarReceiveBuf_(0)
179 {
180  if (debug && !ptf.ready())
181  {
183  << "On patch " << procPatch_.name() << " outstanding request."
184  << abort(FatalError);
185  }
186 }
187 
188 
189 // * * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * //
190 
191 template<class Type>
193 {}
194 
195 
196 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
197 
198 template<class Type>
201 {
202  if (debug && !this->ready())
203  {
205  << "On patch " << procPatch_.name()
206  << " outstanding request."
207  << abort(FatalError);
208  }
209  return *this;
210 }
211 
212 
213 template<class Type>
215 (
216  const Pstream::commsTypes commsType
217 )
218 {
219  if (Pstream::parRun())
220  {
221  this->patchInternalField(sendBuf_);
222 
223  if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
224  {
225  // Fast path. Receive into *this
226  this->setSize(sendBuf_.size());
227  outstandingRecvRequest_ = UPstream::nRequests();
229  (
230  Pstream::nonBlocking,
231  procPatch_.neighbProcNo(),
232  reinterpret_cast<char*>(this->begin()),
233  this->byteSize(),
234  procPatch_.tag(),
235  procPatch_.comm()
236  );
237 
238  outstandingSendRequest_ = UPstream::nRequests();
240  (
241  Pstream::nonBlocking,
242  procPatch_.neighbProcNo(),
243  reinterpret_cast<const char*>(sendBuf_.begin()),
244  this->byteSize(),
245  procPatch_.tag(),
246  procPatch_.comm()
247  );
248  }
249  else
250  {
251  procPatch_.compressedSend(commsType, sendBuf_);
252  }
253  }
254 }
255 
256 
257 template<class Type>
259 (
260  const Pstream::commsTypes commsType
261 )
262 {
263  if (Pstream::parRun())
264  {
265  if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
266  {
267  // Fast path. Received into *this
268 
269  if
270  (
271  outstandingRecvRequest_ >= 0
272  && outstandingRecvRequest_ < Pstream::nRequests()
273  )
274  {
275  UPstream::waitRequest(outstandingRecvRequest_);
276  }
277  outstandingSendRequest_ = -1;
278  outstandingRecvRequest_ = -1;
279  }
280  else
281  {
282  procPatch_.compressedReceive<Type>(commsType, *this);
283  }
284 
285  if (doTransform())
286  {
287  transform(*this, procPatch_.forwardT(), *this);
288  }
289  }
290 }
291 
292 
293 template<class Type>
296 (
297  const scalarField& deltaCoeffs
298 ) const
299 {
300  return deltaCoeffs*(*this - this->patchInternalField());
301 }
302 
303 
304 template<class Type>
306 (
307  scalarField&,
308  const scalarField& psiInternal,
309  const scalarField&,
310  const direction,
311  const Pstream::commsTypes commsType
312 ) const
313 {
314  this->patch().patchInternalField(psiInternal, scalarSendBuf_);
315 
316  if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
317  {
318  // Fast path.
319  if (debug && !this->ready())
320  {
322  << "On patch " << procPatch_.name()
323  << " outstanding request."
324  << abort(FatalError);
325  }
326 
327 
328  scalarReceiveBuf_.setSize(scalarSendBuf_.size());
329  outstandingRecvRequest_ = UPstream::nRequests();
331  (
332  Pstream::nonBlocking,
333  procPatch_.neighbProcNo(),
334  reinterpret_cast<char*>(scalarReceiveBuf_.begin()),
335  scalarReceiveBuf_.byteSize(),
336  procPatch_.tag(),
337  procPatch_.comm()
338  );
339 
340  outstandingSendRequest_ = UPstream::nRequests();
342  (
343  Pstream::nonBlocking,
344  procPatch_.neighbProcNo(),
345  reinterpret_cast<const char*>(scalarSendBuf_.begin()),
346  scalarSendBuf_.byteSize(),
347  procPatch_.tag(),
348  procPatch_.comm()
349  );
350  }
351  else
352  {
353  procPatch_.compressedSend(commsType, scalarSendBuf_);
354  }
355 
356  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
357 }
358 
359 
360 template<class Type>
362 (
363  scalarField& result,
364  const scalarField&,
365  const scalarField& coeffs,
366  const direction cmpt,
367  const Pstream::commsTypes commsType
368 ) const
369 {
370  if (this->updatedMatrix())
371  {
372  return;
373  }
374 
375  const labelUList& faceCells = this->patch().faceCells();
376 
377  if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
378  {
379  // Fast path.
380  if
381  (
382  outstandingRecvRequest_ >= 0
383  && outstandingRecvRequest_ < Pstream::nRequests()
384  )
385  {
386  UPstream::waitRequest(outstandingRecvRequest_);
387  }
388  // Recv finished so assume sending finished as well.
389  outstandingSendRequest_ = -1;
390  outstandingRecvRequest_ = -1;
391 
392  // Consume straight from scalarReceiveBuf_
393 
394  // Transform according to the transformation tensor
395  transformCoupleField(scalarReceiveBuf_, cmpt);
396 
397  // Multiply the field by coefficients and add into the result
398  forAll(faceCells, elemI)
399  {
400  result[faceCells[elemI]] -= coeffs[elemI]*scalarReceiveBuf_[elemI];
401  }
402  }
403  else
404  {
405  scalarField pnf
406  (
407  procPatch_.compressedReceive<scalar>(commsType, this->size())()
408  );
409 
410  // Transform according to the transformation tensor
411  transformCoupleField(pnf, cmpt);
412 
413  // Multiply the field by coefficients and add into the result
414  forAll(faceCells, elemI)
415  {
416  result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
417  }
418  }
419 
420  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
421 }
422 
423 
424 template<class Type>
426 (
427  Field<Type>&,
428  const Field<Type>& psiInternal,
429  const scalarField&,
430  const Pstream::commsTypes commsType
431 ) const
432 {
433  this->patch().patchInternalField(psiInternal, sendBuf_);
434 
435  if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
436  {
437  // Fast path.
438  if (debug && !this->ready())
439  {
441  << "On patch " << procPatch_.name()
442  << " outstanding request."
443  << abort(FatalError);
444  }
445 
446 
447  receiveBuf_.setSize(sendBuf_.size());
448  outstandingRecvRequest_ = UPstream::nRequests();
450  (
451  Pstream::nonBlocking,
452  procPatch_.neighbProcNo(),
453  reinterpret_cast<char*>(receiveBuf_.begin()),
454  receiveBuf_.byteSize(),
455  procPatch_.tag(),
456  procPatch_.comm()
457  );
458 
459  outstandingSendRequest_ = UPstream::nRequests();
461  (
462  Pstream::nonBlocking,
463  procPatch_.neighbProcNo(),
464  reinterpret_cast<const char*>(sendBuf_.begin()),
465  sendBuf_.byteSize(),
466  procPatch_.tag(),
467  procPatch_.comm()
468  );
469  }
470  else
471  {
472  procPatch_.compressedSend(commsType, sendBuf_);
473  }
474 
475  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = false;
476 }
477 
478 
479 template<class Type>
481 (
482  Field<Type>& result,
483  const Field<Type>&,
484  const scalarField& coeffs,
485  const Pstream::commsTypes commsType
486 ) const
487 {
488  if (this->updatedMatrix())
489  {
490  return;
491  }
492 
493  const labelUList& faceCells = this->patch().faceCells();
494 
495  if (commsType == Pstream::nonBlocking && !Pstream::floatTransfer)
496  {
497  // Fast path.
498  if
499  (
500  outstandingRecvRequest_ >= 0
501  && outstandingRecvRequest_ < Pstream::nRequests()
502  )
503  {
504  UPstream::waitRequest(outstandingRecvRequest_);
505  }
506  // Recv finished so assume sending finished as well.
507  outstandingSendRequest_ = -1;
508  outstandingRecvRequest_ = -1;
509 
510  // Consume straight from receiveBuf_
511 
512  // Transform according to the transformation tensor
513  transformCoupleField(receiveBuf_);
514 
515  // Multiply the field by coefficients and add into the result
516  forAll(faceCells, elemI)
517  {
518  result[faceCells[elemI]] -= coeffs[elemI]*receiveBuf_[elemI];
519  }
520  }
521  else
522  {
523  Field<Type> pnf
524  (
525  procPatch_.compressedReceive<Type>(commsType, this->size())()
526  );
527 
528  // Transform according to the transformation tensor
529  transformCoupleField(pnf);
530 
531  // Multiply the field by coefficients and add into the result
532  forAll(faceCells, elemI)
533  {
534  result[faceCells[elemI]] -= coeffs[elemI]*pnf[elemI];
535  }
536  }
537 
538  const_cast<processorFvPatchField<Type>&>(*this).updatedMatrix() = true;
539 }
540 
541 
542 template<class Type>
544 {
545  if
546  (
547  outstandingSendRequest_ >= 0
548  && outstandingSendRequest_ < Pstream::nRequests()
549  )
550  {
551  bool finished = UPstream::finishedRequest(outstandingSendRequest_);
552  if (!finished)
553  {
554  return false;
555  }
556  }
557  outstandingSendRequest_ = -1;
558 
559  if
560  (
561  outstandingRecvRequest_ >= 0
562  && outstandingRecvRequest_ < Pstream::nRequests()
563  )
564  {
565  bool finished = UPstream::finishedRequest(outstandingRecvRequest_);
566  if (!finished)
567  {
568  return false;
569  }
570  }
571  outstandingRecvRequest_ = -1;
572 
573  return true;
574 }
575 
576 
577 // ************************************************************************* //
setSize
points setSize(newPointi)
p
p
Definition: pEqn.H:62
processorFvPatch.H
processorFvPatchField.H
Foam::processorFvPatchField::processorFvPatchField
processorFvPatchField(const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
Definition: processorFvPatchField.C:35
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::processorFvPatchField
This boundary condition enables processor communication across patches.
Definition: processorFvPatchField.H:64
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::read
bool read(const char *, int32_t &)
Definition: int32IO.C:87
dimensionedInternalField
rDeltaT dimensionedInternalField()
Foam::FatalIOError
IOerror FatalIOError
Foam::processorFvPatchField::initEvaluate
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
Definition: processorFvPatchField.C:215
transformField.H
Spatial transformation functions for primitive fields.
Foam::transform
dimensionSet transform(const dimensionSet &)
Definition: dimensionSet.C:465
Foam::processorFvPatchField::scalarSendBuf_
Field< scalar > scalarSendBuf_
Scalar send buffer.
Definition: processorFvPatchField.H:89
Foam::Field< Type >
Foam::processorFvPatchField::sendBuf_
Field< Type > sendBuf_
Send buffer.
Definition: processorFvPatchField.H:77
Foam::processorFvPatchField::evaluate
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
Definition: processorFvPatchField.C:259
Foam::fvPatch
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:61
Foam::processorFvPatchField::initInterfaceMatrixUpdate
virtual void initInterfaceMatrixUpdate(scalarField &result, const scalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Initialise neighbour matrix update.
Definition: processorFvPatchField.C:306
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::lduInterfaceField::updatedMatrix
bool updatedMatrix() const
Whether matrix has been updated.
Definition: lduInterfaceField.H:116
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::processorFvPatchField::updateInterfaceMatrix
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.
Definition: processorFvPatchField.C:362
Foam::processorFvPatchField::patchNeighbourField
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour field given internal field.
Definition: processorFvPatchField.C:200
Foam::processorFvPatchField::~processorFvPatchField
~processorFvPatchField()
Destructor.
Definition: processorFvPatchField.C:192
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:64
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
f
labelList f(nPoints)
Foam::coupledFvPatchField
Abstract base class for coupled patches.
Definition: coupledFvPatchField.H:54
Foam::processorFvPatchField::scalarReceiveBuf_
Field< scalar > scalarReceiveBuf_
Scalar receive buffer.
Definition: processorFvPatchField.H:92
Foam::processorFvPatchField::ready
virtual bool ready() const
Is all data available.
Definition: processorFvPatchField.C:543
Foam::UList
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
Foam::direction
unsigned char direction
Definition: direction.H:43
Foam::processorFvPatchField::receiveBuf_
Field< Type > receiveBuf_
Receive buffer.
Definition: processorFvPatchField.H:80
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:330
Foam::fvPatchFieldMapper
Foam::fvPatchFieldMapper.
Definition: fvPatchFieldMapper.H:45
Foam::fvPatchField< Type >::patch
const fvPatch & patch() const
Return patch.
Definition: fvPatchField.H:300
Foam::coupledFvPatchField::snGrad
virtual tmp< Field< Type > > snGrad() const
Return patch-normal gradient.
Definition: coupledFvPatchField.H:147
Foam::processorLduInterfaceField
Abstract base class for processor coupled interfaces.
Definition: processorLduInterfaceField.H:49
write
Tcoeff write()
Foam::DimensionedField
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: DimensionedField.H:51