Merge branch 'master' of ssh://git.code.sf.net/p/foam-extend/foam-extend-3.2
[foam-extend-3.2.git] / src / tetFiniteElement / tetPolyMesh / MapTetFemFields / tetPolyPatchMapper.C
blob581b90d74ecfc74b45bb04a59b67fa59a6d598ba
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 Description
25     PolyPatch mapper for the face tetFem decomposition
27 \*---------------------------------------------------------------------------*/
29 #include "tetPolyPatchMapper.H"
30 #include "tetPolyPatch.H"
31 #include "tetPolyBoundaryMesh.H"
32 #include "tetPolyMesh.H"
33 #include "mapPolyMesh.H"
34 #include "pointMapper.H"
35 #include "faceMapper.H"
36 #include "faceTetPolyPatch.H"
38 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
40 void Foam::tetPolyPatchMapper::calcAddressing() const
42     if
43     (
44         directPtr_
45      || directAddrPtr_
46      || interpolationAddrPtr_
47      || weightsPtr_
48     )
49     {
50         FatalErrorIn
51         (
52             "void tetPolyPatchMapper::calcAddressing() const)"
53         )   << "Addressing already calculated"
54             << abort(FatalError);
55     }
57     // Mapping
59     // Calculate direct (if all are direct)
60     directPtr_ = new bool(pMapper_.direct() && fMapper_.direct());
62     const labelList& curPatchPointMap = mpm_.patchPointMap()[patch_.index()];
64     const label patchOffset = mpm_.oldPatchStarts()[patch_.index()];
65     const label oldPatchFaceOffset = mpm_.oldPatchNMeshPoints()[patch_.index()];
67     // Assemble the maps
68     // If it's a face patch, insert the faces
69     const polyPatch& p =
70         refCast<const faceTetPolyPatch>(patch_).patch();
72     const label curPatchStart = p.start();
73     const label curPatchEnd = curPatchStart + p.size();
75     // Mapping
76     const label oldPatchStart = mpm_.oldPatchStarts()[patch_.index()];
78     const label oldPatchEnd =
79         oldPatchStart + mpm_.oldPatchSizes()[patch_.index()];
81     if (*directPtr_)
82     {
83         // Direct mapping
85         directAddrPtr_ = new labelList(size());
86         labelList& addr = *directAddrPtr_;
87         label nAddr = 0;
89         forAll (curPatchPointMap, pointI)
90         {
91             if (curPatchPointMap[pointI] > -1)
92             {
93                 addr[nAddr] = curPatchPointMap[pointI];
94             }
95             else
96             {
97                 addr[nAddr] = 0;
98             }
99             nAddr++;
100         }
102         const labelList& mappedFaces = fMapper_.directAddressing();
104         // Insert faces
105         for (label faceI = curPatchStart; faceI < curPatchEnd; faceI++)
106         {
107             if
108             (
109                 mappedFaces[faceI] >= oldPatchStart
110              && mappedFaces[faceI] < oldPatchEnd
111             )
112             {
113                 addr[nAddr] =
114                     mappedFaces[faceI] - patchOffset + oldPatchFaceOffset;
115             }
116             else
117             {
118                 addr[nAddr] = 0;
119             }
121             nAddr++;
122         }
123     }
124     else
125     {
126         // Interpolative mapping
127         interpolationAddrPtr_ = new labelListList(size());
128         labelListList& addr = *interpolationAddrPtr_;
130         weightsPtr_ = new scalarListList(size());
131         scalarListList& w = *weightsPtr_;
133         label nAddr = 0;
135         // Insert points
137         forAll (curPatchPointMap, pointI)
138         {
139             if (curPatchPointMap[pointI] > -1)
140             {
141                 addr[nAddr] = labelList(1, curPatchPointMap[pointI]);
142             }
143             else
144             {
145                 addr[nAddr] = labelList(1, 0);
146             }
148             w[nAddr] = scalarList(1, 1.0);
149             nAddr++;
150         }
152         const labelListList& mappedFaces = fMapper_.addressing();
153         const scalarListList& faceWeights = fMapper_.weights();
155         // Insert faces
156         for (label faceI = curPatchStart; faceI < curPatchEnd; faceI++)
157         {
158             labelList& curAddr = addr[nAddr];
159             scalarList& curW = w[nAddr];
160             label nActive = 0;
162             const labelList& curMf = mappedFaces[faceI];
163             curAddr.setSize(curMf.size());
165             const scalarList& curMfWeights = faceWeights[faceI];
166             curW.setSize(curMfWeights.size());
168             forAll (curMf, lfI)
169             {
170                 if
171                 (
172                     curMf[lfI] >= oldPatchStart
173                  && curMf[lfI] < oldPatchEnd
174                 )
175                 {
176                     curAddr[nActive] =
177                         curMf[lfI] - patchOffset + oldPatchFaceOffset;
179                     curW[nActive] = curMfWeights[lfI];
180                     nActive++;
181                 }
183             }
185             // Cater for bad mapping
186             if (nActive == 0)
187             {
188                 curAddr[nActive] = 0;
189                 curW[nActive] = 1;
190                 nActive++;
191             }
193             curAddr.setSize(nActive);
194             curW.setSize(nActive);
196             // Re-scale the weights
197             scalar sumW = sum(curW);
199             forAll (curW, wI)
200             {
201                 curW[wI] /= sumW;
202             }
204             nAddr++;
205         }
206     }
210 void Foam::tetPolyPatchMapper::clearOut()
212     deleteDemandDrivenData(directPtr_);
213     deleteDemandDrivenData(directAddrPtr_);
214     deleteDemandDrivenData(interpolationAddrPtr_);
215     deleteDemandDrivenData(weightsPtr_);
219 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
221 // Construct from components
222 Foam::tetPolyPatchMapper::tetPolyPatchMapper
224     const tetPolyPatch& patch,
225     const mapPolyMesh& meshMap,
226     const pointMapper& pMapper,
227     const faceMapper& fMapper
230     patch_(patch),
231     mpm_(meshMap),
232     pMapper_(pMapper),
233     fMapper_(fMapper),
234     directPtr_(NULL),
235     directAddrPtr_(NULL),
236     interpolationAddrPtr_(NULL),
237     weightsPtr_(NULL)
241 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
243 Foam::tetPolyPatchMapper::~tetPolyPatchMapper()
245     clearOut();
249 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
251 Foam::label Foam::tetPolyPatchMapper::size() const
253     return patch_.size();
257 Foam::label Foam::tetPolyPatchMapper::sizeBeforeMapping() const
259     return
260         mpm_.oldPatchSizes()[patch_.index()]
261       + mpm_.oldPatchNMeshPoints()[patch_.index()];
265 bool Foam::tetPolyPatchMapper::direct() const
267     if (!directPtr_)
268     {
269         calcAddressing();
270     }
272     return *directPtr_;
276 const Foam::unallocLabelList&
277 Foam::tetPolyPatchMapper::directAddressing() const
279     if (!direct())
280     {
281         FatalErrorIn
282         (
283             "const unallocLabelList& tetPolyPatchMapper::"
284             "directAddressing() const"
285         )   << "Requested direct addressing for an interpolative mapper."
286             << abort(FatalError);
287     }
289     if (!directAddrPtr_)
290     {
291         calcAddressing();
292     }
294     return *directAddrPtr_;
298 const Foam::labelListList&
299 Foam::tetPolyPatchMapper::addressing() const
301     if (direct())
302     {
303         FatalErrorIn
304         (
305             "const labelListList& tetPolyPatchMapper::"
306             "addressing() const"
307         )   << "Requested interpolative addressing for a direct mapper."
308             << abort(FatalError);
309     }
311     if (!interpolationAddrPtr_)
312     {
313         calcAddressing();
314     }
316     return *interpolationAddrPtr_;
320 const Foam::scalarListList& Foam::tetPolyPatchMapper::weights() const
322     if (direct())
323     {
324         FatalErrorIn
325         (
326             "const scalarListList& tetPolyPatchMapper::"
327             "weights() const"
328         )   << "Requested interpolative weights for a direct mapper."
329             << abort(FatalError);
330     }
332     if (!weightsPtr_)
333     {
334         calcAddressing();
335     }
337     return *weightsPtr_;
341 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
344 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
347 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
350 // ************************************************************************* //