ProcessorTopology.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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "ProcessorTopology.H"
29 #include "ListOps.H"
30 #include "Pstream.H"
31 #include "commSchedule.H"
32 #include "boolList.H"
33 
34 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
35 
36 template<class Container, class ProcPatch>
38 (
39  const label nProcs,
40  const Container& patches
41 )
42 {
43  // Determine number of processor neighbours and max neighbour id.
44 
45  label nNeighbours = 0;
46 
47  label maxNb = 0;
48 
49  boolList isNeighbourProc(nProcs, false);
50 
51  forAll(patches, patchi)
52  {
53  const typename Container::const_reference patch = patches[patchi];
54 
55  if (isA<ProcPatch>(patch))
56  {
57  const ProcPatch& procPatch =
58  refCast<const ProcPatch>(patch);
59 
60  label pNeighbProcNo = procPatch.neighbProcNo();
61 
62  if (!isNeighbourProc[pNeighbProcNo])
63  {
64  nNeighbours++;
65 
66  maxNb = max(maxNb, procPatch.neighbProcNo());
67 
68  isNeighbourProc[pNeighbProcNo] = true;
69  }
70  }
71  }
72 
73  labelList neighbours(nNeighbours, -1);
74 
75  nNeighbours = 0;
76 
77  forAll(isNeighbourProc, proci)
78  {
79  if (isNeighbourProc[proci])
80  {
81  neighbours[nNeighbours++] = proci;
82  }
83  }
84 
85  procPatchMap_.setSize(maxNb + 1);
86  procPatchMap_ = -1;
87 
88  forAll(patches, patchi)
89  {
90  const typename Container::const_reference patch = patches[patchi];
91 
92  if (isA<ProcPatch>(patch))
93  {
94  const ProcPatch& procPatch =
95  refCast<const ProcPatch>(patch);
96 
97  // Construct reverse map
98  procPatchMap_[procPatch.neighbProcNo()] = patchi;
99  }
100  }
101 
102  return neighbours;
103 }
104 
105 
106 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
107 
108 template<class Container, class ProcPatch>
110 (
111  const Container& patches,
112  const label comm
113 )
114 :
115  labelListList(Pstream::nProcs(comm)),
116  patchSchedule_(2*patches.size())
117 {
118  if (Pstream::parRun())
119  {
120  // Fill my 'slot' with my neighbours
121  operator[](Pstream::myProcNo(comm)) =
122  procNeighbours(this->size(), patches);
123 
124  // Distribute to all processors
125  Pstream::gatherList(*this, Pstream::msgType(), comm);
126  Pstream::scatterList(*this, Pstream::msgType(), comm);
127  }
128 
129  if
130  (
131  Pstream::parRun()
132  && Pstream::defaultCommsType == Pstream::commsTypes::scheduled
133  )
134  {
135  label patchEvali = 0;
136 
137  // 1. All non-processor patches
138  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139 
140  forAll(patches, patchi)
141  {
142  if (!isA<ProcPatch>(patches[patchi]))
143  {
144  patchSchedule_[patchEvali].patch = patchi;
145  patchSchedule_[patchEvali++].init = true;
146  patchSchedule_[patchEvali].patch = patchi;
147  patchSchedule_[patchEvali++].init = false;
148  }
149  }
150 
151  // 2. All processor patches
152  // ~~~~~~~~~~~~~~~~~~~~~~~~
153 
154  // Determine the schedule for all. Insert processor pair once
155  // to determine the schedule. Each processor pair stands for both
156  // send and receive.
157  label nComms = 0;
158  forAll(*this, proci)
159  {
160  nComms += operator[](proci).size();
161  }
162  DynamicList<labelPair> comms(nComms);
163 
164  forAll(*this, proci)
165  {
166  const labelList& nbrs = operator[](proci);
167 
168  forAll(nbrs, i)
169  {
170  if (proci < nbrs[i])
171  {
172  comms.append(labelPair(proci, nbrs[i]));
173  }
174  }
175  }
176  comms.shrink();
177 
178  // Determine a schedule.
179  labelList mySchedule
180  (
182  (
183  Pstream::nProcs(comm),
184  comms
185  ).procSchedule()[Pstream::myProcNo(comm)]
186  );
187 
188  forAll(mySchedule, iter)
189  {
190  label commI = mySchedule[iter];
191 
192  // Get the other processor
193  label nb = comms[commI][0];
194  if (nb == Pstream::myProcNo(comm))
195  {
196  nb = comms[commI][1];
197  }
198  label patchi = procPatchMap_[nb];
199 
200  if (Pstream::myProcNo(comm) > nb)
201  {
202  patchSchedule_[patchEvali].patch = patchi;
203  patchSchedule_[patchEvali++].init = true;
204  patchSchedule_[patchEvali].patch = patchi;
205  patchSchedule_[patchEvali++].init = false;
206  }
207  else
208  {
209  patchSchedule_[patchEvali].patch = patchi;
210  patchSchedule_[patchEvali++].init = false;
211  patchSchedule_[patchEvali].patch = patchi;
212  patchSchedule_[patchEvali++].init = true;
213  }
214  }
215  }
216  else
217  {
218  patchSchedule_ = nonBlockingSchedule(patches);
219  }
220 }
221 
222 
223 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
224 
225 template<class Container, class ProcPatch>
228 (
229  const Container& patches
230 )
231 {
232  lduSchedule patchSchedule(2*patches.size());
233 
234  label patchEvali = 0;
235 
236  // 1. All non-processor patches
237  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238 
239  // Have evaluate directly after initEvaluate. Could have them separated
240  // as long as they're not intermingled with processor patches since
241  // then e.g. any reduce parallel traffic would interfere with the
242  // processor swaps.
243 
244  forAll(patches, patchi)
245  {
246  if (!isA<ProcPatch>(patches[patchi]))
247  {
248  patchSchedule[patchEvali].patch = patchi;
249  patchSchedule[patchEvali++].init = true;
250  patchSchedule[patchEvali].patch = patchi;
251  patchSchedule[patchEvali++].init = false;
252  }
253  }
254 
255  // 2. All processor patches
256  // ~~~~~~~~~~~~~~~~~~~~~~~~
257 
258  // 2a. initEvaluate
259  forAll(patches, patchi)
260  {
261  if (isA<ProcPatch>(patches[patchi]))
262  {
263  patchSchedule[patchEvali].patch = patchi;
264  patchSchedule[patchEvali++].init = true;
265  }
266  }
267 
268  // 2b. evaluate
269  forAll(patches, patchi)
270  {
271  if (isA<ProcPatch>(patches[patchi]))
272  {
273  patchSchedule[patchEvali].patch = patchi;
274  patchSchedule[patchEvali++].init = false;
275  }
276  }
277 
278  return patchSchedule;
279 }
280 
281 
282 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:71
boolList.H
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::ProcessorTopology::nonBlockingSchedule
static lduSchedule nonBlockingSchedule(const Container &patches)
Calculate non-blocking (i.e. unscheduled) schedule.
Definition: ProcessorTopology.C:228
Foam::boolList
List< bool > boolList
A List of bools.
Definition: List.H:69
Foam::commSchedule
Determines the order in which a set of processors should communicate with one another.
Definition: commSchedule.H:67
Foam::DynamicList::shrink
DynamicList< T, SizeMin > & shrink()
Shrink the allocated space to the number of elements used.
Definition: DynamicListI.H:376
Foam::ProcessorTopology::ProcessorTopology
ProcessorTopology(const Container &patches, const label comm)
Construct from boundaryMesh.
Definition: ProcessorTopology.C:110
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::labelPair
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:54
commSchedule.H
ProcessorTopology.H
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:472
Foam::ProcessorTopology
Determines processor-processor connection. After instantiation contains on all processors the process...
Definition: ProcessorTopology.H:58
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Pstream.H
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
Foam::foamVersion::patch
const std::string patch
OpenFOAM patch number as a std::string.
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:102
patches
const polyBoundaryMesh & patches
Definition: convertProcessorPatches.H:65
ListOps.H
Various functions to operate on Lists.