00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00035 #include <meshTools/directMappedPatchBase.H>
00036
00037
00038
00039 namespace Foam
00040 {
00041 defineTypeNameAndDebug(patchCloudSet, 0);
00042 addToRunTimeSelectionTable(sampledSet, patchCloudSet, word);
00043 }
00044
00045
00046
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
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
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
00096 Random rndGen(123456);
00097
00098 bb = bb.extend(rndGen, 1E-4);
00099
00100
00101 bb.min() -= point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00102 bb.max() += point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
00103
00104
00105 indexedOctree<treeDataFace> patchTree
00106 (
00107 treeDataFace
00108 (
00109 false,
00110 mesh(),
00111 patchFaces
00112 ),
00113 bb,
00114 8,
00115 10,
00116 3.0
00117 );
00118
00119
00120
00121
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
00131 if (patchFaces.size())
00132 {
00133 nearInfo = patchTree.findNearest(sample, sqr(searchDist_));
00134 }
00135 else
00136 {
00137 nearInfo.setMiss();
00138 }
00139
00140
00141
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
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
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
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
00215
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
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
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
00320
00321 Foam::patchCloudSet::~patchCloudSet()
00322 {}
00323
00324
00325
00326
00327 Foam::point Foam::patchCloudSet::getRefPoint(const List<point>& pts) const
00328 {
00329 if (pts.size())
00330 {
00331
00332 return pts[0];
00333 }
00334 else
00335 {
00336 return vector::zero;
00337 }
00338 }
00339
00340
00341