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 -------------------------------------------------------------------------------
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 #include "lduInterfaceField.H"
31 
32 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
33 
34 template<class Type, class DType, class LUType>
36 (
37  const bool add,
38  const FieldField<Field, LUType>& interfaceCoeffs,
39  const Field<Type>& psiif,
40  Field<Type>& result
41 ) const
42 {
43  const UPstream::commsTypes commsType = UPstream::defaultCommsType;
44 
45  if
46  (
47  commsType == UPstream::commsTypes::blocking
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  lduMesh_.lduAddr(),
60  interfacei,
61  psiif,
62  interfaceCoeffs[interfacei],
63  commsType
64  );
65  }
66  }
67  }
68  else if (commsType == UPstream::commsTypes::scheduled)
69  {
70  const lduSchedule& patchSchedule = this->patchSchedule();
71 
72  // Loop over the "global" patches are on the list of interfaces but
73  // beyond the end of the schedule which only handles "normal" patches
74  for
75  (
76  label interfacei=patchSchedule.size()/2;
77  interfacei<interfaces_.size();
78  interfacei++
79  )
80  {
81  if (interfaces_.set(interfacei))
82  {
83  interfaces_[interfacei].initInterfaceMatrixUpdate
84  (
85  result,
86  add,
87  lduMesh_.lduAddr(),
88  interfacei,
89  psiif,
90  interfaceCoeffs[interfacei],
91  UPstream::commsTypes::blocking
92  );
93  }
94  }
95  }
96  else
97  {
99  << "Unsupported communications type "
100  << UPstream::commsTypeNames[commsType]
102  }
103 }
104 
105 
106 template<class Type, class DType, class LUType>
108 (
109  const bool add,
110  const FieldField<Field, LUType>& interfaceCoeffs,
111  const Field<Type>& psiif,
112  Field<Type>& result,
113  const label startRequest
114 ) const
115 {
116  const UPstream::commsTypes commsType = UPstream::defaultCommsType;
117 
118  if
119  (
120  commsType == UPstream::commsTypes::nonBlocking
121  && UPstream::nPollProcInterfaces
122  )
123  {
124  // Wait for some interface requests to become available and
125  // consume them. No guarantee that the finished requests actually
126  // correspond to any particular interface, but it is reasonably
127  // probable that some interfaces will be able to start consumption
128  // without waiting for all requests.
129 
130  DynamicList<int> indices; // (work array)
131 
132  for
133  (
134  bool pollingActive = (UPstream::nPollProcInterfaces < 0);
135  (
136  pollingActive
137  && UPstream::waitSomeRequests(startRequest, -1, &indices)
138  );
139  /*nil*/
140  )
141  {
142  pollingActive = false;
143 
144  forAll(interfaces_, interfacei)
145  {
146  auto* intf = interfaces_.get(interfacei);
147 
148  if (intf && !intf->updatedMatrix())
149  {
150  if (intf->ready())
151  {
152  intf->updateInterfaceMatrix
153  (
154  result,
155  add,
156  lduMesh_.lduAddr(),
157  interfacei,
158  psiif,
159  interfaceCoeffs[interfacei],
160  commsType
161  );
162  }
163  else
164  {
165  pollingActive = true;
166  }
167  }
168  }
169  }
170  }
171 
172 
173  if
174  (
175  commsType == UPstream::commsTypes::blocking
176  || commsType == UPstream::commsTypes::nonBlocking
177  )
178  {
179  // Wait until sends/receives have finished.
180  // - effectively a no-op (without waiting) if already completed.
181  if (commsType == UPstream::commsTypes::nonBlocking)
182  {
183  UPstream::waitRequests(startRequest);
184  }
185 
186  // Check/no-check for updatedMatrix() ?
187  const bool noCheck = (commsType == UPstream::commsTypes::blocking);
188 
189  forAll(interfaces_, interfacei)
190  {
191  auto* intf = interfaces_.get(interfacei);
192 
193  if (intf && (noCheck || !intf->updatedMatrix()))
194  {
195  intf->updateInterfaceMatrix
196  (
197  result,
198  add,
199  lduMesh_.lduAddr(),
200  interfacei,
201  psiif,
202  interfaceCoeffs[interfacei],
203  commsType
204  );
205  }
206  }
207  }
208  else if (commsType == UPstream::commsTypes::scheduled)
209  {
210  const lduSchedule& patchSchedule = this->patchSchedule();
211 
212  // Loop over all the "normal" interfaces relating to standard patches
213  for (const auto& schedEval : patchSchedule)
214  {
215  const label interfacei = schedEval.patch;
216 
217  if (interfaces_.set(interfacei))
218  {
219  if (schedEval.init)
220  {
221  interfaces_[interfacei].initInterfaceMatrixUpdate
222  (
223  result,
224  add,
225  lduMesh_.lduAddr(),
226  interfacei,
227  psiif,
228  interfaceCoeffs[interfacei],
229  commsType
230  );
231  }
232  else
233  {
234  interfaces_[interfacei].updateInterfaceMatrix
235  (
236  result,
237  add,
238  lduMesh_.lduAddr(),
239  interfacei,
240  psiif,
241  interfaceCoeffs[interfacei],
242  commsType
243  );
244  }
245  }
246  }
247 
248  // Loop over the "global" patches are on the list of interfaces but
249  // beyond the end of the schedule which only handles "normal" patches
250  for
251  (
252  label interfacei=patchSchedule.size()/2;
253  interfacei<interfaces_.size();
254  interfacei++
255  )
256  {
257  if (interfaces_.set(interfacei))
258  {
259  interfaces_[interfacei].updateInterfaceMatrix
260  (
261  result,
262  add,
263  lduMesh_.lduAddr(),
264  interfacei,
265  psiif,
266  interfaceCoeffs[interfacei],
267  UPstream::commsTypes::blocking
268  );
269  }
270  }
271  }
272  else
273  {
275  << "Unsupported communications type "
276  << UPstream::commsTypeNames[commsType]
277  << exit(FatalError);
278  }
279 }
280 
281 
282 // ************************************************************************* //
void initMatrixInterfaces(const bool add, const FieldField< Field, LUType > &interfaceCoeffs, const Field< Type > &psiif, Field< Type > &result) const
Initialise the update of interfaced interfaces.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
commsTypes
Communications types.
Definition: UPstream.H:72
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:598
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
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
Generic templated field type.
Definition: Field.H:62
void updateMatrixInterfaces(const bool add, const FieldField< Field, LUType > &interfaceCoeffs, const Field< Type > &psiif, Field< Type > &result, const label startRequest) const
Update 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)