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

sampledTriSurfaceMesh.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) 2010-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 "sampledTriSurfaceMesh.H"
00027 #include <meshTools/treeDataPoint.H>
00028 #include <meshTools/meshSearch.H>
00029 #include <OpenFOAM/Tuple2.H>
00030 #include <OpenFOAM/globalIndex.H>
00031 
00032 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00033 
00034 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00035 
00036 namespace Foam
00037 {
00038     defineTypeNameAndDebug(sampledTriSurfaceMesh, 0);
00039     addToRunTimeSelectionTable
00040     (
00041         sampledSurface,
00042         sampledTriSurfaceMesh,
00043         word
00044     );
00045 
00046     //- Private class for finding nearest
00047     //  - global index
00048     //  - sqr(distance)
00049     typedef Tuple2<scalar, label> nearInfo;
00050 
00051     class nearestEqOp
00052     {
00053 
00054     public:
00055 
00056         void operator()(nearInfo& x, const nearInfo& y) const
00057         {
00058             if (y.first() < x.first())
00059             {
00060                 x = y;
00061             }
00062         }
00063     };
00064 }
00065 
00066 
00067 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00068 
00069 Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
00070 (
00071     const word& name,
00072     const polyMesh& mesh,
00073     const word& surfaceName
00074 )
00075 :
00076     sampledSurface(name, mesh),
00077     surface_
00078     (
00079         IOobject
00080         (
00081             name,
00082             mesh.time().constant(), // instance
00083             "triSurface",           // local
00084             mesh,                   // registry
00085             IOobject::MUST_READ,
00086             IOobject::NO_WRITE,
00087             false
00088         )
00089     ),
00090     needsUpdate_(true),
00091     cellLabels_(0),
00092     pointToFace_(0)
00093 {}
00094 
00095 
00096 Foam::sampledTriSurfaceMesh::sampledTriSurfaceMesh
00097 (
00098     const word& name,
00099     const polyMesh& mesh,
00100     const dictionary& dict
00101 )
00102 :
00103     sampledSurface(name, mesh, dict),
00104     surface_
00105     (
00106         IOobject
00107         (
00108             dict.lookup("surface"),
00109             mesh.time().constant(), // instance
00110             "triSurface",           // local
00111             mesh,                   // registry
00112             IOobject::MUST_READ,
00113             IOobject::NO_WRITE,
00114             false
00115         )
00116     ),
00117     needsUpdate_(true),
00118     cellLabels_(0),
00119     pointToFace_(0)
00120 {}
00121 
00122 
00123 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00124 
00125 Foam::sampledTriSurfaceMesh::~sampledTriSurfaceMesh()
00126 {}
00127 
00128 
00129 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00130 
00131 bool Foam::sampledTriSurfaceMesh::needsUpdate() const
00132 {
00133     return needsUpdate_;
00134 }
00135 
00136 
00137 bool Foam::sampledTriSurfaceMesh::expire()
00138 {
00139     // already marked as expired
00140     if (needsUpdate_)
00141     {
00142         return false;
00143     }
00144 
00145     sampledSurface::clearGeom();
00146     MeshStorage::clear();
00147     cellLabels_.clear();
00148     pointToFace_.clear();
00149 
00150     needsUpdate_ = true;
00151     return true;
00152 }
00153 
00154 
00155 bool Foam::sampledTriSurfaceMesh::update()
00156 {
00157     if (!needsUpdate_)
00158     {
00159         return false;
00160     }
00161 
00162 
00163     // Find the cells the triangles of the surface are in.
00164     // Does approximation by looking at the face centres only
00165     const pointField& fc = surface_.faceCentres();
00166 
00167     meshSearch meshSearcher(mesh(), false);
00168 
00169     const indexedOctree<treeDataPoint>& cellCentreTree =
00170         meshSearcher.cellCentreTree();
00171 
00172 
00173     // Global numbering for cells - only used to uniquely identify local cells.
00174     globalIndex globalCells(mesh().nCells());
00175     List<nearInfo> nearest(fc.size());
00176     forAll(nearest, i)
00177     {
00178         nearest[i].first() = GREAT;
00179         nearest[i].second() = labelMax;
00180     }
00181 
00182     // Search triangles using nearest on local mesh
00183     forAll(fc, triI)
00184     {
00185         pointIndexHit nearInfo = cellCentreTree.findNearest
00186         (
00187             fc[triI],
00188             sqr(GREAT)
00189         );
00190         if (nearInfo.hit())
00191         {
00192             nearest[triI].first() = magSqr(nearInfo.hitPoint()-fc[triI]);
00193             nearest[triI].second() = globalCells.toGlobal(nearInfo.index());
00194         }
00195     }
00196 
00197     // See which processor has the nearest.
00198     Pstream::listCombineGather(nearest, nearestEqOp());
00199     Pstream::listCombineScatter(nearest);
00200 
00201     boolList include(surface_.size(), false);
00202 
00203     cellLabels_.setSize(fc.size());
00204     cellLabels_ = -1;
00205 
00206     label nFound = 0;
00207     forAll(nearest, triI)
00208     {
00209         if (nearest[triI].second() == labelMax)
00210         {
00211             // Not found on any processor. How to map?
00212         }
00213         else if (globalCells.isLocal(nearest[triI].second()))
00214         {
00215             cellLabels_[triI] = globalCells.toLocal(nearest[triI].second());
00216 
00217             include[triI] = true;
00218             nFound++;
00219         }
00220     }
00221 
00222 
00223     if (debug)
00224     {
00225         Pout<< "Local out of faces:" << cellLabels_.size()
00226             << " keeping:" << nFound << endl;
00227     }
00228 
00229     // Now subset the surface. Do not use triSurface::subsetMesh since requires
00230     // original surface to be in compact numbering.
00231 
00232     const triSurface& s = surface_;
00233 
00234     // Compact to original triangle
00235     labelList faceMap(s.size());
00236     // Compact to original points
00237     labelList pointMap(s.points().size());
00238     // From original point to compact points
00239     labelList reversePointMap(s.points().size(), -1);
00240 
00241     {
00242         label newPointI = 0;
00243         label newTriI = 0;
00244 
00245         forAll(s, triI)
00246         {
00247             if (include[triI])
00248             {
00249                 faceMap[newTriI++] = triI;
00250 
00251                 const labelledTri& f = s[triI];
00252                 forAll(f, fp)
00253                 {
00254                     if (reversePointMap[f[fp]] == -1)
00255                     {
00256                         pointMap[newPointI] = f[fp];
00257                         reversePointMap[f[fp]] = newPointI++;
00258                     }
00259                 }
00260             }
00261         }
00262         faceMap.setSize(newTriI);
00263         pointMap.setSize(newPointI);
00264     }
00265 
00266     // Subset cellLabels
00267     cellLabels_ = UIndirectList<label>(cellLabels_, faceMap)();
00268 
00269     // Store any face per point
00270     pointToFace_.setSize(pointMap.size());
00271 
00272     // Create faces and points for subsetted surface
00273     faceList& faces = this->storedFaces();
00274     faces.setSize(faceMap.size());
00275     forAll(faceMap, i)
00276     {
00277         const triFace& f = s[faceMap[i]];
00278         triFace newF
00279         (
00280             reversePointMap[f[0]],
00281             reversePointMap[f[1]],
00282             reversePointMap[f[2]]
00283         );
00284         faces[i] = newF.triFaceFace();
00285 
00286         forAll(newF, fp)
00287         {
00288             pointToFace_[newF[fp]] = i;
00289         }
00290     }
00291 
00292     this->storedPoints() = pointField(s.points(), pointMap);
00293 
00294     if (debug)
00295     {
00296         print(Pout);
00297         Pout<< endl;
00298     }
00299 
00300     needsUpdate_ = false;
00301     return true;
00302 }
00303 
00304 
00305 Foam::tmp<Foam::scalarField>
00306 Foam::sampledTriSurfaceMesh::sample
00307 (
00308     const volScalarField& vField
00309 ) const
00310 {
00311     return sampleField(vField);
00312 }
00313 
00314 
00315 Foam::tmp<Foam::vectorField>
00316 Foam::sampledTriSurfaceMesh::sample
00317 (
00318     const volVectorField& vField
00319 ) const
00320 {
00321     return sampleField(vField);
00322 }
00323 
00324 Foam::tmp<Foam::sphericalTensorField>
00325 Foam::sampledTriSurfaceMesh::sample
00326 (
00327     const volSphericalTensorField& vField
00328 ) const
00329 {
00330     return sampleField(vField);
00331 }
00332 
00333 
00334 Foam::tmp<Foam::symmTensorField>
00335 Foam::sampledTriSurfaceMesh::sample
00336 (
00337     const volSymmTensorField& vField
00338 ) const
00339 {
00340     return sampleField(vField);
00341 }
00342 
00343 
00344 Foam::tmp<Foam::tensorField>
00345 Foam::sampledTriSurfaceMesh::sample
00346 (
00347     const volTensorField& vField
00348 ) const
00349 {
00350     return sampleField(vField);
00351 }
00352 
00353 
00354 Foam::tmp<Foam::scalarField>
00355 Foam::sampledTriSurfaceMesh::interpolate
00356 (
00357     const interpolation<scalar>& interpolator
00358 ) const
00359 {
00360     return interpolateField(interpolator);
00361 }
00362 
00363 
00364 Foam::tmp<Foam::vectorField>
00365 Foam::sampledTriSurfaceMesh::interpolate
00366 (
00367     const interpolation<vector>& interpolator
00368 ) const
00369 {
00370     return interpolateField(interpolator);
00371 }
00372 
00373 Foam::tmp<Foam::sphericalTensorField>
00374 Foam::sampledTriSurfaceMesh::interpolate
00375 (
00376     const interpolation<sphericalTensor>& interpolator
00377 ) const
00378 {
00379     return interpolateField(interpolator);
00380 }
00381 
00382 
00383 Foam::tmp<Foam::symmTensorField>
00384 Foam::sampledTriSurfaceMesh::interpolate
00385 (
00386     const interpolation<symmTensor>& interpolator
00387 ) const
00388 {
00389     return interpolateField(interpolator);
00390 }
00391 
00392 
00393 Foam::tmp<Foam::tensorField>
00394 Foam::sampledTriSurfaceMesh::interpolate
00395 (
00396     const interpolation<tensor>& interpolator
00397 ) const
00398 {
00399     return interpolateField(interpolator);
00400 }
00401 
00402 
00403 void Foam::sampledTriSurfaceMesh::print(Ostream& os) const
00404 {
00405     os  << "sampledTriSurfaceMesh: " << name() << " :"
00406         << "  surface:" << surface_.objectRegistry::name()
00407         << "  faces:" << faces().size()
00408         << "  points:" << points().size();
00409 }
00410 
00411 
00412 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines