Files
openfoam/src/surfMesh/writers/surfaceWriter.C
Mark Olesen 70a32fa21b BUG: surfaceWriter::expire() should not affect the expected nFields() count
- the writer nFields() is a separate type of accounting (currently
  only needed by VTK legacy) and is independent of the geometry.
2019-04-05 12:03:41 +02:00

562 lines
12 KiB
C

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "surfaceWriter.H"
#include "proxySurfaceWriter.H"
#include "MeshedSurfaceProxy.H"
#include "Time.H"
#include "globalIndex.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(surfaceWriter, 0);
defineRunTimeSelectionTable(surfaceWriter, word);
defineRunTimeSelectionTable(surfaceWriter, wordDict);
}
Foam::scalar Foam::surfaceWriter::defaultMergeDim = 1e-8;
const Foam::meshedSurf::emptySurface Foam::surfaceWriter::emptySurface_;
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::surfaceWriter::supportedType(const word& writeType)
{
return
(
wordConstructorTablePtr_->found(writeType)
|| wordDictConstructorTablePtr_->found(writeType)
|| MeshedSurfaceProxy<face>::canWriteType(writeType)
);
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New(const word& writeType)
{
// Constructors without dictionary options
auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
if (!cstrIter.found())
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Generally unknown, but handle via 'proxy' handler
return autoPtr<surfaceWriter>
(
new surfaceWriters::proxyWriter(writeType)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid write types : "
<< flatOutput(wordConstructorTablePtr_->sortedToc()) << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< exit(FatalError);
}
return autoPtr<surfaceWriter>(cstrIter()());
}
Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New
(
const word& writeType,
const dictionary& writeOpts
)
{
// Constructors with dictionary options
auto cstrIter2 = wordDictConstructorTablePtr_->cfind(writeType);
if (cstrIter2.found())
{
return autoPtr<surfaceWriter>(cstrIter2()(writeOpts));
}
// Constructors without dictionary options
auto cstrIter = wordConstructorTablePtr_->cfind(writeType);
if (!cstrIter.found())
{
if (MeshedSurfaceProxy<face>::canWriteType(writeType))
{
// Generally unknown, but handle via 'proxy' handler
return autoPtr<surfaceWriter>
(
new surfaceWriters::proxyWriter(writeType, writeOpts)
);
}
FatalErrorInFunction
<< "Unknown write type \"" << writeType << "\"\n\n"
<< "Valid write types : "
<< wordConstructorTablePtr_->sortedToc() << nl
<< "Valid proxy types : "
<< MeshedSurfaceProxy<face>::writeTypes() << endl
<< exit(FatalError);
}
return autoPtr<surfaceWriter>(cstrIter()());
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriter::surfaceWriter()
:
surf_(std::cref<meshedSurf>(emptySurface_)),
surfComp_(),
useComponents_(false),
upToDate_(false),
wroteGeom_(false),
parallel_(true),
useTimeDir_(false),
isPointData_(false),
verbose_(false),
nFields_(0),
mergeDim_(defaultMergeDim),
merged_(),
currTime_(),
outputPath_()
{
surfaceWriter::close();
}
Foam::surfaceWriter::surfaceWriter(const dictionary& options)
:
surfaceWriter()
{
options.readIfPresent("verbose", verbose_);
}
Foam::surfaceWriter::surfaceWriter
(
const meshedSurf& surf,
bool parallel,
const dictionary& options
)
:
surfaceWriter(options)
{
setSurface(surf, parallel);
}
Foam::surfaceWriter::surfaceWriter
(
const pointField& points,
const faceList& faces,
bool parallel,
const dictionary& options
)
:
surfaceWriter(options)
{
setSurface(points, faces, parallel);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::surfaceWriter::~surfaceWriter()
{
close();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::surfaceWriter::setTime(const instant& inst)
{
currTime_ = inst;
}
void Foam::surfaceWriter::setTime(scalar timeValue)
{
currTime_ = instant(timeValue);
}
void Foam::surfaceWriter::setTime(scalar timeValue, const word& timeName)
{
currTime_.value() = timeValue;
currTime_.name() = timeName;
}
void Foam::surfaceWriter::unsetTime()
{
currTime_.value() = 0;
currTime_.name().clear();
}
void Foam::surfaceWriter::beginTime(const Time& t)
{
setTime(t.value(), t.timeName());
}
void Foam::surfaceWriter::beginTime(const instant& inst)
{
setTime(inst);
}
void Foam::surfaceWriter::endTime()
{
unsetTime();
}
void Foam::surfaceWriter::open(const fileName& outputPath)
{
outputPath_ = outputPath;
wroteGeom_ = false;
}
void Foam::surfaceWriter::open
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel
)
{
close();
setSurface(surf, parallel);
open(outputPath);
}
void Foam::surfaceWriter::open
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel
)
{
close();
setSurface(points, faces, parallel);
open(outputPath);
}
void Foam::surfaceWriter::open
(
const meshedSurf& surf,
const fileName& outputPath
)
{
close();
setSurface(surf, parallel_);
open(outputPath);
}
void Foam::surfaceWriter::open
(
const pointField& points,
const faceList& faces,
const fileName& outputPath
)
{
close();
setSurface(points, faces, parallel_);
open(outputPath);
}
void Foam::surfaceWriter::close()
{
outputPath_.clear();
wroteGeom_ = false;
}
void Foam::surfaceWriter::clear()
{
close();
expire();
useComponents_ = false;
surf_ = std::cref<meshedSurf>(emptySurface_);
surfComp_.clear();
}
void Foam::surfaceWriter::setSurface
(
const meshedSurf& surf,
bool parallel
)
{
expire();
useComponents_ = false;
surf_ = std::cref<meshedSurf>(surf);
surfComp_.clear();
parallel_ = (parallel && Pstream::parRun());
}
void Foam::surfaceWriter::setSurface
(
const pointField& points,
const faceList& faces,
bool parallel
)
{
expire();
useComponents_ = true;
surf_ = std::cref<meshedSurf>(emptySurface_);
surfComp_.reset(points, faces);
parallel_ = (parallel && Pstream::parRun());
}
void Foam::surfaceWriter::setSurface
(
const meshedSurf& surf
)
{
setSurface(surf, parallel_);
}
void Foam::surfaceWriter::setSurface
(
const pointField& points,
const faceList& faces
)
{
setSurface(points, faces, parallel_);
}
bool Foam::surfaceWriter::needsUpdate() const
{
return !upToDate_;
}
bool Foam::surfaceWriter::wroteData() const
{
return wroteGeom_;
}
bool Foam::surfaceWriter::expire()
{
const bool changed = upToDate_;
upToDate_ = false;
wroteGeom_ = false;
merged_.clear();
// Field count (nFields_) is a different type of accounting
// and is unaffected by geometry changes
return changed;
}
bool Foam::surfaceWriter::hasSurface() const
{
return (useComponents_ || (&emptySurface_ != &(surf_.get())));
}
bool Foam::surfaceWriter::empty() const
{
const bool value =
(
useComponents_
? surfComp_.faces().empty()
: surf_.get().faces().empty()
);
return (parallel_ ? returnReduce(value, andOp<bool>()) : value);
}
Foam::label Foam::surfaceWriter::size() const
{
const bool value =
(
useComponents_
? surfComp_.faces().empty()
: surf_.get().faces().empty()
);
return (parallel_ ? returnReduce(value, sumOp<label>()) : value);
}
bool Foam::surfaceWriter::checkOpen() const
{
if (outputPath_.empty())
{
FatalErrorInFunction
<< type() << " : Attempted to write without a path" << nl
<< exit(FatalIOError);
}
return !outputPath_.empty();
}
bool Foam::surfaceWriter::merge() const
{
bool changed = false;
if (parallel_ && Pstream::parRun() && !upToDate_)
{
if (useComponents_)
{
changed = merged_.merge(surfComp_, mergeDim_);
}
else
{
changed = merged_.merge(surf_.get(), mergeDim_);
}
}
upToDate_ = true;
if (changed)
{
wroteGeom_ = false;
}
return changed;
}
const Foam::meshedSurf& Foam::surfaceWriter::surface() const
{
merge();
if (parallel_ && Pstream::parRun())
{
return merged_;
}
if (useComponents_)
{
return surfComp_;
}
else
{
return surf_.get();
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::surfaceWriter::mergeFieldTemplate
(
const Field<Type>& fld
) const
{
if (parallel_ && Pstream::parRun())
{
// Ensure geometry is also merged
merge();
// Gather all values
auto tfield = tmp<Field<Type>>::New();
auto& allFld = tfield.ref();
globalIndex::gatherOp(fld, allFld);
// Renumber (point data) to correspond to merged points
if (Pstream::master() && this->isPointData())
{
inplaceReorder(merged_.pointsMap(), allFld);
allFld.resize(merged_.points().size());
}
return tfield;
}
// Mark that any geometry changes have been taken care of
upToDate_ = true;
return fld;
}
#define defineSurfaceWriterMergeMethod(ThisClass, Type) \
Foam::tmp<Foam::Field<Type>> \
ThisClass::mergeField(const Field<Type>& fld) const \
{ \
return mergeFieldTemplate(fld); \
}
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::label);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::scalar);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::vector);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::sphericalTensor);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::symmTensor);
defineSurfaceWriterMergeMethod(Foam::surfaceWriter, Foam::tensor)
#undef defineSurfaceWriterMergeMethod
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<
(
Ostream& os,
const InfoProxy<surfaceWriter>& ip
)
{
const surfaceWriter& w = ip.t_;
os << "surfaceWriter:"
<< " upToDate: " << w.upToDate_
<< " PointData: " << w.isPointData_
<< " nFields: " << w.nFields_
<< " time: " << w.currTime_
<< " path: " << w.outputPath_ << endl;
return os;
}
// ************************************************************************* //