Loading...
Searching...
No Matches
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-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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/>.
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 (
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 {
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 "
102 << UPstream::commsTypeNames[commsType]
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
122 (
125 )
126 {
127 // Wait for some interface requests to become available and
128 // consume them. No guarantee that the finished requests actually
129 // correspond to any particular interface, but it is reasonably
130 // probable that some interfaces will be able to start consumption
131 // without waiting for all requests.
132
133 DynamicList<int> indices; // (work array)
134
135 // const label maxPolling =
136 // (
137 // (UPstream::nPollProcInterfaces < 0)
138 // ? (UPstream::nRequests() - startRequest)
139 // : UPstream::nPollProcInterfaces
140 // );
141
142 for
143 (
144 bool pollingActive = (UPstream::nPollProcInterfaces < 0);
145 (
146 pollingActive
147 && UPstream::waitSomeRequests(startRequest, -1, &indices)
148 );
149 /*nil*/
150 )
151 {
152 pollingActive = false;
153
154 forAll(interfaces, interfacei)
155 {
156 auto* intf = interfaces.get(interfacei);
157
158 if (intf && !intf->updatedMatrix())
159 {
160 if (intf->ready())
161 {
162 intf->updateInterfaceMatrix
163 (
164 result,
165 add,
166 mesh().lduAddr(),
167 interfacei,
168 psiif,
169 coupleCoeffs[interfacei],
170 cmpt,
171 commsType
172 );
173 }
174 else
175 {
176 pollingActive = true;
177 }
178 }
179 }
180 }
181
182 // [OLDER]
183 // Alternative for consuming interfaces as they become available.
184 // Within the loop, the ready() calls an MPI_Test
185 // that can trigger progression. However, a bit less reliably
186 // (and less efficient) since it is implies multiple calls to
187 // MPI_Test to progress the MPI transfer, but no guarantee that
188 // any of them will actually complete within nPollProcInterfaces
189 // calls.
190
191 for (label i = 0; i < UPstream::nPollProcInterfaces; ++i)
192 {
193 bool allUpdated = true;
194
195 forAll(interfaces, interfacei)
196 {
197 auto* intf = interfaces.get(interfacei);
198
199 if (intf && !intf->updatedMatrix())
200 {
201 if (intf->ready())
202 {
203 intf->updateInterfaceMatrix
204 (
205 result,
206 add,
207 mesh().lduAddr(),
208 interfacei,
209 psiif,
210 coupleCoeffs[interfacei],
211 cmpt,
212 commsType
213 );
214 }
215 else
216 {
217 allUpdated = false;
218 }
219 }
220 }
221
222 if (allUpdated)
223 {
224 break; // Early exit
225 }
226 }
227 }
228
229
230 if
231 (
234 )
235 {
236 // Wait until sends/receives have finished.
237 // - effectively a no-op (without waiting) if already completed.
238 if (commsType == UPstream::commsTypes::nonBlocking)
239 {
240 UPstream::waitRequests(startRequest);
241 }
242
243 // Check/no-check for updatedMatrix() ?
244 const bool noCheck = (commsType == UPstream::commsTypes::buffered);
245
246 // Consume anything still outstanding
247 forAll(interfaces, interfacei)
248 {
249 auto* intf = interfaces.get(interfacei);
250
251 if (intf && (noCheck || !intf->updatedMatrix()))
252 {
253 intf->updateInterfaceMatrix
254 (
255 result,
256 add,
257 mesh().lduAddr(),
258 interfacei,
259 psiif,
260 coupleCoeffs[interfacei],
261 cmpt,
262 commsType
263 );
264 }
265 }
266 }
267 else if (commsType == UPstream::commsTypes::scheduled)
268 {
269 const lduSchedule& patchSchedule = this->patchSchedule();
270
271 // Loop over all the "normal" interfaces relating to standard patches
272 for (const auto& sched : patchSchedule)
273 {
274 const label interfacei = sched.patch;
275
276 if (interfaces.set(interfacei))
277 {
278 if (sched.init)
279 {
280 interfaces[interfacei].initInterfaceMatrixUpdate
281 (
282 result,
283 add,
284 mesh().lduAddr(),
285 interfacei,
286 psiif,
287 coupleCoeffs[interfacei],
288 cmpt,
289 commsType
290 );
291 }
292 else
293 {
294 interfaces[interfacei].updateInterfaceMatrix
295 (
296 result,
297 add,
298 mesh().lduAddr(),
299 interfacei,
300 psiif,
301 coupleCoeffs[interfacei],
302 cmpt,
303 commsType
304 );
305 }
306 }
307 }
308
309 // Loop over the "global" patches are on the list of interfaces but
310 // beyond the end of the schedule which only handles "normal" patches
311 for
312 (
313 label interfacei=patchSchedule.size()/2;
314 interfacei<interfaces.size();
315 interfacei++
316 )
317 {
318 if (interfaces.set(interfacei))
319 {
320 interfaces[interfacei].updateInterfaceMatrix
321 (
322 result,
323 add,
324 mesh().lduAddr(),
325 interfacei,
326 psiif,
327 coupleCoeffs[interfacei],
328 cmpt,
330 );
331 }
332 }
333 }
334 else
335 {
337 << "Unsupported communications type "
338 << UPstream::commsTypeNames[commsType]
339 << exit(FatalError);
340 }
341}
342
343
344// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
A field of fields is a PtrList of fields with reference counting.
Definition FieldField.H:77
static bool waitSomeRequests(label pos, label len=-1, DynamicList< int > *indices=nullptr)
Wait until some requests (from position onwards) have finished. Corresponds to MPI_Waitsome().
commsTypes
Communications types.
Definition UPstream.H:81
@ scheduled
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
Definition UPstream.H:83
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
Definition UPstream.H:84
@ buffered
"buffered" : (MPI_Bsend, MPI_Recv)
Definition UPstream.H:82
static const Enum< commsTypes > commsTypeNames
Enumerated names for the communication types.
Definition UPstream.H:92
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition UPstream.H:1040
static void waitRequests()
Wait for all requests to finish.
Definition UPstream.H:2497
static commsTypes defaultCommsType
Default commsType.
Definition UPstream.H:1045
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition UPtrList.H:366
const T * get(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition UPtrListI.H:134
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
const lduAddressing & lduAddr() const
Return the LDU addressing.
Definition lduMatrix.H:769
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.
const lduSchedule & patchSchedule() const
Return the patch evaluation schedule.
Definition lduMatrix.H:777
const lduMesh & mesh() const noexcept
Return the LDU mesh from which the addressing is obtained.
Definition lduMatrix.H:753
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.
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
List< lduScheduleEntry > lduSchedule
A List of lduSchedule entries.
Definition lduSchedule.H:46
void add(DimensionedField< scalar, GeoMesh > &result, const dimensioned< scalar > &dt1, const DimensionedField< scalar, GeoMesh > &f2)
Field< solveScalar > solveScalarField
uint8_t direction
Definition direction.H:49
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
UPtrList< const lduInterfaceField > lduInterfaceFieldPtrsList
List of coupled interface fields to be used in coupling.
dict add("bounds", meshBb)
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299