1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011-2011 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
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
13 the Free Software Foundation, either version 3 of the License, or
14 (at your 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
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "patchCloudSet.H"
28 #include "addToRunTimeSelectionTable.H"
29 #include "pointIndexHit.H"
31 #include "treeBoundBox.H"
32 #include "indexedOctree.H"
33 #include "treeDataFace.H"
35 #include "meshTools.H"
36 #include "wordReList.H"
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
42 defineTypeNameAndDebug(patchCloudSet, 0);
43 addToRunTimeSelectionTable(sampledSet, patchCloudSet, word);
46 //- Helper class for finding nearest
48 // - point+local index
51 typedef Tuple2<pointIndexHit, Tuple2<scalar, label> > nearInfo;
58 void operator()(nearInfo& x, const nearInfo& y) const
66 else if (y.second().first() < x.second().first())
77 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
79 void Foam::patchCloudSet::calcSamples
81 DynamicList<point>& samplingPts,
82 DynamicList<label>& samplingCells,
83 DynamicList<label>& samplingFaces,
84 DynamicList<label>& samplingSegments,
85 DynamicList<scalar>& samplingCurveDist
90 Info<< "patchCloudSet : sampling on patches :" << endl;
93 // Construct search tree for all patch faces.
95 forAllConstIter(labelHashSet, patchSet_, iter)
97 const polyPatch& pp = mesh().boundaryMesh()[iter.key()];
103 Info<< " " << pp.name() << " size " << pp.size() << endl;
107 labelList patchFaces(sz);
109 treeBoundBox bb(point::max, point::min);
110 forAllConstIter(labelHashSet, patchSet_, iter)
112 const polyPatch& pp = mesh().boundaryMesh()[iter.key()];
116 patchFaces[sz++] = pp.start()+i;
119 const boundBox patchBb(pp.localPoints());
121 bb.min() = min(bb.min(), patchBb.min());
122 bb.max() = max(bb.max(), patchBb.max());
126 Random rndGen(123456);
127 // Make bb asymetric just to avoid problems on symmetric meshes
128 bb = bb.extend(rndGen, 1E-4);
130 bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
131 bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
134 indexedOctree<treeDataFace> patchTree
136 treeDataFace // all information needed to search faces
138 false, // do not cache bb
140 patchFaces // boundary faces only
142 bb, // overall search domain
150 // All the info for nearest. Construct to miss
151 List<nearInfo> nearest(sampleCoords_.size());
153 forAll(sampleCoords_, sampleI)
155 const point& sample = sampleCoords_[sampleI];
157 pointIndexHit& nearInfo = nearest[sampleI].first();
159 // Find the nearest locally
160 nearInfo = patchTree.findNearest(sample, magSqr(bb.span()));
162 // Fill in the distance field and the processor field
165 nearest[sampleI].second().first() = Foam::sqr(GREAT);
166 nearest[sampleI].second().second() = Pstream::myProcNo();
170 // Set nearest to mesh face label
171 nearInfo.setIndex(patchFaces[nearInfo.index()]);
173 nearest[sampleI].second().first() = magSqr
178 nearest[sampleI].second().second() = Pstream::myProcNo();
184 Pstream::listCombineGather(nearest, nearestEqOp());
185 Pstream::listCombineScatter(nearest);
188 if (debug && Pstream::master())
196 Info<< "Dumping mapping as lines from supplied points to"
197 << " nearest patch face to file " << str.name() << endl;
203 meshTools::writeOBJ(str, sampleCoords_[i]);
205 meshTools::writeOBJ(str, nearest[i].first().hitPoint());
207 str << "l " << vertI-1 << ' ' << vertI << nl;
212 // Store the sampling locations on the nearest processor
213 forAll(nearest, sampleI)
215 if (nearest[sampleI].second().second() == Pstream::myProcNo())
217 const pointIndexHit& nearInfo = nearest[sampleI].first();
219 label faceI = nearInfo.index();
221 samplingPts.append(nearInfo.hitPoint());
222 samplingCells.append(mesh().faceOwner()[faceI]);
223 samplingFaces.append(faceI);
224 samplingSegments.append(0);
225 samplingCurveDist.append(1.0 * sampleI);
231 void Foam::patchCloudSet::genSamples()
233 // Storage for sample points
234 DynamicList<point> samplingPts;
235 DynamicList<label> samplingCells;
236 DynamicList<label> samplingFaces;
237 DynamicList<label> samplingSegments;
238 DynamicList<scalar> samplingCurveDist;
249 samplingPts.shrink();
250 samplingCells.shrink();
251 samplingFaces.shrink();
252 samplingSegments.shrink();
253 samplingCurveDist.shrink();
266 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
268 Foam::patchCloudSet::patchCloudSet
271 const polyMesh& mesh,
272 meshSearch& searchEngine,
274 const List<point>& sampleCoords,
275 const labelHashSet& patchSet
278 sampledSet(name, mesh, searchEngine, axis),
279 sampleCoords_(sampleCoords),
291 Foam::patchCloudSet::patchCloudSet
294 const polyMesh& mesh,
295 meshSearch& searchEngine,
296 const dictionary& dict
299 sampledSet(name, mesh, searchEngine, dict),
300 sampleCoords_(dict.lookup("points")),
303 mesh.boundaryMesh().patchSet
305 wordList(dict.lookup("patches"))
318 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
320 Foam::patchCloudSet::~patchCloudSet()
324 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
326 Foam::point Foam::patchCloudSet::getRefPoint(const List<point>& pts) const
330 // Use first samplePt as starting point
340 // ************************************************************************* //