FreeFOAM The Cross-Platform CFD Toolkit
syncTools.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) 1991-2010 OpenCFD Ltd.
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 "syncTools.H"
27 #include <OpenFOAM/polyMesh.H>
28 
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
30 
31 // Does anyone have couples? Since meshes might have 0 cells and 0 proc
32 // boundaries need to reduce this info.
33 bool Foam::syncTools::hasCouples(const polyBoundaryMesh& patches)
34 {
35  bool hasAnyCouples = false;
36 
37  forAll(patches, patchI)
38  {
39  if (patches[patchI].coupled())
40  {
41  hasAnyCouples = true;
42  break;
43  }
44  }
45  return returnReduce(hasAnyCouples, orOp<bool>());
46 }
47 
48 
49 void Foam::syncTools::checkTransform
50 (
51  const coupledPolyPatch& pp,
52  const bool applySeparation
53 )
54 {
55  if (!pp.parallel() && pp.forwardT().size() > 1)
56  {
57  FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
58  << "Non-uniform transformation not supported for point or edge"
59  << " fields." << endl
60  << "Patch:" << pp.name()
61  << abort(FatalError);
62  }
63  if (applySeparation && pp.separated() && pp.separation().size() > 1)
64  {
65  FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
66  << "Non-uniform separation vector not supported for point or edge"
67  << " fields." << endl
68  << "Patch:" << pp.name()
69  << abort(FatalError);
70  }
71 }
72 
73 
74 // Determines for every point whether it is coupled and if so sets only one.
76 {
77  PackedBoolList isMasterPoint(mesh.nPoints(), 0);
78  PackedBoolList donePoint(mesh.nPoints(), 0);
79 
80 
81  // Do multiple shared points. Min. proc is master
82  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83 
84  const labelList& sharedPointAddr =
85  mesh.globalData().sharedPointAddr();
86 
87  labelList minProc(mesh.globalData().nGlobalPoints(), labelMax);
88 
89  UIndirectList<label>(minProc, sharedPointAddr) = Pstream::myProcNo();
90 
93 
94  const labelList& sharedPointLabels =
96 
97  forAll(sharedPointAddr, i)
98  {
99  if (minProc[sharedPointAddr[i]] == Pstream::myProcNo())
100  {
101  isMasterPoint.set(sharedPointLabels[i], 1u);
102  }
103  donePoint.set(sharedPointLabels[i], 1u);
104  }
105 
106 
107  // Do other points on coupled patches
108  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
109 
110  const polyBoundaryMesh& patches = mesh.boundaryMesh();
111 
112  forAll(patches, patchI)
113  {
114  if (patches[patchI].coupled())
115  {
116  if
117  (
119  && isA<processorPolyPatch>(patches[patchI])
120  )
121  {
122  const processorPolyPatch& pp =
123  refCast<const processorPolyPatch>(patches[patchI]);
124 
125  const labelList& meshPoints = pp.meshPoints();
126 
127  forAll(meshPoints, i)
128  {
129  label pointI = meshPoints[i];
130 
131  if (donePoint.get(pointI) == 0u)
132  {
133  donePoint.set(pointI, 1u);
134 
135  if (pp.owner())
136  {
137  isMasterPoint.set(pointI, 1u);
138  }
139  }
140  }
141  }
142  else if (isA<cyclicPolyPatch>(patches[patchI]))
143  {
144  const cyclicPolyPatch& pp =
145  refCast<const cyclicPolyPatch>(patches[patchI]);
146 
147  const edgeList& coupledPoints = pp.coupledPoints();
148  const labelList& meshPoints = pp.meshPoints();
149 
150  forAll(coupledPoints, i)
151  {
152  // First one of couple points is master
153 
154  const edge& pointPair = coupledPoints[i];
155  label p0 = meshPoints[pointPair[0]];
156  label p1 = meshPoints[pointPair[1]];
157 
158  if (donePoint.get(p0) == 0u)
159  {
160  donePoint.set(p0, 1u);
161  isMasterPoint.set(p0, 1u);
162  donePoint.set(p1, 1u);
163  }
164  }
165  }
166  else
167  {
168  FatalErrorIn("syncTools::getMasterPoints(const polyMesh&)")
169  << "Cannot handle coupled patch " << patches[patchI].name()
170  << " of type " << patches[patchI].type()
171  << abort(FatalError);
172  }
173  }
174  }
175 
176 
177  // Do all other points
178  // ~~~~~~~~~~~~~~~~~~~
179 
180  forAll(donePoint, pointI)
181  {
182  if (donePoint.get(pointI) == 0u)
183  {
184  donePoint.set(pointI, 1u);
185  isMasterPoint.set(pointI, 1u);
186  }
187  }
188 
189  return isMasterPoint;
190 }
191 
192 
193 // Determines for every edge whether it is coupled and if so sets only one.
195 {
196  PackedBoolList isMasterEdge(mesh.nEdges(), 0);
197  PackedBoolList doneEdge(mesh.nEdges(), 0);
198 
199 
200  // Do multiple shared edges. Min. proc is master
201  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
202 
203  const labelList& sharedEdgeAddr =
204  mesh.globalData().sharedEdgeAddr();
205 
206  labelList minProc(mesh.globalData().nGlobalEdges(), labelMax);
207 
208  UIndirectList<label>(minProc, sharedEdgeAddr) = Pstream::myProcNo();
209 
212 
213  const labelList& sharedEdgeLabels =
214  mesh.globalData().sharedEdgeLabels();
215 
216  forAll(sharedEdgeAddr, i)
217  {
218  if (minProc[sharedEdgeAddr[i]] == Pstream::myProcNo())
219  {
220  isMasterEdge.set(sharedEdgeLabels[i], 1u);
221  }
222  doneEdge.set(sharedEdgeLabels[i], 1u);
223  }
224 
225 
226  // Do other edges on coupled patches
227  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
228 
229  const polyBoundaryMesh& patches = mesh.boundaryMesh();
230 
231  forAll(patches, patchI)
232  {
233  if (patches[patchI].coupled())
234  {
235  if
236  (
238  && isA<processorPolyPatch>(patches[patchI])
239  )
240  {
241  const processorPolyPatch& pp =
242  refCast<const processorPolyPatch>(patches[patchI]);
243 
244  const labelList& meshEdges = pp.meshEdges();
245 
246  forAll(meshEdges, i)
247  {
248  label edgeI = meshEdges[i];
249 
250  if (doneEdge.get(edgeI) == 0u)
251  {
252  doneEdge.set(edgeI, 1u);
253 
254  if (pp.owner())
255  {
256  isMasterEdge.set(edgeI, 1u);
257  }
258  }
259  }
260  }
261  else if (isA<cyclicPolyPatch>(patches[patchI]))
262  {
263  const cyclicPolyPatch& pp =
264  refCast<const cyclicPolyPatch>(patches[patchI]);
265 
266  const edgeList& coupledEdges = pp.coupledEdges();
267  const labelList& meshEdges = pp.meshEdges();
268 
269  forAll(coupledEdges, i)
270  {
271  // First one of couple edges is master
272 
273  const edge& edgePair = coupledEdges[i];
274  label e0 = meshEdges[edgePair[0]];
275  label e1 = meshEdges[edgePair[1]];
276 
277  if (doneEdge.get(e0) == 0u)
278  {
279  doneEdge.set(e0, 1u);
280  isMasterEdge.set(e0, 1u);
281  doneEdge.set(e1, 1u);
282  }
283  }
284  }
285  else
286  {
287  FatalErrorIn("syncTools::getMasterEdges(const polyMesh&)")
288  << "Cannot handle coupled patch " << patches[patchI].name()
289  << " of type " << patches[patchI].type()
290  << abort(FatalError);
291  }
292  }
293  }
294 
295 
296  // Do all other edges
297  // ~~~~~~~~~~~~~~~~~~
298 
299  forAll(doneEdge, edgeI)
300  {
301  if (doneEdge.get(edgeI) == 0u)
302  {
303  doneEdge.set(edgeI, 1u);
304  isMasterEdge.set(edgeI, 1u);
305  }
306  }
307 
308  return isMasterEdge;
309 }
310 
311 
312 // Determines for every face whether it is coupled and if so sets only one.
314 {
315  PackedBoolList isMasterFace(mesh.nFaces(), 1);
316 
317  const polyBoundaryMesh& patches = mesh.boundaryMesh();
318 
319  forAll(patches, patchI)
320  {
321  if (patches[patchI].coupled())
322  {
323  if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI]))
324  {
325  const processorPolyPatch& pp =
326  refCast<const processorPolyPatch>(patches[patchI]);
327 
328  if (!pp.owner())
329  {
330  forAll(pp, i)
331  {
332  isMasterFace.set(pp.start()+i, 0);
333  }
334  }
335  }
336  else if (isA<cyclicPolyPatch>(patches[patchI]))
337  {
338  const cyclicPolyPatch& pp =
339  refCast<const cyclicPolyPatch>(patches[patchI]);
340 
341  for (label i = pp.size()/2; i < pp.size(); i++)
342  {
343  isMasterFace.set(pp.start()+i, 0);
344  }
345  }
346  else
347  {
348  FatalErrorIn("syncTools::getMasterFaces(const polyMesh&)")
349  << "Cannot handle coupled patch " << patches[patchI].name()
350  << " of type " << patches[patchI].type()
351  << abort(FatalError);
352  }
353  }
354  }
355 
356  return isMasterFace;
357 }
358 
359 
360 template <>
361 void Foam::syncTools::separateList
362 (
363  const vectorField& separation,
364  UList<vector>& field
365 )
366 {
367  if (separation.size() == 1)
368  {
369  // Single value for all.
370 
371  forAll(field, i)
372  {
373  field[i] += separation[0];
374  }
375  }
376  else if (separation.size() == field.size())
377  {
378  forAll(field, i)
379  {
380  field[i] += separation[i];
381  }
382  }
383  else
384  {
386  (
387  "syncTools::separateList(const vectorField&, UList<vector>&)"
388  ) << "Sizes of field and transformation not equal. field:"
389  << field.size() << " transformation:" << separation.size()
390  << abort(FatalError);
391  }
392 }
393 
394 
395 template <>
396 void Foam::syncTools::separateList
397 (
398  const vectorField& separation,
399  Map<vector>& field
400 )
401 {
402  if (separation.size() == 1)
403  {
404  // Single value for all.
405  forAllIter(Map<vector>, field, iter)
406  {
407  iter() += separation[0];
408  }
409  }
410  else if (separation.size() == field.size())
411  {
412  forAllIter(Map<vector>, field, iter)
413  {
414  iter() += separation[iter.key()];
415  }
416  }
417  else
418  {
420  (
421  "syncTools::separateList(const vectorField&, Map<vector>&)"
422  ) << "Sizes of field and transformation not equal. field:"
423  << field.size() << " transformation:" << separation.size()
424  << abort(FatalError);
425  }
426 }
427 
428 
429 template <>
430 void Foam::syncTools::separateList
431 (
432  const vectorField& separation,
433  EdgeMap<vector>& field
434 )
435 {
436  if (separation.size() == 1)
437  {
438  // Single value for all.
439  forAllIter(EdgeMap<vector>, field, iter)
440  {
441  iter() += separation[0];
442  }
443  }
444  else
445  {
447  (
448  "syncTools::separateList(const vectorField&, EdgeMap<vector>&)"
449  ) << "Multiple separation vectors not supported. field:"
450  << field.size() << " transformation:" << separation.size()
451  << abort(FatalError);
452  }
453 }
454 
455 
456 // ************************ vim: set sw=4 sts=4 et: ************************ //