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"
27 #include "parLagrangianRedistributor.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,
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 (
131  passiveParticleCloud& lpi
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  (
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,
204  IDLList<passiveParticle>()
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  (
228  IDLList<passiveParticle>,
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
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
278  return autoPtr<mapDistributeBase>
279  (
280  new mapDistributeBase
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 =
302 
303  if (oldCheckType == regIOobject::timeStampMaster)
304  {
306  }
307  else if (oldCheckType == regIOobject::inotifyMaster)
308  {
310  }
311 
312  // Load cloud and send particle
313  passiveParticleCloud lpi(srcMesh_, cloudName, false);
314 
316 
317  return redistributeLagrangianPositions(lpi);
318 }
319 
320 
321 // ************************************************************************* //
Foam::parLagrangianRedistributor::redistributeLagrangianPositions
autoPtr< mapDistributeBase > redistributeLagrangianPositions(passiveParticleCloud &cloud) const
Redistribute and write lagrangian positions.
Definition: parLagrangianRedistributor.C:130
forAllIter
#define forAllIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:431
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::polyMesh::dbDir
virtual const fileName & dbDir() const
Override the objectRegistry dbDir for a single-region case.
Definition: polyMesh.C:753
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:387
Foam::regIOobject::inotify
@ inotify
Definition: regIOobject.H:72
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::mapDistributePolyMesh::cellMap
const mapDistribute & cellMap() const
Cell distribute map.
Definition: mapDistributePolyMesh.H:214
Foam::wordList
List< word > wordList
A List of words.
Definition: fileName.H:54
Foam::regIOobject::timeStamp
@ timeStamp
Definition: regIOobject.H:70
Foam::UPstream::nonBlocking
@ nonBlocking
Definition: UPstream.H:68
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::Time::timePath
fileName timePath() const
Return current time path.
Definition: Time.H:297
Foam::regIOobject::fileCheckTypes
fileCheckTypes
Types of communications.
Definition: regIOobject.H:68
Foam::identity
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
Definition: ListOps.C:104
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::Pstream::combineGather
static void combineGather(const List< commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
Definition: combineGatherScatter.C:50
Foam::parFvFieldReconstructor::distMap_
const mapDistributePolyMesh & distMap_
Distribution map reference.
Definition: parFvFieldReconstructor.H:68
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:405
Foam::fileNameList
List< fileName > fileNameList
A List of fileNames.
Definition: fileNameList.H:50
Foam::cloud::prefix
static const word prefix
The prefix to local: lagrangian.
Definition: cloud.H:71
Foam::regIOobject::fileModificationChecking
static fileCheckTypes fileModificationChecking
Definition: regIOobject.H:128
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::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
Foam::regIOobject::inotifyMaster
@ inotifyMaster
Definition: regIOobject.H:73
passiveParticleCloud.H
Foam::Time::timeName
static word timeName(const scalar, const int precision=precision_)
Return time name of given scalar time.
Definition: Time.C:741
Foam::fileName::DIRECTORY
@ DIRECTORY
Definition: fileName.H:86
cloudName
const word cloudName(propsDict.lookup("cloudName"))
Foam::fvMesh::time
const Time & time() const
Return the top-level database.
Definition: fvMesh.H:243
List
Definition: Test.C:19
ListOps.H
Various functions to operate on Lists.
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::Pstream::combineScatter
static void combineScatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Reverse of combineGather.
Definition: combineGatherScatter.C:178
Foam::name
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
Foam::regIOobject::timeStampMaster
@ timeStampMaster
Definition: regIOobject.H:71