FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

PrimitivePatchInterpolation_.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 \*---------------------------------------------------------------------------*/
00025 
00026 #include "PrimitivePatchInterpolation_.H"
00027 #include <OpenFOAM/faceList.H>
00028 #include <OpenFOAM/demandDrivenData.H>
00029 
00030 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00031 
00032 namespace Foam
00033 {
00034 
00035 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00036 
00037 template<class Patch>
00038 const scalarListList&
00039 PrimitivePatchInterpolation<Patch>::faceToPointWeights() const
00040 {
00041     if (!faceToPointWeightsPtr_)
00042     {
00043         makeFaceToPointWeights();
00044     }
00045 
00046     return *faceToPointWeightsPtr_;
00047 }
00048 
00049 
00050 template<class Patch>
00051 void PrimitivePatchInterpolation<Patch>::makeFaceToPointWeights() const
00052 {
00053     if (faceToPointWeightsPtr_)
00054     {
00055         FatalErrorIn
00056         (
00057             "PrimitivePatchInterpolation<Patch>::makeFaceToPointWeights() const"
00058         )   << "Face-to-edge weights already calculated"
00059             << abort(FatalError);
00060     }
00061 
00062     const pointField& points = patch_.localPoints();
00063     const faceList& faces = patch_.localFaces();
00064 
00065     faceToPointWeightsPtr_ = new scalarListList(points.size());
00066     scalarListList& weights = *faceToPointWeightsPtr_;
00067 
00068     // get reference to addressing
00069     const labelListList& pointFaces = patch_.pointFaces();
00070 
00071     forAll(pointFaces, pointi)
00072     {
00073         const labelList& curFaces = pointFaces[pointi];
00074 
00075         scalarList& pw = weights[pointi];
00076         pw.setSize(curFaces.size());
00077 
00078         scalar sumw = 0.0;
00079 
00080         forAll(curFaces, facei)
00081         {
00082             pw[facei] = 
00083                 1.0/mag(faces[curFaces[facei]].centre(points) - points[pointi]);
00084             sumw += pw[facei];
00085         }
00086 
00087         forAll(curFaces, facei)
00088         {
00089             pw[facei] /= sumw;
00090         }
00091     }
00092 }
00093 
00094 
00095 template<class Patch>
00096 const scalarList&
00097 PrimitivePatchInterpolation<Patch>::faceToEdgeWeights() const
00098 {
00099     if (!faceToEdgeWeightsPtr_)
00100     {
00101         makeFaceToEdgeWeights();
00102     }
00103 
00104     return *faceToEdgeWeightsPtr_;
00105 }
00106 
00107 
00108 template<class Patch>
00109 void PrimitivePatchInterpolation<Patch>::makeFaceToEdgeWeights() const
00110 {
00111     if (faceToEdgeWeightsPtr_)
00112     {
00113         FatalErrorIn
00114         (
00115             "PrimitivePatchInterpolation<Patch>::makeFaceToEdgeWeights() const"
00116         )   << "Face-to-edge weights already calculated"
00117             << abort(FatalError);
00118     }
00119 
00120     const pointField& points = patch_.localPoints();
00121     const faceList& faces = patch_.localFaces();
00122     const edgeList& edges = patch_.edges();
00123     const labelListList& edgeFaces = patch_.edgeFaces();
00124 
00125     faceToEdgeWeightsPtr_ = new scalarList(patch_.nInternalEdges());
00126     scalarList& weights = *faceToEdgeWeightsPtr_;
00127 
00128     for (label edgei = 0; edgei < weights.size(); edgei++)
00129     {
00130         vector P = faces[edgeFaces[edgei][0]].centre(points);
00131         vector N = faces[edgeFaces[edgei][1]].centre(points);
00132         vector S = points[edges[edgei].start()];
00133         vector e = edges[edgei].vec(points);
00134 
00135         scalar alpha = 
00136             -(((N - P)^(S - P))&((N - P)^e))/(((N - P)^e )&((N - P)^e));
00137 
00138         vector E = S + alpha*e;
00139 
00140         weights[edgei] = mag(N - E)/(mag(N - E) + mag(E - P));
00141     }
00142 }
00143 
00144 
00145 template<class Patch>
00146 void PrimitivePatchInterpolation<Patch>::clearWeights()
00147 {
00148     deleteDemandDrivenData(faceToPointWeightsPtr_);
00149     deleteDemandDrivenData(faceToEdgeWeightsPtr_);
00150 }
00151 
00152 
00153 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00154 
00155 template<class Patch>
00156 PrimitivePatchInterpolation<Patch>::PrimitivePatchInterpolation(const Patch& p)
00157 :
00158     patch_(p),
00159     faceToPointWeightsPtr_(NULL),
00160     faceToEdgeWeightsPtr_(NULL)
00161 {}
00162 
00163 
00164 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
00165 
00166 template<class Patch>
00167 PrimitivePatchInterpolation<Patch>::~PrimitivePatchInterpolation()
00168 {
00169     clearWeights();
00170 }
00171 
00172 
00173 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00174 
00175 template<class Patch>
00176 template<class Type>
00177 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToPointInterpolate
00178 (
00179     const Field<Type>& ff
00180 ) const
00181 {
00182     // Check size of the given field
00183     if (ff.size() != patch_.size())
00184     {
00185         FatalErrorIn
00186         (
00187             "tmp<Field<Type> > PrimitivePatchInterpolation::"
00188             "faceToPointInterpolate(const Field<Type> ff)"
00189         )   << "given field does not correspond to patch. Patch size: "
00190             << patch_.size() << " field size: " << ff.size()
00191             << abort(FatalError);
00192     }
00193 
00194     tmp<Field<Type> > tresult
00195     (
00196         new Field<Type>
00197         (
00198             patch_.nPoints(), pTraits<Type>::zero
00199         )
00200     );
00201 
00202     Field<Type>& result = tresult();
00203 
00204     const labelListList& pointFaces = patch_.pointFaces();
00205     const scalarListList& weights = faceToPointWeights();
00206 
00207     forAll(pointFaces, pointi)
00208     {
00209         const labelList& curFaces = pointFaces[pointi];
00210         const scalarList& w = weights[pointi];
00211 
00212         forAll(curFaces, facei)
00213         {
00214             result[pointi] += w[facei]*ff[curFaces[facei]];
00215         }
00216     }
00217 
00218     return tresult;
00219 }
00220 
00221 
00222 template<class Patch>
00223 template<class Type>
00224 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToPointInterpolate
00225 (
00226     const tmp<Field<Type> >& tff
00227 ) const
00228 {
00229     tmp<Field<Type> > tint = faceToPointInterpolate(tff());
00230     tff.clear();
00231     return tint;
00232 }
00233 
00234 
00235 template<class Patch>
00236 template<class Type>
00237 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::pointToFaceInterpolate
00238 (
00239     const Field<Type>& pf
00240 ) const
00241 {
00242     if (pf.size() != patch_.nPoints())
00243     {
00244         FatalErrorIn
00245         (
00246             "tmp<Field<Type> > PrimitivePatchInterpolation::"
00247             "pointToFaceInterpolate(const Field<Type> pf)"
00248         )   << "given field does not correspond to patch. Patch size: "
00249             << patch_.nPoints() << " field size: " << pf.size()
00250             << abort(FatalError);
00251     }
00252 
00253     tmp<Field<Type> > tresult
00254     (
00255         new Field<Type>
00256         (
00257             patch_.size(),
00258             pTraits<Type>::zero
00259         )
00260     );
00261 
00262     Field<Type>& result = tresult();
00263 
00264     const faceList& localFaces = patch_.localFaces();
00265 
00266     forAll(result, facei)
00267     {
00268         const labelList& curPoints = localFaces[facei];
00269 
00270         forAll(curPoints, pointi)
00271         {
00272             result[facei] += pf[curPoints[pointi]];
00273         }
00274 
00275         result[facei] /= curPoints.size();
00276     }
00277 
00278     return tresult;
00279 }
00280 
00281 
00282 template<class Patch>
00283 template<class Type>
00284 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::pointToFaceInterpolate
00285 (
00286     const tmp<Field<Type> >& tpf
00287 ) const
00288 {
00289     tmp<Field<Type> > tint = pointToFaceInterpolate(tpf());
00290     tpf.clear();
00291     return tint;
00292 }
00293 
00294 
00295 template<class Patch>
00296 template<class Type>
00297 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToEdgeInterpolate
00298 (
00299     const Field<Type>& pf
00300 ) const
00301 {
00302     // Check size of the given field
00303     if (pf.size() != patch_.size())
00304     {
00305         FatalErrorIn
00306         (
00307             "tmp<Field<Type> > PrimitivePatchInterpolation::"
00308             "faceToEdgeInterpolate(const Field<Type> ff)"
00309         )   << "given field does not correspond to patch. Patch size: "
00310             << patch_.size() << " field size: " << pf.size()
00311             << abort(FatalError);
00312     }
00313 
00314     tmp<Field<Type> > tresult
00315     (
00316         new Field<Type>(patch_.nEdges(), pTraits<Type>::zero)
00317     );
00318 
00319     Field<Type>& result = tresult();
00320     
00321     const pointField& points = patch_.localPoints();
00322     const faceList& faces = patch_.localFaces();
00323     const edgeList& edges = patch_.edges();
00324     const labelListList& edgeFaces = patch_.edgeFaces();
00325 
00326     const scalarList& weights = faceToEdgeWeights();
00327 
00328     for (label edgei = 0; edgei < patch_.nInternalEdges(); edgei++)
00329     {
00330         result[edgei] = 
00331             weights[edgei]*pf[edgeFaces[edgei][0]]
00332           + (1.0 - weights[edgei])*pf[edgeFaces[edgei][1]];
00333     }
00334 
00335     for (label edgei = patch_.nInternalEdges(); edgei < edges.size(); edgei++)
00336     {
00337         result[edgei] = pf[edgeFaces[edgei][0]];
00338     }
00339 
00340     return tresult;
00341 }
00342 
00343 
00344 template<class Patch>
00345 template<class Type>
00346 tmp<Field<Type> > PrimitivePatchInterpolation<Patch>::faceToEdgeInterpolate
00347 (
00348     const tmp<Field<Type> >& tpf
00349 ) const
00350 {
00351     tmp<Field<Type> > tint = faceToEdgeInterpolate(tpf());
00352     tpf.clear();
00353     return tint;
00354 }
00355 
00356 
00357 template<class Patch>
00358 bool PrimitivePatchInterpolation<Patch>::movePoints()
00359 {
00360     clearWeights();
00361 
00362     return true;
00363 }
00364 
00365 
00366 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00367 
00368 } // End namespace Foam
00369 
00370 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines