lduMatrixUpdateMatrixInterfaces.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 "lduMatrix.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
34 (
35  const bool add,
36  const FieldField<Field, scalar>& coupleCoeffs,
37  const lduInterfaceFieldPtrsList& interfaces,
38  const solveScalarField& psiif,
39  solveScalarField& result,
40  const direction cmpt
41 ) const
42 {
44 
45  if
46  (
48  || commsType == UPstream::commsTypes::nonBlocking
49  )
50  {
51  forAll(interfaces, interfacei)
52  {
53  if (interfaces.set(interfacei))
54  {
55  interfaces[interfacei].initInterfaceMatrixUpdate
56  (
57  result,
58  add,
59  mesh().lduAddr(),
60  interfacei,
61  psiif,
62  coupleCoeffs[interfacei],
63  cmpt,
64  commsType
65  );
66  }
67  }
68  }
69  else if (commsType == UPstream::commsTypes::scheduled)
70  {
71  const lduSchedule& patchSchedule = this->patchSchedule();
72 
73  // Loop over the "global" patches are on the list of interfaces but
74  // beyond the end of the schedule which only handles "normal" patches
75  for
76  (
77  label interfacei=patchSchedule.size()/2;
78  interfacei<interfaces.size();
79  interfacei++
80  )
81  {
82  if (interfaces.set(interfacei))
83  {
84  interfaces[interfacei].initInterfaceMatrixUpdate
85  (
86  result,
87  add,
88  mesh().lduAddr(),
89  interfacei,
90  psiif,
91  coupleCoeffs[interfacei],
92  cmpt,
94  );
95  }
96  }
97  }
98  else
99  {
101  << "Unsupported communications type "
103  << exit(FatalError);
104  }
105 }
106 
107 
109 (
110  const bool add,
111  const FieldField<Field, scalar>& coupleCoeffs,
112  const lduInterfaceFieldPtrsList& interfaces,
113  const solveScalarField& psiif,
114  solveScalarField& result,
115  const direction cmpt,
116  const label startRequest
117 ) const
118 {
120 
121  if (commsType == UPstream::commsTypes::blocking)
122  {
123  forAll(interfaces, interfacei)
124  {
125  if (interfaces.set(interfacei))
126  {
127  interfaces[interfacei].updateInterfaceMatrix
128  (
129  result,
130  add,
131  mesh().lduAddr(),
132  interfacei,
133  psiif,
134  coupleCoeffs[interfacei],
135  cmpt,
136  commsType
137  );
138  }
139  }
140  }
141  else if (commsType == UPstream::commsTypes::nonBlocking)
142  {
143  // Try and consume interfaces as they become available
144  bool allUpdated = false;
145 
146  for (label i=0; i<UPstream::nPollProcInterfaces; i++)
147  {
148  allUpdated = true;
149 
150  forAll(interfaces, interfacei)
151  {
152  if (interfaces.set(interfacei))
153  {
154  if (!interfaces[interfacei].updatedMatrix())
155  {
156  if (interfaces[interfacei].ready())
157  {
158  interfaces[interfacei].updateInterfaceMatrix
159  (
160  result,
161  add,
162  mesh().lduAddr(),
163  interfacei,
164  psiif,
165  coupleCoeffs[interfacei],
166  cmpt,
167  commsType
168  );
169  }
170  else
171  {
172  allUpdated = false;
173  }
174  }
175  }
176  }
177 
178  if (allUpdated)
179  {
180  break;
181  }
182  }
183 
184  // Block for everything
185  if (Pstream::parRun())
186  {
187  if (allUpdated)
188  {
189  // All received. Just remove all outstanding requests
190  UPstream::resetRequests(startRequest);
191  }
192  else
193  {
194  // Block for all requests and remove storage
195  UPstream::waitRequests(startRequest);
196  }
197  }
198 
199  // Consume
200  forAll(interfaces, interfacei)
201  {
202  if
203  (
204  interfaces.set(interfacei)
205  && !interfaces[interfacei].updatedMatrix()
206  )
207  {
208  interfaces[interfacei].updateInterfaceMatrix
209  (
210  result,
211  add,
212  mesh().lduAddr(),
213  interfacei,
214  psiif,
215  coupleCoeffs[interfacei],
216  cmpt,
217  commsType
218  );
219  }
220  }
221  }
222  else if (commsType == UPstream::commsTypes::scheduled)
223  {
224  const lduSchedule& patchSchedule = this->patchSchedule();
225 
226  // Loop over all the "normal" interfaces relating to standard patches
227  for (const auto& sched : patchSchedule)
228  {
229  const label interfacei = sched.patch;
230 
231  if (interfaces.set(interfacei))
232  {
233  if (sched.init)
234  {
235  interfaces[interfacei].initInterfaceMatrixUpdate
236  (
237  result,
238  add,
239  mesh().lduAddr(),
240  interfacei,
241  psiif,
242  coupleCoeffs[interfacei],
243  cmpt,
244  commsType
245  );
246  }
247  else
248  {
249  interfaces[interfacei].updateInterfaceMatrix
250  (
251  result,
252  add,
253  mesh().lduAddr(),
254  interfacei,
255  psiif,
256  coupleCoeffs[interfacei],
257  cmpt,
258  commsType
259  );
260  }
261  }
262  }
263 
264  // Loop over the "global" patches are on the list of interfaces but
265  // beyond the end of the schedule which only handles "normal" patches
266  for
267  (
268  label interfacei=patchSchedule.size()/2;
269  interfacei<interfaces.size();
270  interfacei++
271  )
272  {
273  if (interfaces.set(interfacei))
274  {
275  interfaces[interfacei].updateInterfaceMatrix
276  (
277  result,
278  add,
279  mesh().lduAddr(),
280  interfacei,
281  psiif,
282  coupleCoeffs[interfacei],
283  cmpt,
285  );
286  }
287  }
288  }
289  else
290  {
292  << "Unsupported communications type "
293  << UPstream::commsTypeNames[commsType]
294  << exit(FatalError);
295  }
296 }
297 
298 
299 // ************************************************************************* //
UPtrList< const lduInterfaceField > lduInterfaceFieldPtrsList
List of coupled interface fields to be used in coupling.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
"blocking" : (MPI_Bsend, MPI_Recv)
uint8_t direction
Definition: direction.H:46
static const Enum< commsTypes > commsTypeNames
Enumerated names for the communication types.
Definition: UPstream.H:76
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
Field< solveScalar > solveScalarField
commsTypes
Types of communications.
Definition: UPstream.H:66
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:578
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:639
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
Definition: lduSchedule.H:46
A field of fields is a PtrList of fields with reference counting.
Definition: FieldField.H:51
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
Definition: UPtrListI.H:134
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:413
const lduSchedule & patchSchedule() const
Return the patch evaluation schedule.
Definition: lduMatrix.H:722
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition: UPstream.H:342
dynamicFvMesh & mesh
"scheduled" : (MPI_Send, MPI_Recv)
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:99
void updateMatrixInterfaces(const bool add, const FieldField< Field, scalar > &interfaceCoeffs, const lduInterfaceFieldPtrsList &interfaces, const solveScalarField &psiif, solveScalarField &result, const direction cmpt, const label startRequest) const
Update interfaced interfaces for matrix operations.
void initMatrixInterfaces(const bool add, const FieldField< Field, scalar > &interfaceCoeffs, const lduInterfaceFieldPtrsList &interfaces, const solveScalarField &psiif, solveScalarField &result, const direction cmpt) const
Initialise the update of interfaced interfaces for matrix operations.
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
static void resetRequests(const label n)
Truncate outstanding requests to given length.
Definition: UPstream.C:89
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Definition: UPstream.C:93
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:337
const lduMesh & mesh() const noexcept
Return the LDU mesh from which the addressing is obtained.
Definition: lduMatrix.H:698
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition: lduMatrix.H:714
"nonBlocking" : (MPI_Isend, MPI_Irecv)