/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
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 .
\*---------------------------------------------------------------------------*/
#include "mydebugSurfaceWriter.H"
#include "globalIndex.H"
#include "argList.H"
#include "OFstream.H"
#include "OSspecific.H"
#include "IOmanip.H"
#include "Time.H"
#include "pointIOField.H"
#include "primitivePatch.H"
#include "profiling.H"
#include "surfaceWriterMethods.H"
#include "PrecisionAdaptor.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
namespace surfaceWriters
{
defineTypeName(mydebugWriter);
addToRunTimeSelectionTable(surfaceWriter, mydebugWriter, word);
addToRunTimeSelectionTable(surfaceWriter, mydebugWriter, wordDict);
}
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Type narrowing - base implementation is pass-through
template struct narrowType
{
typedef Type type;
};
template<> struct narrowType
{
typedef float type;
};
template<> struct narrowType>
{
typedef Vector type;
};
template<> struct narrowType>
{
typedef SphericalTensor type;
};
template<> struct narrowType>
{
typedef SymmTensor type;
};
// FIXME: Not sure why this one seems to be broken...
//
// template<> struct narrowType>
// {
// typedef Tensor type;
// };
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template
Foam::tmp>
Foam::surfaceWriters::mydebugWriter::mergeField
(
const Field& fld
) const
{
addProfiling(merge, "debugWriter::merge-field");
// This is largely identical to surfaceWriter::mergeField()
// but with narrowing for communication
if (narrowTransfer_ && parallel_ && UPstream::parRun())
{
// The narrowed type
typedef typename narrowType::type narrowedType;
// Ensure geometry is also merged
merge();
// Gather all values
auto tfield = tmp>::New();
auto& allFld = tfield.ref();
// Update any expired global index (as required)
const globalIndex& globIndex =
(
this->isPointData()
? mergedSurf_.pointGlobalIndex()
: mergedSurf_.faceGlobalIndex()
);
ConstPrecisionAdaptor input(fld);
PrecisionAdaptor output(allFld);
globIndex.gather
(
input.cref(), // fld,
output.ref(), // allFld,
UPstream::msgType(),
commType_,
UPstream::worldComm
);
// Commit adapted content changes
input.commit();
output.commit();
// Discard adaptors
input.clear();
output.clear();
// Renumber (point data) to correspond to merged points
if
(
UPstream::master()
&& this->isPointData()
&& mergedSurf_.pointsMap().size()
)
{
inplaceReorder(mergedSurf_.pointsMap(), allFld);
allFld.resize(mergedSurf_.points().size());
}
return tfield;
}
return surfaceWriter::mergeField(fld);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceWriters::mydebugWriter::mydebugWriter()
:
surfaceWriter(),
enableMerge_(true),
enableWrite_(false),
header_(true),
narrowTransfer_(false),
streamOpt_(IOstreamOption::BINARY)
{}
Foam::surfaceWriters::mydebugWriter::mydebugWriter
(
const dictionary& options
)
:
surfaceWriter(options),
enableMerge_(options.getOrDefault("merge", true)),
enableWrite_(options.getOrDefault("write", false)),
header_(true),
narrowTransfer_(options.getOrDefault("narrow", false)),
streamOpt_(IOstreamOption::BINARY)
{
Info<< "Using debug surface writer ("
<< (this->isPointData() ? "point" : "face") << " data):"
<< " commsType=" << UPstream::commsTypeNames[commType_]
<< " merge=" << Switch::name(enableMerge_)
<< " write=" << Switch::name(enableWrite_)
<< " narrow=" << Switch::name(narrowTransfer_)
<< endl;
}
Foam::surfaceWriters::mydebugWriter::mydebugWriter
(
const meshedSurf& surf,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
mydebugWriter(options)
{
open(surf, outputPath, parallel);
}
Foam::surfaceWriters::mydebugWriter::mydebugWriter
(
const pointField& points,
const faceList& faces,
const fileName& outputPath,
bool parallel,
const dictionary& options
)
:
mydebugWriter(options)
{
open(points, faces, outputPath, parallel);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::surfaceWriters::mydebugWriter::serialWriteGeometry
(
const regIOobject& iopts,
const meshedSurf& surf
)
{
const pointField& points = surf.points();
const faceList& faces = surf.faces();
if (verbose_)
{
if (this->isPointData())
{
Info<< "Writing points: " << iopts.objectPath() << endl;
}
else
{
Info<< "Writing face centres: " << iopts.objectPath() << endl;
}
}
// Like regIOobject::writeObject without instance() adaptation
// since this would write to e.g. 0/ instead of postProcessing/
autoPtr ppPtr;
{
OFstream os(iopts.objectPath(), streamOpt_);
if (header_)
{
iopts.writeHeader(os);
}
if (this->isPointData())
{
// Just like writeData, but without copying beforehand
os << points;
}
else
{
ppPtr.reset(new primitivePatch(SubList(faces), points));
// Just like writeData, but without copying beforehand
os << ppPtr().faceCentres();
}
if (header_)
{
IOobject::writeEndDivider(os);
}
}
}
Foam::fileName Foam::surfaceWriters::mydebugWriter::write()
{
checkOpen();
// Geometry: rootdir/surfaceName/"points"
// Field: rootdir/surfaceName/