1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "syncTools.H"
29 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
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)
35 bool hasAnyCouples = false;
37 forAll(patches, patchI)
39 if (patches[patchI].coupled())
45 return returnReduce(hasAnyCouples, orOp<bool>());
49 void Foam::syncTools::checkTransform
51 const coupledPolyPatch& pp,
52 const bool applySeparation
55 if (!pp.parallel() && pp.forwardT().size() > 1)
57 FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
58 << "Non-uniform transformation not supported for point or edge"
60 << "Patch:" << pp.name()
63 if (applySeparation && pp.separated() && pp.separation().size() > 1)
65 FatalErrorIn("syncTools::checkTransform(const coupledPolyPatch&)")
66 << "Non-uniform separation vector not supported for point or edge"
68 << "Patch:" << pp.name()
74 // Determines for every point whether it is coupled and if so sets only one.
75 Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
77 PackedBoolList isMasterPoint(mesh.nPoints(), 0);
78 PackedBoolList donePoint(mesh.nPoints(), 0);
81 // Do multiple shared points. Min. proc is master
82 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84 const labelList& sharedPointAddr =
85 mesh.globalData().sharedPointAddr();
87 labelList minProc(mesh.globalData().nGlobalPoints(), labelMax);
89 UIndirectList<label>(minProc, sharedPointAddr) = Pstream::myProcNo();
91 Pstream::listCombineGather(minProc, minEqOp<label>());
92 Pstream::listCombineScatter(minProc);
94 const labelList& sharedPointLabels =
95 mesh.globalData().sharedPointLabels();
97 forAll(sharedPointAddr, i)
99 if (minProc[sharedPointAddr[i]] == Pstream::myProcNo())
101 isMasterPoint.set(sharedPointLabels[i], 1u);
103 donePoint.set(sharedPointLabels[i], 1u);
107 // Do other points on coupled patches
108 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110 const polyBoundaryMesh& patches = mesh.boundaryMesh();
112 forAll(patches, patchI)
114 if (patches[patchI].coupled())
119 && isA<processorPolyPatch>(patches[patchI])
122 const processorPolyPatch& pp =
123 refCast<const processorPolyPatch>(patches[patchI]);
125 const labelList& meshPoints = pp.meshPoints();
127 forAll(meshPoints, i)
129 label pointI = meshPoints[i];
131 if (donePoint.get(pointI) == 0u)
133 donePoint.set(pointI, 1u);
137 isMasterPoint.set(pointI, 1u);
142 else if (isA<cyclicPolyPatch>(patches[patchI]))
144 const cyclicPolyPatch& pp =
145 refCast<const cyclicPolyPatch>(patches[patchI]);
147 const edgeList& coupledPoints = pp.coupledPoints();
148 const labelList& meshPoints = pp.meshPoints();
150 forAll(coupledPoints, i)
152 // First one of couple points is master
154 const edge& pointPair = coupledPoints[i];
155 label p0 = meshPoints[pointPair[0]];
156 label p1 = meshPoints[pointPair[1]];
158 if (donePoint.get(p0) == 0u)
160 donePoint.set(p0, 1u);
161 isMasterPoint.set(p0, 1u);
162 donePoint.set(p1, 1u);
168 FatalErrorIn("syncTools::getMasterPoints(const polyMesh&)")
169 << "Cannot handle coupled patch " << patches[patchI].name()
170 << " of type " << patches[patchI].type()
171 << abort(FatalError);
177 // Do all other points
178 // ~~~~~~~~~~~~~~~~~~~
180 forAll(donePoint, pointI)
182 if (donePoint.get(pointI) == 0u)
184 donePoint.set(pointI, 1u);
185 isMasterPoint.set(pointI, 1u);
189 return isMasterPoint;
193 // Determines for every edge whether it is coupled and if so sets only one.
194 Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
196 PackedBoolList isMasterEdge(mesh.nEdges(), 0);
197 PackedBoolList doneEdge(mesh.nEdges(), 0);
200 // Do multiple shared edges. Min. proc is master
201 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203 const labelList& sharedEdgeAddr =
204 mesh.globalData().sharedEdgeAddr();
206 labelList minProc(mesh.globalData().nGlobalEdges(), labelMax);
208 UIndirectList<label>(minProc, sharedEdgeAddr) = Pstream::myProcNo();
210 Pstream::listCombineGather(minProc, minEqOp<label>());
211 Pstream::listCombineScatter(minProc);
213 const labelList& sharedEdgeLabels =
214 mesh.globalData().sharedEdgeLabels();
216 forAll(sharedEdgeAddr, i)
218 if (minProc[sharedEdgeAddr[i]] == Pstream::myProcNo())
220 isMasterEdge.set(sharedEdgeLabels[i], 1u);
222 doneEdge.set(sharedEdgeLabels[i], 1u);
226 // Do other edges on coupled patches
227 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229 const polyBoundaryMesh& patches = mesh.boundaryMesh();
231 forAll(patches, patchI)
233 if (patches[patchI].coupled())
238 && isA<processorPolyPatch>(patches[patchI])
241 const processorPolyPatch& pp =
242 refCast<const processorPolyPatch>(patches[patchI]);
244 const labelList& meshEdges = pp.meshEdges();
248 label edgeI = meshEdges[i];
250 if (doneEdge.get(edgeI) == 0u)
252 doneEdge.set(edgeI, 1u);
256 isMasterEdge.set(edgeI, 1u);
261 else if (isA<cyclicPolyPatch>(patches[patchI]))
263 const cyclicPolyPatch& pp =
264 refCast<const cyclicPolyPatch>(patches[patchI]);
266 const edgeList& coupledEdges = pp.coupledEdges();
267 const labelList& meshEdges = pp.meshEdges();
269 forAll(coupledEdges, i)
271 // First one of couple edges is master
273 const edge& edgePair = coupledEdges[i];
274 label e0 = meshEdges[edgePair[0]];
275 label e1 = meshEdges[edgePair[1]];
277 if (doneEdge.get(e0) == 0u)
279 doneEdge.set(e0, 1u);
280 isMasterEdge.set(e0, 1u);
281 doneEdge.set(e1, 1u);
287 FatalErrorIn("syncTools::getMasterEdges(const polyMesh&)")
288 << "Cannot handle coupled patch " << patches[patchI].name()
289 << " of type " << patches[patchI].type()
290 << abort(FatalError);
296 // Do all other edges
297 // ~~~~~~~~~~~~~~~~~~
299 forAll(doneEdge, edgeI)
301 if (doneEdge.get(edgeI) == 0u)
303 doneEdge.set(edgeI, 1u);
304 isMasterEdge.set(edgeI, 1u);
312 // Determines for every face whether it is coupled and if so sets only one.
313 Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
315 PackedBoolList isMasterFace(mesh.nFaces(), 1);
317 const polyBoundaryMesh& patches = mesh.boundaryMesh();
319 forAll(patches, patchI)
321 if (patches[patchI].coupled())
323 if (Pstream::parRun() && isA<processorPolyPatch>(patches[patchI]))
325 const processorPolyPatch& pp =
326 refCast<const processorPolyPatch>(patches[patchI]);
332 isMasterFace.set(pp.start()+i, 0);
336 else if (isA<cyclicPolyPatch>(patches[patchI]))
338 const cyclicPolyPatch& pp =
339 refCast<const cyclicPolyPatch>(patches[patchI]);
341 for (label i = pp.size()/2; i < pp.size(); i++)
343 isMasterFace.set(pp.start()+i, 0);
348 FatalErrorIn("syncTools::getMasterFaces(const polyMesh&)")
349 << "Cannot handle coupled patch " << patches[patchI].name()
350 << " of type " << patches[patchI].type()
351 << abort(FatalError);
361 void Foam::syncTools::separateList
363 const vectorField& separation,
367 if (separation.size() == 1)
369 // Single value for all.
373 field[i] += separation[0];
376 else if (separation.size() == field.size())
380 field[i] += separation[i];
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);
396 void Foam::syncTools::separateList
398 const vectorField& separation,
402 if (separation.size() == 1)
404 // Single value for all.
405 forAllIter(Map<vector>, field, iter)
407 iter() += separation[0];
410 else if (separation.size() == field.size())
412 forAllIter(Map<vector>, field, iter)
414 iter() += separation[iter.key()];
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);
430 void Foam::syncTools::separateList
432 const vectorField& separation,
433 EdgeMap<vector>& field
436 if (separation.size() == 1)
438 // Single value for all.
439 forAllIter(EdgeMap<vector>, field, iter)
441 iter() += separation[0];
448 "syncTools::separateList(const vectorField&, EdgeMap<vector>&)"
449 ) << "Multiple separation vectors not supported. field:"
450 << field.size() << " transformation:" << separation.size()
451 << abort(FatalError);
456 // ************************************************************************* //