/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2019 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 .
Description
Code chunk for converting volume fields on processor boundaries,
included by foamToVTK.
\*---------------------------------------------------------------------------*/
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Generate processor/processorN/procBoundary
{
using reportFields = foamToVtkReportFields;
const label nVolFields =
(
objects.count(stringListOps::foundOp(fieldTypes::volume))
);
reportFields::volume(Info, objects);
// Setup for the vtm writer.
fileName vtmOutputBase
(
outputDir/regionPrefix/vtkName + timeDesc
);
// Naming
const auto subDirNaming =
[](const label i) -> fileName
{ return "processor" / ("processor" + Foam::name(i)); };
// Dummy writer.
autoPtr internalWriter;
// Setup the patch writers
PtrList patchWriters;
const polyBoundaryMesh& patches = mesh.boundaryMesh();
labelList patchIds =
identity
(
patches.size()-patches.nNonProcessor(),
patches.nNonProcessor()
);
forAll(patchIds, i)
{
if (!isA(patches[patchIds[i]]))
{
patchIds.resize(i);
break;
}
}
patchWriters.resize(patchIds.size());
label nPatchWriters = 0;
List procPatchNames(Pstream::nProcs());
procPatchNames[Pstream::myProcNo()].resize(patchIds.size());
for (const label patchId : patchIds)
{
const polyPatch& pp = patches[patchId];
auto writer = autoPtr::New
(
meshProxy.mesh(),
labelList(one(), pp.index()),
writeOpts,
nearCellValue,
(
vtmOutputBase
/ subDirNaming(Pstream::myProcNo())
/ pp.name()
),
false // This MUST be non-parallel (serial only)
);
procPatchNames[Pstream::myProcNo()][nPatchWriters] = pp.name();
writer->writeTimeValue(timeValue);
writer->writeGeometry();
// Transfer writer to list for later use
patchWriters.set(nPatchWriters++, writer);
}
patchWriters.resize(nPatchWriters);
Pstream::gatherList(procPatchNames);
// CellData
{
for (vtk::patchWriter& writer : patchWriters)
{
// Optionally with patchID, procID, neighID fields
// - use Pstream::parRun() not writer.parallel() !!
writer.beginCellData
(
(withMeshIds ? 1 + (Pstream::parRun() ? 2 : 0) : 0)
+ nVolFields
);
if (withMeshIds)
{
writer.writePatchIDs();
writer.writeProcIDs(); // parallel only
writer.writeNeighIDs(); // parallel only
}
}
writeAllVolFields
(
internalWriter,
patchWriters,
meshProxy,
objects,
true // syncPar
);
// End CellData is implicit
}
// Finish writers
if (internalWriter.valid())
{
internalWriter->close();
}
for (vtk::patchWriter& writer : patchWriters)
{
writer.close();
}
patchWriters.clear();
// Collective output
const label nProcPatches = returnReduce(nPatchWriters, sumOp