mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-12-28 03:37:59 +00:00
- the writer nFields() is a separate type of accounting (currently only needed by VTK legacy) and is independent of the geometry.
562 lines
12 KiB
C
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;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|