Initial commit for version 2.0.x patch release
[OpenFOAM-2.0.x.git] / src / OpenFOAM / meshes / primitiveMesh / PatchTools / PatchToolsNormals.C
blob9de4e76a9427696a80ffe9888a89b0c3b95cff48
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011-2011 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
9     This file is part of OpenFOAM.
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.
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.
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/>.
24 \*---------------------------------------------------------------------------*/
26 #include "PatchTools.H"
27 #include "polyMesh.H"
28 #include "indirectPrimitivePatch.H"
29 #include "globalMeshData.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 namespace Foam
36     //- Transformation
37     class listTransform
38     {
39     public:
41         void operator()
42         (
43             const vectorTensorTransform& vt,
44             const bool forward,
45             List<List<point> >& fld
46         ) const
47         {
48             const tensor T
49             (
50                 forward
51               ? vt.R()
52               : vt.R().T()
53             );
55             forAll(fld, i)
56             {
57                 List<point>& elems = fld[i];
58                 forAll(elems, elemI)
59                 {
60                     elems[elemI] = transform(T, elems[elemI]);
61                 }
62             }
63         }
64     };
68 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
70 template
72     class Face,
73     template<class> class FaceList,
74     class PointField,
75     class PointType
78 Foam::tmp<Foam::pointField>
79 Foam::PatchTools::pointNormals
81     const polyMesh& mesh,
82     const PrimitivePatch<Face, FaceList, PointField, PointType>& p,
83     const labelList& meshFaces
86     // Assume patch is smaller than the globalData().coupledPatch() (?) so
87     // loop over patch meshPoints.
89     const globalMeshData& globalData = mesh.globalData();
90     const indirectPrimitivePatch& coupledPatch = globalData.coupledPatch();
91     const Map<label>& coupledPatchMP = coupledPatch.meshPointMap();
92     const mapDistribute& map = globalData.globalPointSlavesMap();
93     const globalIndexAndTransform& transforms =
94         globalData.globalTransforms();
97     // 1. Start off with local normals (note:without calculating pointNormals
98     //    to avoid them being stored)
100     tmp<pointField> textrudeN(new pointField(p.nPoints(), vector::zero));
101     pointField& extrudeN = textrudeN();
102     {
103         const faceList& localFaces = p.localFaces();
104         const vectorField& faceNormals = p.faceNormals();
106         forAll(localFaces, faceI)
107         {
108             const face& f = localFaces[faceI];
109             const vector& n = faceNormals[faceI];
110             forAll(f, fp)
111             {
112                 extrudeN[f[fp]] += n;
113             }
114         }
115         extrudeN /= mag(extrudeN)+VSMALL;
116     }
119     // Collect local pointFaces
120     List<List<point> > pointFaceNormals(map.constructSize());
121     forAll(p.meshPoints(), patchPointI)
122     {
123         label meshPointI = p.meshPoints()[patchPointI];
124         Map<label>::const_iterator fnd = coupledPatchMP.find(meshPointI);
125         if (fnd != coupledPatchMP.end())
126         {
127             label coupledPointI = fnd();
129             List<point>& pNormals = pointFaceNormals[coupledPointI];
130             const labelList& pFaces = p.pointFaces()[patchPointI];
131             pNormals.setSize(pFaces.size());
132             forAll(pFaces, i)
133             {
134                 pNormals[i] = p.faceNormals()[pFaces[i]];
135             }
136         }
137     }
140     // Pull remote data into local slots
141     map.distribute
142     (
143         transforms,
144         pointFaceNormals,
145         listTransform()
146     );
149     // Combine normals
150     const labelListList& slaves = globalData.globalPointSlaves();
151     const labelListList& transformedSlaves =
152         globalData.globalPointTransformedSlaves();
155     pointField coupledPointNormals(map.constructSize(), vector::zero);
157     forAll(p.meshPoints(), patchPointI)
158     {
159         label meshPointI = p.meshPoints()[patchPointI];
160         Map<label>::const_iterator fnd = coupledPatchMP.find(meshPointI);
161         if (fnd != coupledPatchMP.end())
162         {
163             label coupledPointI = fnd();
164             const labelList& slaveSlots =
165                 slaves[coupledPointI];
166             const labelList& transformedSlaveSlots =
167                 transformedSlaves[coupledPointI];
169             label nFaces = slaveSlots.size()+transformedSlaveSlots.size();
170             if (nFaces > 0)
171             {
172                 // Combine
173                 point& n = coupledPointNormals[coupledPointI];
175                 n += sum(pointFaceNormals[coupledPointI]);
177                 forAll(slaveSlots, i)
178                 {
179                     n += sum(pointFaceNormals[slaveSlots[i]]);
180                 }
181                 forAll(transformedSlaveSlots, i)
182                 {
183                     n += sum(pointFaceNormals[transformedSlaveSlots[i]]);
184                 }
185                 n /= mag(n)+VSMALL;
187                 // Put back into slave slots
188                 forAll(slaveSlots, i)
189                 {
190                     coupledPointNormals[slaveSlots[i]] = n;
191                 }
192                 forAll(transformedSlaveSlots, i)
193                 {
194                     coupledPointNormals[transformedSlaveSlots[i]] = n;
195                 }
196             }
197         }
198     }
201     // Send back
202     map.reverseDistribute
203     (
204         transforms,
205         coupledPointNormals.size(),
206         coupledPointNormals,
207         mapDistribute::transform()
208     );
211     // Override patch normals
212     forAll(p.meshPoints(), patchPointI)
213     {
214         label meshPointI = p.meshPoints()[patchPointI];
215         Map<label>::const_iterator fnd = coupledPatchMP.find(meshPointI);
216         if (fnd != coupledPatchMP.end())
217         {
218             label coupledPointI = fnd();
219             extrudeN[patchPointI] = coupledPointNormals[coupledPointI];
220         }
221     }
223     return textrudeN;
227 // ************************************************************************* //