initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / OpenFOAM / interpolations / primitivePatchInterpolation / PrimitivePatchInterpolation.C
blob809d00a0b89d5704bb5d516c128924bfc9aed212
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 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 the
13     Free Software Foundation; either version 2 of the License, or (at your
14     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, write to the Free Software Foundation,
23     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "PrimitivePatchInterpolation.H"
28 #include "faceList.H"
29 #include "demandDrivenData.H"
31 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
33 namespace Foam
36 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
38 template<class Patch>
39 const scalarListList&
40 PrimitivePatchInterpolation<Patch>::faceToPointWeights() const
42     if (!faceToPointWeightsPtr_)
43     {
44         makeFaceToPointWeights();
45     }
47     return *faceToPointWeightsPtr_;
51 template<class Patch>
52 void PrimitivePatchInterpolation<Patch>::makeFaceToPointWeights() const
54     if (faceToPointWeightsPtr_)
55     {
56         FatalErrorIn
57         (
58             "PrimitivePatchInterpolation<Patch>::makeFaceToPointWeights() const"
59         )   << "Face-to-edge weights already calculated"
60             << abort(FatalError);
61     }
63     const pointField& points = patch_.localPoints();
64     const faceList& faces = patch_.localFaces();
66     faceToPointWeightsPtr_ = new scalarListList(points.size());
67     scalarListList& weights = *faceToPointWeightsPtr_;
69     // get reference to addressing
70     const labelListList& pointFaces = patch_.pointFaces();
72     forAll(pointFaces, pointi)
73     {
74         const labelList& curFaces = pointFaces[pointi];
76         scalarList& pw = weights[pointi];
77         pw.setSize(curFaces.size());
79         scalar sumw = 0.0;
81         forAll(curFaces, facei)
82         {
83             pw[facei] = 
84                 1.0/mag(faces[curFaces[facei]].centre(points) - points[pointi]);
85             sumw += pw[facei];
86         }
88         forAll(curFaces, facei)
89         {
90             pw[facei] /= sumw;
91         }
92     }
96 template<class Patch>
97 const scalarList&
98 PrimitivePatchInterpolation<Patch>::faceToEdgeWeights() const
100     if (!faceToEdgeWeightsPtr_)
101     {
102         makeFaceToEdgeWeights();
103     }
105     return *faceToEdgeWeightsPtr_;
109 template<class Patch>
110 void PrimitivePatchInterpolation<Patch>::makeFaceToEdgeWeights() const
112     if (faceToEdgeWeightsPtr_)
113     {
114         FatalErrorIn
115         (
116             "PrimitivePatchInterpolation<Patch>::makeFaceToEdgeWeights() const"
117         )   << "Face-to-edge weights already calculated"
118             << abort(FatalError);
119     }
121     const pointField& points = patch_.localPoints();
122     const faceList& faces = patch_.localFaces();
123     const edgeList& edges = patch_.edges();
124     const labelListList& edgeFaces = patch_.edgeFaces();
126     faceToEdgeWeightsPtr_ = new scalarList(patch_.nInternalEdges());
127     scalarList& weights = *faceToEdgeWeightsPtr_;
129     for (label edgei = 0; edgei < weights.size(); edgei++)
130     {
131         vector P = faces[edgeFaces[edgei][0]].centre(points);
132         vector N = faces[edgeFaces[edgei][1]].centre(points);
133         vector S = points[edges[edgei].start()];
134         vector e = edges[edgei].vec(points);
136         scalar alpha = 
137             -(((N - P)^(S - P))&((N - P)^e))/(((N - P)^e )&((N - P)^e));
139         vector E = S + alpha*e;
141         weights[edgei] = mag(N - E)/(mag(N - E) + mag(E - P));
142     }
146 template<class Patch>
147 void PrimitivePatchInterpolation<Patch>::clearWeights()
149     deleteDemandDrivenData(faceToPointWeightsPtr_);
150     deleteDemandDrivenData(faceToEdgeWeightsPtr_);
154 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
156 template<class Patch>
157 PrimitivePatchInterpolation<Patch>::PrimitivePatchInterpolation(const Patch& p)
159     patch_(p),
160     faceToPointWeightsPtr_(NULL),
161     faceToEdgeWeightsPtr_(NULL)
165 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
167 template<class Patch>
168 PrimitivePatchInterpolation<Patch>::~PrimitivePatchInterpolation()
170     clearWeights();
174 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
176 template<class Patch>
177 template<class Type>
178 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToPointInterpolate
180     const Field<Type>& ff
181 ) const
183     // Check size of the given field
184     if (ff.size() != patch_.size())
185     {
186         FatalErrorIn
187         (
188             "tmp<Field<Type> > PrimitivePatchInterpolation::"
189             "faceToPointInterpolate(const Field<Type> ff)"
190         )   << "given field does not correspond to patch. Patch size: "
191             << patch_.size() << " field size: " << ff.size()
192             << abort(FatalError);
193     }
195     tmp<Field<Type> > tresult
196     (
197         new Field<Type>
198         (
199             patch_.nPoints(), pTraits<Type>::zero
200         )
201     );
203     Field<Type>& result = tresult();
205     const labelListList& pointFaces = patch_.pointFaces();
206     const scalarListList& weights = faceToPointWeights();
208     forAll(pointFaces, pointi)
209     {
210         const labelList& curFaces = pointFaces[pointi];
211         const scalarList& w = weights[pointi];
213         forAll(curFaces, facei)
214         {
215             result[pointi] += w[facei]*ff[curFaces[facei]];
216         }
217     }
219     return tresult;
223 template<class Patch>
224 template<class Type>
225 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToPointInterpolate
227     const tmp<Field<Type> >& tff
228 ) const
230     tmp<Field<Type> > tint = faceToPointInterpolate(tff());
231     tff.clear();
232     return tint;
236 template<class Patch>
237 template<class Type>
238 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::pointToFaceInterpolate
240     const Field<Type>& pf
241 ) const
243     if (pf.size() != patch_.nPoints())
244     {
245         FatalErrorIn
246         (
247             "tmp<Field<Type> > PrimitivePatchInterpolation::"
248             "pointToFaceInterpolate(const Field<Type> pf)"
249         )   << "given field does not correspond to patch. Patch size: "
250             << patch_.nPoints() << " field size: " << pf.size()
251             << abort(FatalError);
252     }
254     tmp<Field<Type> > tresult
255     (
256         new Field<Type>
257         (
258             patch_.size(),
259             pTraits<Type>::zero
260         )
261     );
263     Field<Type>& result = tresult();
265     const faceList& localFaces = patch_.localFaces();
267     forAll(result, facei)
268     {
269         const labelList& curPoints = localFaces[facei];
271         forAll(curPoints, pointi)
272         {
273             result[facei] += pf[curPoints[pointi]];
274         }
276         result[facei] /= curPoints.size();
277     }
279     return tresult;
283 template<class Patch>
284 template<class Type>
285 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::pointToFaceInterpolate
287     const tmp<Field<Type> >& tpf
288 ) const
290     tmp<Field<Type> > tint = pointToFaceInterpolate(tpf());
291     tpf.clear();
292     return tint;
296 template<class Patch>
297 template<class Type>
298 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToEdgeInterpolate
300     const Field<Type>& pf
301 ) const
303     // Check size of the given field
304     if (pf.size() != patch_.size())
305     {
306         FatalErrorIn
307         (
308             "tmp<Field<Type> > PrimitivePatchInterpolation::"
309             "faceToEdgeInterpolate(const Field<Type> ff)"
310         )   << "given field does not correspond to patch. Patch size: "
311             << patch_.size() << " field size: " << pf.size()
312             << abort(FatalError);
313     }
315     tmp<Field<Type> > tresult
316     (
317         new Field<Type>(patch_.nEdges(), pTraits<Type>::zero)
318     );
320     Field<Type>& result = tresult();
321         
322     const pointField& points = patch_.localPoints();
323     const faceList& faces = patch_.localFaces();
324     const edgeList& edges = patch_.edges();
325     const labelListList& edgeFaces = patch_.edgeFaces();
327     const scalarList& weights = faceToEdgeWeights();
329     for (label edgei = 0; edgei < patch_.nInternalEdges(); edgei++)
330     {
331         result[edgei] = 
332             weights[edgei]*pf[edgeFaces[edgei][0]]
333           + (1.0 - weights[edgei])*pf[edgeFaces[edgei][1]];
334     }
336     for (label edgei = patch_.nInternalEdges(); edgei < edges.size(); edgei++)
337     {
338         result[edgei] = pf[edgeFaces[edgei][0]];
339     }
341     return tresult;
345 template<class Patch>
346 template<class Type>
347 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToEdgeInterpolate
349     const tmp<Field<Type> >& tpf
350 ) const
352     tmp<Field<Type> > tint = faceToEdgeInterpolate(tpf());
353     tpf.clear();
354     return tint;
358 template<class Patch>
359 bool PrimitivePatchInterpolation<Patch>::movePoints()
361     clearWeights();
363     return true;
367 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
369 } // End namespace Foam
371 // ************************************************************************* //