parLagrangianRedistributor.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 | Copyright (C) 2015 OpenFOAM Foundation
6  \\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
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 "ListOps.H"
28 #include "passiveParticleCloud.H"
29 
30 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
31 
33 (
34  const fvMesh& srcMesh,
35  const fvMesh& tgtMesh,
36  const label nSrcCells,
37  const mapDistributePolyMesh& distMap
38 )
39 :
40  srcMesh_(srcMesh),
41  tgtMesh_(tgtMesh),
42  distMap_(distMap)
43 {
44  const mapDistribute& cellMap = distMap_.cellMap();
45 
46  // Get destination processors and cells
47  destinationProcID_ = labelList(tgtMesh_.nCells(), Pstream::myProcNo());
48  cellMap.reverseDistribute(nSrcCells, destinationProcID_);
49 
50  destinationCell_ = identity(tgtMesh_.nCells());
51  cellMap.reverseDistribute(nSrcCells, destinationCell_);
52 }
53 
54 
55 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
56 
57 // Find all clouds (on all processors) and for each cloud all the objects.
58 // Result will be synchronised on all processors
60 (
61  const fvMesh& mesh,
62  wordList& cloudNames,
63  List<wordList>& objectNames
64 )
65 {
66  fileNameList localCloudDirs
67  (
68  readDir
69  (
70  mesh.time().timePath()
71  / mesh.dbDir()
72  / cloud::prefix,
73  fileName::DIRECTORY
74  )
75  );
76 
77  cloudNames.setSize(localCloudDirs.size());
78  forAll(localCloudDirs, i)
79  {
80  cloudNames[i] = localCloudDirs[i];
81  }
82 
83  // Synchronise cloud names
84  Pstream::combineGather(cloudNames, ListUniqueEqOp<word>());
85  Pstream::combineScatter(cloudNames);
86 
87  objectNames.setSize(cloudNames.size());
88 
89  forAll(localCloudDirs, i)
90  {
91  // Do local scan for valid cloud objects
92  IOobjectList sprayObjs
93  (
94  mesh,
95  mesh.time().timeName(),
96  cloud::prefix/localCloudDirs[i]
97  );
98 
99  if (sprayObjs.lookup(word("positions")))
100  {
101  // One of the objects is positions so must be valid cloud
102 
103  label cloudI = findIndex(cloudNames, localCloudDirs[i]);
104 
105  objectNames[cloudI].setSize(sprayObjs.size());
106  label objectI = 0;
107  forAllConstIter(IOobjectList, sprayObjs, iter)
108  {
109  const word& name = iter.key();
110  if (name != "positions")
111  {
112  objectNames[cloudI][objectI++] = name;
113  }
114  }
115  objectNames[cloudI].setSize(objectI);
116  }
117  }
118 
119  // Synchronise objectNames
120  forAll(objectNames, cloudI)
121  {
122  Pstream::combineGather(objectNames[cloudI], ListUniqueEqOp<word>());
123  Pstream::combineScatter(objectNames[cloudI]);
124  }
125 }
126 
127 
130 (
132 ) const
133 {
134  //Debug(lpi.size());
135 
136  labelListList subMap;
137 
138 
139  // Allocate transfer buffers
140  PstreamBuffers pBufs(Pstream::nonBlocking);
141 
142  {
143  // List of lists of particles to be transfered for all of the
144  // neighbour processors
145  List<IDLList<passiveParticle> > particleTransferLists
146  (
147  Pstream::nProcs()
148  );
149 
150  // Per particle the destination processor
151  labelList destProc(lpi.size());
152 
153  label particleI = 0;
154  forAllIter(passiveParticleCloud, lpi, iter)
155  {
156  passiveParticle& ppi = iter();
157 
158  label destProcI = destinationProcID_[ppi.cell()];
159  label destCellI = destinationCell_[ppi.cell()];
160 
161  ppi.cell() = destCellI;
162  destProc[particleI++] = destProcI;
163  //Pout<< "Sending particle:" << ppi << " to processor " << destProcI
164  // << " to cell " << destCellI << endl;
165  particleTransferLists[destProcI].append(lpi.remove(&ppi));
166  }
167 
168 
169  // Per processor the indices of the particles to send
170  subMap = invertOneToMany(Pstream::nProcs(), destProc);
171 
172 
173  // Stream into send buffers
174  forAll(particleTransferLists, procI)
175  {
176  //Pout<< "To proc " << procI << " sending "
177  // << particleTransferLists[procI] << endl;
178  if (particleTransferLists[procI].size())
179  {
180  UOPstream particleStream(procI, pBufs);
181  particleStream << particleTransferLists[procI];
182  }
183  }
184  }
185 
186 
187  // Start sending. Sets number of bytes transferred
188  labelListList allNTrans(Pstream::nProcs());
189  pBufs.finishedSends(allNTrans);
190 
191 
192  {
193  // Temporarily rename original cloud so we can construct a new one
194  // (to distribute the positions) without getting a duplicate
195  // registration warning
196  const word cloudName = lpi.name();
197  lpi.rename(cloudName + "_old");
198 
199  // New cloud on tgtMesh
200  passiveParticleCloud lagrangianPositions
201  (
202  tgtMesh_,
203  cloudName,
205  );
206 
207 
208  // Retrieve from receive buffers
209  forAll(allNTrans, procI)
210  {
211  label nRec = allNTrans[procI][Pstream::myProcNo()];
212 
213  //Pout<< "From processor " << procI << " receiving bytes " << nRec
214  // << endl;
215 
216  if (nRec)
217  {
218  UIPstream particleStream(procI, pBufs);
219 
220  IDLList<passiveParticle> newParticles
221  (
222  particleStream,
223  passiveParticle::iNew(tgtMesh_)
224  );
225 
226  forAllIter
227  (
229  newParticles,
230  newpIter
231  )
232  {
233  passiveParticle& newp = newpIter();
234 
235  lagrangianPositions.addParticle(newParticles.remove(&newp));
236  }
237  }
238  }
239 
240 
241  //OFstream::debug = 1;
242  //Debug(lagrangianPositions.size());
243  IOPosition<passiveParticleCloud>(lagrangianPositions).write();
244  //OFstream::debug = 0;
245 
246  // Restore cloud name
247  lpi.rename(cloudName);
248  }
249 
250  // Work the send indices (subMap) into a mapDistributeBase
251  labelListList sizes(Pstream::nProcs());
252  labelList& nsTransPs = sizes[Pstream::myProcNo()];
253  nsTransPs.setSize(Pstream::nProcs());
254  forAll(subMap, sendProcI)
255  {
256  nsTransPs[sendProcI] = subMap[sendProcI].size();
257  }
258  // Send sizes across. Note: blocks.
259  combineReduce(sizes, Pstream::listEq());
260 
261  labelListList constructMap(Pstream::nProcs());
262  label constructSize = 0;
263  forAll(constructMap, procI)
264  {
265  label nRecv = sizes[procI][UPstream::myProcNo()];
266 
267  labelList& map = constructMap[procI];
268 
269  map.setSize(nRecv);
270  forAll(map, i)
271  {
272  map[i] = constructSize++;
273  }
274  }
275 
276 
277  // Construct map
279  (
281  (
282  constructSize,
283  subMap.xfer(),
284  constructMap.xfer()
285  )
286  );
287 }
288 
289 
292 (
293  const word& cloudName
294 ) const
295 {
296  (void)srcMesh_.tetBasePtIs();
297  (void)tgtMesh_.tetBasePtIs();
298 
299  // Temporarily: override master-only checking
300  regIOobject::fileCheckTypes oldCheckType =
301  regIOobject::fileModificationChecking;
302 
303  if (oldCheckType == regIOobject::timeStampMaster)
304  {
305  regIOobject::fileModificationChecking = regIOobject::timeStamp;
306  }
307  else if (oldCheckType == regIOobject::inotifyMaster)
308  {
309  regIOobject::fileModificationChecking = regIOobject::inotify;
310  }
311 
312  // Load cloud and send particle
313  passiveParticleCloud lpi(srcMesh_, cloudName, false);
314 
315  regIOobject::fileModificationChecking = oldCheckType;
316 
317  return redistributeLagrangianPositions(lpi);
318 }
319 
320 
321 // ************************************************************************* //
Foam::Cloud::addParticle
void addParticle(ParticleType *pPtr)
Transfer particle to cloud.
Definition: Cloud.C:162
Foam::IOPosition::write
virtual bool write() const
Definition: IOPosition.C:51
Foam::parLagrangianRedistributor::redistributeLagrangianPositions
autoPtr< mapDistributeBase > redistributeLagrangianPositions(passiveParticleCloud &cloud) const
Redistribute and write lagrangian positions.
Definition: parLagrangianRedistributor.C:130
Foam::word
A class for handling words, derived from string.
Definition: word.H:59
forAllIter
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:431
Foam::UOPstream
Output inter-processor communications stream operating on external buffer.
Definition: UOPstream.H:54
Foam::labelList
List< label > labelList
A List of labels.
Definition: labelList.H:56
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::findIndex
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
Foam::invertOneToMany
labelListList invertOneToMany(const label len, const labelUList &)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:67
Foam::List::xfer
Xfer< List< T > > xfer()
Transfer contents to the Xfer container.
Definition: ListI.H:90
Foam::PstreamBuffers
Buffers for inter-processor communications streams (UOPstream, UIPstream).
Definition: PstreamBuffers.H:85
Foam::passiveParticle
Copy of base particle.
Definition: passiveParticle.H:50
Foam::combineReduce
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
Definition: PstreamCombineReduceOps.H:52
Foam::parLagrangianRedistributor::parLagrangianRedistributor
parLagrangianRedistributor(const parLagrangianRedistributor &)
Disallow default bitwise copy construct.
forAllConstIter
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:39
Foam::particle::cell
label & cell()
Return current cell particle is in.
Definition: particleI.H:598
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::IDLList
Intrusive doubly-linked list.
Definition: IDLList.H:47
Foam::List::append
void append(const T &)
Append an element at the end of the list.
Foam::Cloud::size
label size() const
Definition: Cloud.H:175
parLagrangianRedistributor.H
Foam::mapDistribute
Class containing processor-to-processor mapping information.
Definition: mapDistribute.H:152
Foam::IOPosition
Helper IO class to read and write particle positions.
Definition: Cloud.H:55
Foam::regIOobject::fileCheckTypes
fileCheckTypes
Types of communications.
Definition: regIOobject.H:68
Foam::passiveParticleCloud
A Cloud of passive particles.
Definition: passiveParticleCloud.H:49
Foam::PstreamBuffers::finishedSends
void finishedSends(const bool block=true)
Mark all sends as having been done. This will start receives.
Definition: PstreamBuffers.C:82
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
Foam::IOobjectList::lookup
IOobject * lookup(const word &name) const
Lookup a given name and return IOobject ptr if found else NULL.
Definition: IOobjectList.C:128
Foam::parLagrangianRedistributor::findClouds
static void findClouds(const fvMesh &, wordList &cloudNames, List< wordList > &objectNames)
Find all clouds (on all processors) and for each cloud all.
Definition: parLagrangianRedistributor.C:60
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:78
Foam::IOobjectList
List of IOobjects with searching and retrieving facilities.
Definition: IOobjectList.H:50
Foam::ListUniqueEqOp
Helper class for list to append unique elelements of y onto the end of x.
Definition: ListOps.H:268
Foam::List::setSize
void setSize(const label)
Reset size of List.
Foam::autoPtr
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Definition: PtrList.H:117
Foam::UPstream::listEq
combineReduce operator for lists. Used for counting.
Definition: UPstream.H:160
passiveParticleCloud.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
cloudName
const word cloudName(propsDict.lookup("cloudName"))
Foam::mapDistributeBase
Class containing processor-to-processor mapping information.
Definition: mapDistributeBase.H:91
Foam::mapDistribute::reverseDistribute
void reverseDistribute(const label constructSize, List< T > &, const bool dummyTransform=true, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType.
Definition: mapDistributeTemplates.C:187
ListOps.H
Various functions to operate on Lists.
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::UIPstream
Input inter-processor communications stream operating on external buffer.
Definition: UIPstream.H:53
Foam::readDir
fileNameList readDir(const fileName &, const fileName::Type=fileName::FILE, const bool filtergz=true)
Read a directory and return the entries as a string list.
Definition: POSIX.C:660
Foam::mapDistributePolyMesh
Class containing mesh-to-mesh mapping information after a mesh distribution where we send parts of me...
Definition: mapDistributePolyMesh.H:57
Foam::passiveParticle::iNew
Factory class to read-construct particles used for.
Definition: passiveParticle.H:111
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47