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 "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
00035
00036 namespace Foam
00037 {
00038 defineTypeNameAndDebug(sampledTriSurfaceMesh, 0);
00039 addToRunTimeSelectionTable
00040 (
00041 sampledSurface,
00042 sampledTriSurfaceMesh,
00043 word
00044 );
00045
00046
00047
00048
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
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(),
00083 "triSurface",
00084 mesh,
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(),
00110 "triSurface",
00111 mesh,
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
00124
00125 Foam::sampledTriSurfaceMesh::~sampledTriSurfaceMesh()
00126 {}
00127
00128
00129
00130
00131 bool Foam::sampledTriSurfaceMesh::needsUpdate() const
00132 {
00133 return needsUpdate_;
00134 }
00135
00136
00137 bool Foam::sampledTriSurfaceMesh::expire()
00138 {
00139
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
00164
00165 const pointField& fc = surface_.faceCentres();
00166
00167 meshSearch meshSearcher(mesh(), false);
00168
00169 const indexedOctree<treeDataPoint>& cellCentreTree =
00170 meshSearcher.cellCentreTree();
00171
00172
00173
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
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
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
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
00230
00231
00232 const triSurface& s = surface_;
00233
00234
00235 labelList faceMap(s.size());
00236
00237 labelList pointMap(s.points().size());
00238
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
00267 cellLabels_ = UIndirectList<label>(cellLabels_, faceMap)();
00268
00269
00270 pointToFace_.setSize(pointMap.size());
00271
00272
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