globalIndexTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2013-2018 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 "globalIndex.H"
27 
28 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
29 
30 template<class Type>
32 (
33  const labelUList& off,
34  const label comm,
35  const labelList& procIDs,
36  const UList<Type>& fld,
37  List<Type>& allFld,
38  const int tag,
39  const Pstream::commsTypes commsType
40 )
41 {
42  if (Pstream::myProcNo(comm) == procIDs[0])
43  {
44  allFld.setSize(off.last());
45 
46  // Assign my local data
47  SubList<Type>(allFld, fld.size(), 0) = fld;
48 
49  if
50  (
51  commsType == Pstream::commsTypes::scheduled
52  || commsType == Pstream::commsTypes::blocking
53  )
54  {
55  for (label i = 1; i < procIDs.size(); i++)
56  {
57  SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
58 
59  if (contiguous<Type>())
60  {
62  (
63  commsType,
64  procIDs[i],
65  reinterpret_cast<char*>(procSlot.begin()),
66  procSlot.byteSize(),
67  tag,
68  comm
69  );
70  }
71  else
72  {
73  IPstream fromSlave
74  (
75  commsType,
76  procIDs[i],
77  0,
78  tag,
79  comm
80  );
81  fromSlave >> procSlot;
82  }
83  }
84  }
85  else
86  {
87  // nonBlocking
88 
89  if (!contiguous<Type>())
90  {
92  << "nonBlocking not supported for non-contiguous data"
93  << exit(FatalError);
94  }
95 
96  label startOfRequests = Pstream::nRequests();
97 
98  // Set up reads
99  for (label i = 1; i < procIDs.size(); i++)
100  {
101  SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
102 
104  (
105  commsType,
106  procIDs[i],
107  reinterpret_cast<char*>(procSlot.begin()),
108  procSlot.byteSize(),
109  tag,
110  comm
111  );
112  }
113 
114  // Wait for all to finish
115  Pstream::waitRequests(startOfRequests);
116  }
117  }
118  else
119  {
120  if
121  (
122  commsType == Pstream::commsTypes::scheduled
123  || commsType == Pstream::commsTypes::blocking
124  )
125  {
126  if (contiguous<Type>())
127  {
129  (
130  commsType,
131  procIDs[0],
132  reinterpret_cast<const char*>(fld.begin()),
133  fld.byteSize(),
134  tag,
135  comm
136  );
137  }
138  else
139  {
140  OPstream toMaster
141  (
142  commsType,
143  procIDs[0],
144  0,
145  tag,
146  comm
147  );
148  toMaster << fld;
149  }
150  }
151  else
152  {
153  // nonBlocking
154 
155  if (!contiguous<Type>())
156  {
158  << "nonBlocking not supported for non-contiguous data"
159  << exit(FatalError);
160  }
161 
162  label startOfRequests = Pstream::nRequests();
163 
164  // Set up write
166  (
167  commsType,
168  procIDs[0],
169  reinterpret_cast<const char*>(fld.begin()),
170  fld.byteSize(),
171  tag,
172  comm
173  );
174 
175  // Wait for all to finish
176  Pstream::waitRequests(startOfRequests);
177  }
178  }
179 }
180 
181 
182 template<class Type>
184 (
185  const labelUList& off,
186  const label comm,
187  const labelList& procIDs,
188  List<Type>& fld,
189  const int tag,
190  const Pstream::commsTypes commsType
191 )
192 {
193  List<Type> allFld;
194 
195  gather(off, comm, procIDs, fld, allFld, tag, commsType);
196 
197  if (Pstream::myProcNo(comm) == procIDs[0])
198  {
199  fld.transfer(allFld);
200  }
201 }
202 
203 
204 template<class Type>
206 (
207  const labelUList& off,
208  const label comm,
209  const labelList& procIDs,
210  const UList<Type>& allFld,
211  UList<Type>& fld,
212  const int tag,
213  const Pstream::commsTypes commsType
214 )
215 {
216  if (Pstream::myProcNo(comm) == procIDs[0])
217  {
218  fld.deepCopy(SubList<Type>(allFld, off[1]-off[0]));
219 
220  if
221  (
222  commsType == Pstream::commsTypes::scheduled
223  || commsType == Pstream::commsTypes::blocking
224  )
225  {
226  for (label i = 1; i < procIDs.size(); i++)
227  {
228  const SubList<Type> procSlot
229  (
230  allFld,
231  off[i+1]-off[i],
232  off[i]
233  );
234 
235  if (contiguous<Type>())
236  {
238  (
239  commsType,
240  procIDs[i],
241  reinterpret_cast<const char*>(procSlot.begin()),
242  procSlot.byteSize(),
243  tag,
244  comm
245  );
246  }
247  else
248  {
249  OPstream toSlave
250  (
251  commsType,
252  procIDs[i],
253  0,
254  tag,
255  comm
256  );
257  toSlave << procSlot;
258  }
259  }
260  }
261  else
262  {
263  // nonBlocking
264 
265  if (!contiguous<Type>())
266  {
268  << "nonBlocking not supported for non-contiguous data"
269  << exit(FatalError);
270  }
271 
272  label startOfRequests = Pstream::nRequests();
273 
274  // Set up writes
275  for (label i = 1; i < procIDs.size(); i++)
276  {
277  const SubList<Type> procSlot
278  (
279  allFld,
280  off[i+1]-off[i],
281  off[i]
282  );
283 
285  (
286  commsType,
287  procIDs[i],
288  reinterpret_cast<const char*>(procSlot.begin()),
289  procSlot.byteSize(),
290  tag,
291  comm
292  );
293  }
294 
295  // Wait for all to finish
296  Pstream::waitRequests(startOfRequests);
297  }
298  }
299  else
300  {
301  if
302  (
303  commsType == Pstream::commsTypes::scheduled
304  || commsType == Pstream::commsTypes::blocking
305  )
306  {
307  if (contiguous<Type>())
308  {
310  (
311  commsType,
312  procIDs[0],
313  reinterpret_cast<char*>(fld.begin()),
314  fld.byteSize(),
315  tag,
316  comm
317  );
318  }
319  else
320  {
321  IPstream fromMaster
322  (
323  commsType,
324  procIDs[0],
325  0,
326  tag,
327  comm
328  );
329  fromMaster >> fld;
330  }
331  }
332  else
333  {
334  // nonBlocking
335 
336  if (!contiguous<Type>())
337  {
339  << "nonBlocking not supported for non-contiguous data"
340  << exit(FatalError);
341  }
342 
343  label startOfRequests = Pstream::nRequests();
344 
345  // Set up read
347  (
348  commsType,
349  procIDs[0],
350  reinterpret_cast<char*>(fld.begin()),
351  fld.byteSize(),
352  tag,
353  comm
354  );
355 
356  // Wait for all to finish
357  Pstream::waitRequests(startOfRequests);
358  }
359  }
360 }
361 
362 
363 // ************************************************************************* //
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
static void gather(const labelUList &offsets, const label comm, const labelList &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
commsTypes
Types of communications.
Definition: UPstream.H:64
static void scatter(const labelUList &offsets, const label comm, const labelList &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Distribute data in processor order. Requires fld to be sized!
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void read(Istream &, label &, const dictionary &)
In-place read with dictionary lookup.
void deepCopy(const UList< T > &)
Copy elements of the given UList.
Definition: UList.C:35
Input inter-processor communications stream.
Definition: IPstream.H:50
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().x()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().y()<< ' ';}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){ gmvFile<< iter().position().z()<< ' ';}gmvFile<< nl;forAll(lagrangianScalarNames, i){ const word &name=lagrangianScalarNames[i];IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
iterator begin()
Return an iterator to begin traversing the UList.
Definition: UListI.H:216
void write(std::ostream &os, const bool binary, List< floatScalar > &fField)
Write floats ascii or binary.
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
Output inter-processor communications stream.
Definition: OPstream.H:50
void setSize(const label)
Reset size of List.
Definition: List.C:281
std::streamsize byteSize() const
Return the binary size in number of characters of the UList.
Definition: UList.C:100
T & last()
Return the last element of the list.
Definition: UListI.H:128
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342