1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "sampledSurfaces.H"
27 #include "volFields.H"
28 #include "dictionary.H"
31 #include "ListListOps.H"
32 #include "mergePoints.H"
33 #include "volPointInterpolation.H"
35 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 //- Used to offset faces in Pstream::combineOffset
52 face result(x.size());
56 result[xI] = x[xI] + offset;
63 defineTypeNameAndDebug(sampledSurfaces, 0);
67 bool Foam::sampledSurfaces::verbose_(false);
68 Foam::scalar Foam::sampledSurfaces::mergeTol_(1e-10);
70 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
72 Foam::label Foam::sampledSurfaces::classifyFieldTypes()
76 scalarFields_.clear();
77 vectorFields_.clear();
78 sphericalTensorFields_.clear();
79 symmTensorFields_.clear();
80 tensorFields_.clear();
82 forAll(fieldNames_, fieldI)
84 const word& fieldName = fieldNames_[fieldI];
87 // check files for a particular time
93 mesh_.time().timeName(),
102 fieldType = io.headerClassName();
111 // check objectRegistry
112 objectRegistry::const_iterator iter = mesh_.find(fieldName);
114 if (iter != mesh_.objectRegistry::end())
116 fieldType = iter()->type();
125 if (fieldType == volScalarField::typeName)
127 scalarFields_.append(fieldName);
130 else if (fieldType == volVectorField::typeName)
132 vectorFields_.append(fieldName);
135 else if (fieldType == volSphericalTensorField::typeName)
137 sphericalTensorFields_.append(fieldName);
140 else if (fieldType == volSymmTensorField::typeName)
142 symmTensorFields_.append(fieldName);
145 else if (fieldType == volTensorField::typeName)
147 tensorFields_.append(fieldName);
157 void Foam::sampledSurfaces::writeGeometry() const
159 // Write to time directory under outputPath_
160 // skip surface without faces (eg, a failed cut-plane)
162 const fileName outputDir = outputPath_/mesh_.time().timeName();
166 const sampledSurface& s = operator[](surfI);
168 if (Pstream::parRun())
170 if (Pstream::master() && mergeList_[surfI].faces.size())
172 genericFormatter_->write
176 mergeList_[surfI].points,
177 mergeList_[surfI].faces
181 else if (s.faces().size())
183 genericFormatter_->write
195 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
197 Foam::sampledSurfaces::sampledSurfaces
200 const objectRegistry& obr,
201 const dictionary& dict,
202 const bool loadFromFiles
205 PtrList<sampledSurface>(),
207 mesh_(refCast<const fvMesh>(obr)),
208 loadFromFiles_(loadFromFiles),
209 outputPath_(fileName::null),
211 interpolationScheme_(word::null),
212 writeFormat_(word::null),
214 genericFormatter_(NULL),
217 sphericalTensorFields_(),
221 if (Pstream::parRun())
223 outputPath_ = mesh_.time().path()/".."/name_;
227 outputPath_ = mesh_.time().path()/name_;
234 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
236 Foam::sampledSurfaces::~sampledSurfaces()
240 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
242 void Foam::sampledSurfaces::verbose(const bool verbosity)
244 verbose_ = verbosity;
248 void Foam::sampledSurfaces::execute()
250 // Do nothing - only valid on write
254 void Foam::sampledSurfaces::end()
256 // Do nothing - only valid on write
260 void Foam::sampledSurfaces::write()
264 // finalize surfaces, merge points etc.
267 const label nFields = classifyFieldTypes();
269 if (Pstream::master())
273 Pout<< "timeName = " << mesh_.time().timeName() << nl
274 << "scalarFields " << scalarFields_ << nl
275 << "vectorFields " << vectorFields_ << nl
276 << "sphTensorFields " << sphericalTensorFields_ << nl
277 << "symTensorFields " << symmTensorFields_ <<nl
278 << "tensorFields " << tensorFields_ <<nl;
280 Pout<< "Creating directory "
281 << outputPath_/mesh_.time().timeName() << nl << endl;
285 mkDir(outputPath_/mesh_.time().timeName());
288 // write geometry first if required, or when no fields would otherwise
290 if (nFields == 0 || genericFormatter_->separateFiles())
295 sampleAndWrite(scalarFields_);
296 sampleAndWrite(vectorFields_);
297 sampleAndWrite(sphericalTensorFields_);
298 sampleAndWrite(symmTensorFields_);
299 sampleAndWrite(tensorFields_);
304 void Foam::sampledSurfaces::read(const dictionary& dict)
306 fieldNames_ = wordList(dict.lookup("fields"));
308 const label nFields = fieldNames_.size();
310 scalarFields_.reset(nFields);
311 vectorFields_.reset(nFields);
312 sphericalTensorFields_.reset(nFields);
313 symmTensorFields_.reset(nFields);
314 tensorFields_.reset(nFields);
316 interpolationScheme_ = dict.lookupOrDefault<word>
318 "interpolationScheme",
321 writeFormat_ = dict.lookupOrDefault<word>
328 // define the generic (geometry) writer
329 genericFormatter_ = surfaceWriter<bool>::New(writeFormat_);
332 PtrList<sampledSurface> newList
334 dict.lookup("surfaces"),
335 sampledSurface::iNew(mesh_)
340 if (Pstream::parRun())
342 mergeList_.setSize(size());
345 // ensure all surfaces and merge information are expired
348 if (Pstream::master() && debug)
350 Pout<< "sample fields:" << fieldNames_ << nl
351 << "sample surfaces:" << nl << "(" << nl;
355 Pout<< " " << operator[](surfI) << endl;
362 void Foam::sampledSurfaces::updateMesh(const mapPolyMesh&)
368 void Foam::sampledSurfaces::movePoints(const pointField&)
374 void Foam::sampledSurfaces::readUpdate(const polyMesh::readUpdateState state)
376 if (state != polyMesh::UNCHANGED)
383 bool Foam::sampledSurfaces::needsUpdate() const
387 if (operator[](surfI).needsUpdate())
397 bool Foam::sampledSurfaces::expire()
399 bool justExpired = false;
403 if (operator[](surfI).expire())
408 // clear merge information
409 if (Pstream::parRun())
411 mergeList_[surfI].clear();
415 // reset interpolation
416 pointMesh::Delete(mesh_);
417 volPointInterpolation::Delete(mesh_);
419 // true if any surfaces just expired
424 bool Foam::sampledSurfaces::update()
426 bool updated = false;
433 // serial: quick and easy, no merging required
434 if (!Pstream::parRun())
438 if (operator[](surfI).update())
447 // dimension as fraction of mesh bounding box
448 scalar mergeDim = mergeTol_ * mesh_.globalData().bb().mag();
450 if (Pstream::master() && debug)
452 Pout<< nl << "Merging all points within "
453 << mergeDim << " meter" << endl;
458 sampledSurface& s = operator[](surfI);
470 // Collect points from all processors
471 List<pointField> gatheredPoints(Pstream::nProcs());
472 gatheredPoints[Pstream::myProcNo()] = s.points();
473 Pstream::gatherList(gatheredPoints);
475 if (Pstream::master())
477 mergeList_[surfI].points = ListListOps::combine<pointField>
480 accessOp<pointField>()
484 // Collect faces from all processors and renumber using sizes of
486 List<faceList> gatheredFaces(Pstream::nProcs());
487 gatheredFaces[Pstream::myProcNo()] = s.faces();
488 Pstream::gatherList(gatheredFaces);
490 if (Pstream::master())
492 mergeList_[surfI].faces = static_cast<const faceList&>
494 ListListOps::combineOffset<faceList>
497 ListListOps::subSizes
500 accessOp<pointField>()
502 accessOp<faceList>(),
508 pointField newPoints;
511 bool hasMerged = mergePoints
513 mergeList_[surfI].points,
522 // Store point mapping
523 mergeList_[surfI].pointsMap.transfer(oldToNew);
526 mergeList_[surfI].points.transfer(newPoints);
529 faceList& faces = mergeList_[surfI].faces;
533 inplaceRenumber(mergeList_[surfI].pointsMap, faces[faceI]);
536 if (Pstream::master() && debug)
538 Pout<< "For surface " << surfI << " merged from "
539 << mergeList_[surfI].pointsMap.size() << " points down to "
540 << mergeList_[surfI].points.size() << " points" << endl;
549 // ************************************************************************* //