1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
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 "sampledIsoSurface.H"
27 #include "dictionary.H"
28 #include "volFields.H"
29 #include "volPointInterpolation.H"
30 #include "addToRunTimeSelectionTable.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
36 defineTypeNameAndDebug(sampledIsoSurface, 0);
37 addNamedToRunTimeSelectionTable
46 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
48 void Foam::sampledIsoSurface::getIsoFields() const
50 const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
55 if (fvm.foundObject<volScalarField>(isoField_))
59 Info<< "sampledIsoSurface::getIsoField() : lookup volField "
62 storedVolFieldPtr_.clear();
63 volFieldPtr_ = &fvm.lookupObject<volScalarField>(isoField_);
67 // Bit of a hack. Read field and store.
71 Info<< "sampledIsoSurface::getIsoField() : checking "
72 << isoField_ << " for same time " << fvm.time().timeName()
78 storedVolFieldPtr_.empty()
79 || (fvm.time().timeName() != storedVolFieldPtr_().instance())
84 Info<< "sampledIsoSurface::getIsoField() : reading volField "
85 << isoField_ << " from time " << fvm.time().timeName()
89 storedVolFieldPtr_.reset
96 fvm.time().timeName(),
105 volFieldPtr_ = storedVolFieldPtr_.operator->();
114 if (!subMeshPtr_.valid())
116 word pointFldName = "volPointInterpolate(" + isoField_ + ')';
118 if (fvm.foundObject<pointScalarField>(pointFldName))
122 Info<< "sampledIsoSurface::getIsoField() : lookup pointField "
123 << pointFldName << endl;
125 pointFieldPtr_ = &fvm.lookupObject<pointScalarField>(pointFldName);
129 // Not in registry. Interpolate.
133 Info<< "sampledIsoSurface::getIsoField() : checking pointField "
134 << pointFldName << " for same time "
135 << fvm.time().timeName() << endl;
140 storedPointFieldPtr_.empty()
141 || (fvm.time().timeName() != storedPointFieldPtr_().instance())
146 Info<< "sampledIsoSurface::getIsoField() :"
147 << " interpolating volField " << volFieldPtr_->name()
148 << " to get pointField " << pointFldName << endl;
151 storedPointFieldPtr_.reset
153 volPointInterpolation::New(fvm)
154 .interpolate(*volFieldPtr_).ptr()
156 storedPointFieldPtr_->checkOut();
157 pointFieldPtr_ = storedPointFieldPtr_.operator->();
162 // If averaging redo the volField. Can only be done now since needs the
166 storedVolFieldPtr_.reset
168 pointAverage(*pointFieldPtr_).ptr()
170 volFieldPtr_ = storedVolFieldPtr_.operator->();
176 Info<< "sampledIsoSurface::getIsoField() : volField "
177 << volFieldPtr_->name() << " min:" << min(*volFieldPtr_).value()
178 << " max:" << max(*volFieldPtr_).value() << endl;
179 Info<< "sampledIsoSurface::getIsoField() : pointField "
180 << pointFieldPtr_->name()
181 << " min:" << gMin(pointFieldPtr_->internalField())
182 << " max:" << gMax(pointFieldPtr_->internalField()) << endl;
187 // Get subMesh variants
188 const fvMesh& subFvm = subMeshPtr_().subMesh();
190 // Either lookup on the submesh or subset the whole-mesh volField
192 if (subFvm.foundObject<volScalarField>(isoField_))
196 Info<< "sampledIsoSurface::getIsoField() :"
197 << " submesh lookup volField "
198 << isoField_ << endl;
200 storedVolSubFieldPtr_.clear();
201 volSubFieldPtr_ = &subFvm.lookupObject<volScalarField>(isoField_);
207 Info<< "sampledIsoSurface::getIsoField() : subsetting volField "
208 << isoField_ << endl;
210 storedVolSubFieldPtr_.reset
212 subMeshPtr_().interpolate
217 storedVolSubFieldPtr_->checkOut();
218 volSubFieldPtr_ = storedVolSubFieldPtr_.operator->();
222 // Pointfield on submesh
225 "volPointInterpolate("
226 + volSubFieldPtr_->name()
229 if (subFvm.foundObject<pointScalarField>(pointFldName))
233 Info<< "sampledIsoSurface::getIsoField() :"
234 << " submesh lookup pointField " << pointFldName << endl;
236 storedPointSubFieldPtr_.clear();
237 pointSubFieldPtr_ = &subFvm.lookupObject<pointScalarField>
246 Info<< "sampledIsoSurface::getIsoField() :"
247 << " interpolating submesh volField "
248 << volSubFieldPtr_->name()
249 << " to get submesh pointField " << pointFldName << endl;
251 storedPointSubFieldPtr_.reset
253 volPointInterpolation::New
256 ).interpolate(*volSubFieldPtr_).ptr()
258 storedPointSubFieldPtr_->checkOut();
259 pointSubFieldPtr_ = storedPointSubFieldPtr_.operator->();
264 // If averaging redo the volField. Can only be done now since needs the
268 storedVolSubFieldPtr_.reset
270 pointAverage(*pointSubFieldPtr_).ptr()
272 volSubFieldPtr_ = storedVolSubFieldPtr_.operator->();
278 Info<< "sampledIsoSurface::getIsoField() : volSubField "
279 << volSubFieldPtr_->name()
280 << " min:" << min(*volSubFieldPtr_).value()
281 << " max:" << max(*volSubFieldPtr_).value() << endl;
282 Info<< "sampledIsoSurface::getIsoField() : pointSubField "
283 << pointSubFieldPtr_->name()
284 << " min:" << gMin(pointSubFieldPtr_->internalField())
285 << " max:" << gMax(pointSubFieldPtr_->internalField()) << endl;
291 bool Foam::sampledIsoSurface::updateGeometry() const
293 const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
296 if (fvm.time().timeIndex() == prevTimeIndex_)
302 if (zoneID_.index() != -1 && !subMeshPtr_.valid())
304 const polyBoundaryMesh& patches = mesh().boundaryMesh();
306 // Patch to put exposed internal faces into
307 const label exposedPatchI = patches.findPatchID(exposedPatchName_);
311 Info<< "Allocating subset of size "
312 << mesh().cellZones()[zoneID_.index()].size()
313 << " with exposed faces into patch "
314 << patches[exposedPatchI].name() << endl;
319 new fvMeshSubset(fvm)
321 subMeshPtr_().setLargeCellSubset
323 labelHashSet(mesh().cellZones()[zoneID_.index()]),
329 prevTimeIndex_ = fvm.time().timeIndex();
332 // Clear any stored topo
336 // Clear derived data
339 if (subMeshPtr_.valid())
371 Pout<< "sampledIsoSurface::updateGeometry() : constructed iso:"
373 << " regularise : " << regularise_ << nl
374 << " average : " << average_ << nl
375 << " isoField : " << isoField_ << nl
376 << " isoValue : " << isoVal_ << nl;
377 if (subMeshPtr_.valid())
379 Pout<< " zone size : " << subMeshPtr_().subMesh().nCells()
382 Pout<< " points : " << points().size() << nl
383 << " tris : " << surface().size() << nl
384 << " cut cells : " << surface().meshCells().size()
392 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
394 Foam::sampledIsoSurface::sampledIsoSurface
397 const polyMesh& mesh,
398 const dictionary& dict
401 sampledSurface(name, mesh, dict),
402 isoField_(dict.lookup("isoField")),
403 isoVal_(readScalar(dict.lookup("isoValue"))),
404 mergeTol_(dict.lookupOrDefault("mergeTol", 1E-6)),
405 regularise_(dict.lookupOrDefault("regularise", true)),
406 average_(dict.lookupOrDefault("average", false)),
407 zoneID_(dict.lookupOrDefault("zone", word::null), mesh.cellZones()),
408 exposedPatchName_(word::null),
412 storedVolFieldPtr_(NULL),
414 storedPointFieldPtr_(NULL),
417 if (!sampledSurface::interpolate())
421 "sampledIsoSurface::sampledIsoSurface"
422 "(const word&, const polyMesh&, const dictionary&)",
424 ) << "Non-interpolated iso surface not supported since triangles"
425 << " span across cells." << exit(FatalIOError);
428 if (zoneID_.index() != -1)
430 dict.lookup("exposedPatchName") >> exposedPatchName_;
432 if (mesh.boundaryMesh().findPatchID(exposedPatchName_) == -1)
436 "sampledIsoSurface::sampledIsoSurface"
437 "(const word&, const polyMesh&, const dictionary&)",
439 ) << "Cannot find patch " << exposedPatchName_
440 << " in which to put exposed faces." << endl
441 << "Valid patches are " << mesh.boundaryMesh().names()
442 << exit(FatalIOError);
445 if (debug && zoneID_.index() != -1)
447 Info<< "Restricting to cellZone " << zoneID_.name()
448 << " with exposed internal faces into patch "
449 << exposedPatchName_ << endl;
455 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
457 Foam::sampledIsoSurface::~sampledIsoSurface()
461 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
463 bool Foam::sampledIsoSurface::needsUpdate() const
465 const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
467 return fvm.time().timeIndex() != prevTimeIndex_;
471 bool Foam::sampledIsoSurface::expire()
477 // Clear derived data
480 // already marked as expired
481 if (prevTimeIndex_ == -1)
492 bool Foam::sampledIsoSurface::update()
494 return updateGeometry();
498 Foam::tmp<Foam::scalarField> Foam::sampledIsoSurface::sample
500 const volScalarField& vField
503 return sampleField(vField);
507 Foam::tmp<Foam::vectorField> Foam::sampledIsoSurface::sample
509 const volVectorField& vField
512 return sampleField(vField);
516 Foam::tmp<Foam::sphericalTensorField> Foam::sampledIsoSurface::sample
518 const volSphericalTensorField& vField
521 return sampleField(vField);
525 Foam::tmp<Foam::symmTensorField> Foam::sampledIsoSurface::sample
527 const volSymmTensorField& vField
530 return sampleField(vField);
534 Foam::tmp<Foam::tensorField> Foam::sampledIsoSurface::sample
536 const volTensorField& vField
539 return sampleField(vField);
543 Foam::tmp<Foam::scalarField> Foam::sampledIsoSurface::interpolate
545 const interpolation<scalar>& interpolator
548 return interpolateField(interpolator);
552 Foam::tmp<Foam::vectorField> Foam::sampledIsoSurface::interpolate
554 const interpolation<vector>& interpolator
557 return interpolateField(interpolator);
560 Foam::tmp<Foam::sphericalTensorField> Foam::sampledIsoSurface::interpolate
562 const interpolation<sphericalTensor>& interpolator
565 return interpolateField(interpolator);
569 Foam::tmp<Foam::symmTensorField> Foam::sampledIsoSurface::interpolate
571 const interpolation<symmTensor>& interpolator
574 return interpolateField(interpolator);
578 Foam::tmp<Foam::tensorField> Foam::sampledIsoSurface::interpolate
580 const interpolation<tensor>& interpolator
583 return interpolateField(interpolator);
587 void Foam::sampledIsoSurface::print(Ostream& os) const
589 os << "sampledIsoSurface: " << name() << " :"
590 << " field :" << isoField_
591 << " value :" << isoVal_;
592 //<< " faces:" << faces().size() // note: possibly no geom yet
593 //<< " points:" << points().size();
597 // ************************************************************************* //