calculatedProcessorFvPatchField.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) 2019-2025 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 
29 
30 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 
32 template<class Type>
34 (
35  const lduInterface& interface,
36  const fvPatch& p,
38 )
39 :
40  coupledFvPatchField<Type>(p, iF),
41  procInterface_(refCast<const lduPrimitiveProcessorInterface>(interface)),
42  sendRequest_(-1),
43  recvRequest_(-1)
44 {}
45 
46 
47 template<class Type>
49 (
51 )
52 :
53  coupledFvPatchField<Type>(ptf),
54  procInterface_(ptf.procInterface_),
55  sendRequest_(-1),
56  recvRequest_(-1)
57 {}
58 
59 
60 template<class Type>
62 (
65 )
66 :
67  coupledFvPatchField<Type>(ptf, iF),
68  procInterface_(ptf.procInterface_),
69  sendRequest_(-1),
70  recvRequest_(-1)
71 {}
72 
73 
74 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
75 
76 template<class Type>
78 {
79  return UPstream::finishedRequestPair(recvRequest_, sendRequest_);
80 }
81 
82 
83 template<class Type>
85 {
86  const bool ok = UPstream::finishedRequest(recvRequest_);
87  if (ok)
88  {
89  recvRequest_ = -1;
90  if (UPstream::finishedRequest(sendRequest_)) sendRequest_ = -1;
91  }
92  return ok;
93 }
94 
95 
96 template<class Type>
99 {
100  if (!this->ready())
101  {
103  << "Outstanding request on patch of size "
104  << procInterface_.faceCells().size()
105  << " between proc " << procInterface_.myProcNo()
106  << " and " << procInterface_.neighbProcNo()
107  << abort(FatalError);
108  }
109  return *this;
110 }
111 
112 
113 template<class Type>
115 (
116  UList<Type>& pnf
117 ) const
118 {
119  if (!this->ready())
120  {
122  << "Outstanding request on patch of size "
123  << procInterface_.faceCells().size()
124  << " between proc " << procInterface_.myProcNo()
125  << " and " << procInterface_.neighbProcNo()
126  << abort(FatalError);
127  }
128  pnf.deepCopy(*this);
129 }
130 
131 
132 template<class Type>
134 (
135  const Pstream::commsTypes commsType
136 )
137 {
138  if (UPstream::parRun())
139  {
140  if constexpr (!is_contiguous_v<Type>)
141  {
143  << "Invalid for non-contiguous data types"
144  << abort(FatalError);
145  }
146 
147  // Bypass patchInternalField since uses fvPatch addressing
148 
149  Field<Type>& self = *this; // Receive straight into *this
150 
151  {
152  const Field<Type>& psiInternal = this->internalField();
153  const labelUList& faceCells = procInterface_.faceCells();
154 
155  sendBuf_.resize_nocopy(faceCells.size());
156  self.resize_nocopy(faceCells.size());
157 
158  forAll(faceCells, i)
159  {
160  sendBuf_[i] = psiInternal[faceCells[i]];
161  }
162  }
163 
164  recvRequest_ = UPstream::nRequests();
166  (
167  UPstream::commsTypes::nonBlocking,
168  procInterface_.neighbProcNo(),
169  self,
170  procInterface_.tag(),
171  procInterface_.comm()
172  );
173 
174  sendRequest_ = UPstream::nRequests();
176  (
177  UPstream::commsTypes::nonBlocking,
178  procInterface_.neighbProcNo(),
179  sendBuf_,
180  procInterface_.tag(),
181  procInterface_.comm()
182  );
183  }
184 }
185 
186 
187 template<class Type>
189 (
190  const Pstream::commsTypes commsType
191 )
192 {
193  if (UPstream::parRun())
194  {
195  // Require receive data.
196  // Only update the send request state.
197  UPstream::waitRequest(recvRequest_); recvRequest_ = -1;
198  if (UPstream::finishedRequest(sendRequest_)) sendRequest_ = -1;
199  }
200 }
201 
202 
203 template<class Type>
205 (
206  solveScalarField& result,
207  const bool add,
208  const lduAddressing& lduAddr,
209  const label patchId,
210  const solveScalarField& psiInternal,
211  const scalarField& coeffs,
212  const direction cmpt,
213  const Pstream::commsTypes commsType
214 ) const
215 {
216  if (!this->all_ready())
217  {
219  << "Outstanding request(s) on interface "
220  //<< interface_.name()
221  << abort(FatalError);
222  }
223 
224  // Bypass patchInternalField since uses fvPatch addressing
225  const labelUList& faceCells = lduAddr.patchAddr(patchId);
226 
227  {
228  scalarSendBuf_.resize_nocopy(faceCells.size());
229  scalarRecvBuf_.resize_nocopy(faceCells.size());
230 
231  forAll(faceCells, i)
232  {
233  scalarSendBuf_[i] = psiInternal[faceCells[i]];
234  }
235  }
236 
237  recvRequest_ = UPstream::nRequests();
239  (
240  UPstream::commsTypes::nonBlocking,
241  procInterface_.neighbProcNo(),
242  scalarRecvBuf_,
243  procInterface_.tag(),
244  procInterface_.comm()
245  );
246 
247  sendRequest_ = UPstream::nRequests();
249  (
250  UPstream::commsTypes::nonBlocking,
251  procInterface_.neighbProcNo(),
252  scalarSendBuf_,
253  procInterface_.tag(),
254  procInterface_.comm()
255  );
257  this->updatedMatrix(false);
258 }
259 
260 
261 template<class Type>
263 (
264  solveScalarField& result,
265  const bool add,
266  const scalarField& coeffs,
267  const solveScalarField& vals
268 ) const
269 {
270  const labelUList& faceCells = this->procInterface_.faceCells();
271 
272  if (add)
273  {
274  forAll(faceCells, elemI)
275  {
276  result[faceCells[elemI]] += coeffs[elemI]*vals[elemI];
277  }
278  }
279  else
280  {
281  forAll(faceCells, elemI)
282  {
283  result[faceCells[elemI]] -= coeffs[elemI]*vals[elemI];
284  }
285  }
286 }
287 
288 
289 template<class Type>
291 (
292  solveScalarField& result,
293  const bool add,
294  const lduAddressing& lduAddr,
295  const label patchId,
296  const solveScalarField& psiInternal,
297  const scalarField& coeffs,
298  const direction cmpt,
299  const Pstream::commsTypes commsType
300 ) const
301 {
302  if (this->updatedMatrix())
303  {
304  return;
305  }
306 
307  if (UPstream::parRun())
308  {
309  // Require receive data.
310  // Only update the send request state.
311  UPstream::waitRequest(recvRequest_); recvRequest_ = -1;
312  if (UPstream::finishedRequest(sendRequest_)) sendRequest_ = -1;
313  }
314 
315 
316  // Consume straight from receive buffer. Note use of our own
317  // helper to avoid using fvPatch addressing
318  addToInternalField(result, !add, coeffs, scalarRecvBuf_);
319 
320  this->updatedMatrix(true);
321 }
322 
323 
324 // ************************************************************************* //
label patchId(-1)
uint8_t direction
Definition: direction.H:46
void addToInternalField(solveScalarField &result, const bool add, const scalarField &coeffs, const solveScalarField &vals) const
virtual tmp< Field< Type > > patchNeighbourField() const
Return neighbour field.
Field< solveScalar > solveScalarField
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
Definition: typeInfo.H:172
virtual void evaluate(const Pstream::commsTypes commsType)
Evaluate the patch field.
A finiteVolume patch using a polyPatch and a fvBoundaryMesh.
Definition: fvPatch.H:70
interfaceProperties interface(alpha1, U, thermo->transportPropertiesDict())
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:52
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
virtual void initEvaluate(const Pstream::commsTypes commsType)
Initialise the evaluation of the patch field.
virtual void updateInterfaceMatrix(solveScalarField &result, const bool add, const lduAddressing &lduAddr, const label patchId, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Update result field based on interface functionality.
virtual bool all_ready() const
Receive and send requests have both completed.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Abstract base class for coupled patches.
virtual bool ready() const
Are all (receive) data available?
virtual void initInterfaceMatrixUpdate(solveScalarField &result, const bool add, const lduAddressing &lduAddr, const label patchId, const solveScalarField &psiInternal, const scalarField &coeffs, const direction cmpt, const Pstream::commsTypes commsType) const
Initialise neighbour matrix update.
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
void read(Istream &, label &val, const dictionary &)
In-place read with dictionary lookup.
Concrete implementation of processor interface. Used to temporarily store settings.
calculatedProcessorFvPatchField(const lduInterface &interface, const fvPatch &, const DimensionedField< Type, volMesh > &)
Construct from patch and internal field.
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
An abstract base class for implicitly-coupled interfaces e.g. processor and cyclic patches...
Definition: lduInterface.H:53
A processorFvPatchField type bypassing fvPatch.
volScalarField & p
A class for managing temporary objects.
Definition: HashPtrTable.H:50