Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / foam / meshes / polyMesh / syncTools / syncTools.C
blob1aff8433cdb84c765cf772676b2fa5ead9124bcd
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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"
27 #include "polyMesh.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)
38     {
39         if (patches[patchI].coupled())
40         {
41             hasAnyCouples = true;
42             break;
43         }
44     }
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)
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     }
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)
98     {
99         if (minProc[sharedPointAddr[i]] == Pstream::myProcNo())
100         {
101             isMasterPoint.set(sharedPointLabels[i], 1u);
102         }
103         donePoint.set(sharedPointLabels[i], 1u);
104     }
107     // Do other points on coupled patches
108     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
110     const polyBoundaryMesh& patches = mesh.boundaryMesh();
112     forAll(patches, patchI)
113     {
114         if (patches[patchI].coupled())
115         {
116             if
117             (
118                 Pstream::parRun()
119              && isA<processorPolyPatch>(patches[patchI])
120             )
121             {
122                 const processorPolyPatch& pp =
123                     refCast<const processorPolyPatch>(patches[patchI]);
125                 const labelList& meshPoints = pp.meshPoints();
127                 forAll(meshPoints, i)
128                 {
129                     label pointI = meshPoints[i];
131                     if (donePoint.get(pointI) == 0u)
132                     {
133                         donePoint.set(pointI, 1u);
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]);
147                 const edgeList& coupledPoints = pp.coupledPoints();
148                 const labelList& meshPoints = pp.meshPoints();
150                 forAll(coupledPoints, i)
151                 {
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)
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     }
177     // Do all other points
178     // ~~~~~~~~~~~~~~~~~~~
180     forAll(donePoint, pointI)
181     {
182         if (donePoint.get(pointI) == 0u)
183         {
184             donePoint.set(pointI, 1u);
185             isMasterPoint.set(pointI, 1u);
186         }
187     }
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)
217     {
218         if (minProc[sharedEdgeAddr[i]] == Pstream::myProcNo())
219         {
220             isMasterEdge.set(sharedEdgeLabels[i], 1u);
221         }
222         doneEdge.set(sharedEdgeLabels[i], 1u);
223     }
226     // Do other edges on coupled patches
227     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229     const polyBoundaryMesh& patches = mesh.boundaryMesh();
231     forAll(patches, patchI)
232     {
233         if (patches[patchI].coupled())
234         {
235             if
236             (
237                 Pstream::parRun()
238              && isA<processorPolyPatch>(patches[patchI])
239             )
240             {
241                 const processorPolyPatch& pp =
242                     refCast<const processorPolyPatch>(patches[patchI]);
244                 const labelList& meshEdges = pp.meshEdges();
246                 forAll(meshEdges, i)
247                 {
248                     label edgeI = meshEdges[i];
250                     if (doneEdge.get(edgeI) == 0u)
251                     {
252                         doneEdge.set(edgeI, 1u);
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]);
266                 const edgeList& coupledEdges = pp.coupledEdges();
267                 const labelList& meshEdges = pp.meshEdges();
269                 forAll(coupledEdges, i)
270                 {
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)
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     }
296     // Do all other edges
297     // ~~~~~~~~~~~~~~~~~~
299     forAll(doneEdge, edgeI)
300     {
301         if (doneEdge.get(edgeI) == 0u)
302         {
303             doneEdge.set(edgeI, 1u);
304             isMasterEdge.set(edgeI, 1u);
305         }
306     }
308     return isMasterEdge;
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)
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]);
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]);
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     }
356     return isMasterFace;
360 template <>
361 void Foam::syncTools::separateList
363     const vectorField& separation,
364     UList<vector>& field
367     if (separation.size() == 1)
368     {
369         // Single value for all.
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     {
385         FatalErrorIn
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     }
395 template <>
396 void Foam::syncTools::separateList
398     const vectorField& separation,
399     Map<vector>& field
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     {
419         FatalErrorIn
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     }
429 template <>
430 void Foam::syncTools::separateList
432     const vectorField& separation,
433     EdgeMap<vector>& field
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     {
446         FatalErrorIn
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     }
456 // ************************************************************************* //