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

patchCloudSet.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) 2011-2011 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 "patchCloudSet.H"
00027 #include <OpenFOAM/polyMesh.H>
00028 #include <OpenFOAM/addToRunTimeSelectionTable.H>
00029 #include <meshTools/treeBoundBox.H>
00030 #include <meshTools/treeDataFace.H>
00031 #include <OpenFOAM/Time.H>
00032 #include <meshTools/meshTools.H>
00033 #include <OpenFOAM/wordReList.H>
00034 // For 'nearInfo' helper class only
00035 #include <meshTools/directMappedPatchBase.H>
00036 
00037 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
00038 
00039 namespace Foam
00040 {
00041     defineTypeNameAndDebug(patchCloudSet, 0);
00042     addToRunTimeSelectionTable(sampledSet, patchCloudSet, word);
00043 }
00044 
00045 
00046 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
00047 
00048 void Foam::patchCloudSet::calcSamples
00049 (
00050     DynamicList<point>& samplingPts,
00051     DynamicList<label>& samplingCells,
00052     DynamicList<label>& samplingFaces,
00053     DynamicList<label>& samplingSegments,
00054     DynamicList<scalar>& samplingCurveDist
00055 ) const
00056 {
00057     if (debug)
00058     {
00059         Info<< "patchCloudSet : sampling on patches :" << endl;
00060     }
00061 
00062     // Construct search tree for all patch faces.
00063     label sz = 0;
00064     forAllConstIter(labelHashSet, patchSet_, iter)
00065     {
00066         const polyPatch& pp = mesh().boundaryMesh()[iter.key()];
00067 
00068         sz += pp.size();
00069 
00070         if (debug)
00071         {
00072             Info<< "    " << pp.name() << " size " << pp.size() << endl;
00073         }
00074     }
00075 
00076     labelList patchFaces(sz);
00077     sz = 0;
00078     treeBoundBox bb(point::max, point::min);
00079     forAllConstIter(labelHashSet, patchSet_, iter)
00080     {
00081         const polyPatch& pp = mesh().boundaryMesh()[iter.key()];
00082 
00083         forAll(pp, i)
00084         {
00085             patchFaces[sz++] = pp.start()+i;
00086         }
00087 
00088         // Do not do reduction.
00089         const boundBox patchBb(pp.localPoints(), false);
00090 
00091         bb.min() = min(bb.min(), patchBb.min());
00092         bb.max() = max(bb.max(), patchBb.max());
00093     }
00094 
00095     // Not very random
00096     Random rndGen(123456);
00097     // Make bb asymetric just to avoid problems on symmetric meshes
00098     bb = bb.extend(rndGen, 1E-4);
00099 
00100     // Make sure bb is 3D.
00101     bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00102     bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00103 
00104 
00105     indexedOctree<treeDataFace> patchTree
00106     (
00107         treeDataFace    // all information needed to search faces
00108         (
00109             false,      // do not cache bb
00110             mesh(),
00111             patchFaces  // boundary faces only
00112         ),
00113         bb,             // overall search domain
00114         8,              // maxLevel
00115         10,             // leafsize
00116         3.0             // duplicity
00117     );
00118 
00119 
00120 
00121     // All the info for nearest. Construct to miss
00122     List<directMappedPatchBase::nearInfo> nearest(sampleCoords_.size());
00123 
00124     forAll(sampleCoords_, sampleI)
00125     {
00126         const point& sample = sampleCoords_[sampleI];
00127 
00128         pointIndexHit& nearInfo = nearest[sampleI].first();
00129 
00130         // Find the nearest locally
00131         if (patchFaces.size())
00132         {
00133             nearInfo = patchTree.findNearest(sample, sqr(searchDist_));
00134         }
00135         else
00136         {
00137             nearInfo.setMiss();
00138         }
00139 
00140 
00141         // Fill in the distance field and the processor field
00142         if (!nearInfo.hit())
00143         {
00144             nearest[sampleI].second().first() = Foam::sqr(GREAT);
00145             nearest[sampleI].second().second() = Pstream::myProcNo();
00146         }
00147         else
00148         {
00149             // Set nearest to mesh face label
00150             nearInfo.setIndex(patchFaces[nearInfo.index()]);
00151 
00152             nearest[sampleI].second().first() = magSqr
00153             (
00154                 nearInfo.hitPoint()
00155               - sample
00156             );
00157             nearest[sampleI].second().second() = Pstream::myProcNo();
00158         }
00159     }
00160 
00161 
00162     // Find nearest.
00163     Pstream::listCombineGather(nearest, directMappedPatchBase::nearestEqOp());
00164     Pstream::listCombineScatter(nearest);
00165 
00166 
00167     if (debug && Pstream::master())
00168     {
00169         OFstream str
00170         (
00171             mesh().time().path()
00172           / name()
00173           + "_nearest.obj"
00174         );
00175         Info<< "Dumping mapping as lines from supplied points to"
00176             << " nearest patch face to file " << str.name() << endl;
00177 
00178         label vertI = 0;
00179 
00180         forAll(nearest, i)
00181         {
00182             if (nearest[i].first().hit())
00183             {
00184                 meshTools::writeOBJ(str, sampleCoords_[i]);
00185                 vertI++;
00186                 meshTools::writeOBJ(str, nearest[i].first().hitPoint());
00187                 vertI++;
00188                 str << "l " << vertI-1 << ' ' << vertI << nl;
00189             }
00190         }
00191     }
00192 
00193 
00194     // Store the sampling locations on the nearest processor
00195     forAll(nearest, sampleI)
00196     {
00197         const pointIndexHit& nearInfo = nearest[sampleI].first();
00198 
00199         if (nearInfo.hit())
00200         {
00201             if (nearest[sampleI].second().second() == Pstream::myProcNo())
00202             {
00203                 label faceI = nearInfo.index();
00204 
00205                 samplingPts.append(nearInfo.hitPoint());
00206                 samplingCells.append(mesh().faceOwner()[faceI]);
00207                 samplingFaces.append(faceI);
00208                 samplingSegments.append(0);
00209                 samplingCurveDist.append(1.0 * sampleI);
00210             }
00211         }
00212         else
00213         {
00214             // No processor found point near enough. Mark with special value
00215             // which is intercepted when interpolating
00216             if (Pstream::master())
00217             {
00218                 samplingPts.append(sampleCoords_[sampleI]);
00219                 samplingCells.append(-1);
00220                 samplingFaces.append(-1);
00221                 samplingSegments.append(0);
00222                 samplingCurveDist.append(1.0 * sampleI);
00223             }
00224         }
00225     }
00226 }
00227 
00228 
00229 void Foam::patchCloudSet::genSamples()
00230 {
00231     // Storage for sample points
00232     DynamicList<point> samplingPts;
00233     DynamicList<label> samplingCells;
00234     DynamicList<label> samplingFaces;
00235     DynamicList<label> samplingSegments;
00236     DynamicList<scalar> samplingCurveDist;
00237 
00238     calcSamples
00239     (
00240         samplingPts,
00241         samplingCells,
00242         samplingFaces,
00243         samplingSegments,
00244         samplingCurveDist
00245     );
00246 
00247     samplingPts.shrink();
00248     samplingCells.shrink();
00249     samplingFaces.shrink();
00250     samplingSegments.shrink();
00251     samplingCurveDist.shrink();
00252 
00253     setSamples
00254     (
00255         samplingPts,
00256         samplingCells,
00257         samplingFaces,
00258         samplingSegments,
00259         samplingCurveDist
00260     );
00261 }
00262 
00263 
00264 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
00265 
00266 Foam::patchCloudSet::patchCloudSet
00267 (
00268     const word& name,
00269     const polyMesh& mesh,
00270     meshSearch& searchEngine,
00271     const word& axis,
00272     const List<point>& sampleCoords,
00273     const labelHashSet& patchSet,
00274     const scalar searchDist
00275 )
00276 :
00277     sampledSet(name, mesh, searchEngine, axis),
00278     sampleCoords_(sampleCoords),
00279     patchSet_(patchSet),
00280     searchDist_(searchDist)
00281 {
00282     genSamples();
00283 
00284     if (debug)
00285     {
00286         write(Info);
00287     }
00288 }
00289 
00290 
00291 Foam::patchCloudSet::patchCloudSet
00292 (
00293     const word& name,
00294     const polyMesh& mesh,
00295     meshSearch& searchEngine,
00296     const dictionary& dict
00297 )
00298 :
00299     sampledSet(name, mesh, searchEngine, dict),
00300     sampleCoords_(dict.lookup("points")),
00301     patchSet_
00302     (
00303         mesh.boundaryMesh().patchSet
00304         (
00305             wordList(dict.lookup("patches"))
00306         )
00307     ),
00308     searchDist_(readScalar(dict.lookup("maxDistance")))
00309 {
00310     genSamples();
00311 
00312     if (debug)
00313     {
00314         write(Info);
00315     }
00316 }
00317 
00318 
00319 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
00320 
00321 Foam::patchCloudSet::~patchCloudSet()
00322 {}
00323 
00324 
00325 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
00326 
00327 Foam::point Foam::patchCloudSet::getRefPoint(const List<point>& pts) const
00328 {
00329     if (pts.size())
00330     {
00331         // Use first samplePt as starting point
00332         return pts[0];
00333     }
00334     else
00335     {
00336         return vector::zero;
00337     }
00338 }
00339 
00340 
00341 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines