diff --git a/src/conversion/vtk/output/foamVtkInternalWriter.C b/src/conversion/vtk/output/foamVtkInternalWriter.C index 1179b8971fe310923523e38d35350cfab922a951..392f01b80eefc03ed9e0ae76168fd498b9a76ab6 100644 --- a/src/conversion/vtk/output/foamVtkInternalWriter.C +++ b/src/conversion/vtk/output/foamVtkInternalWriter.C @@ -665,9 +665,9 @@ void Foam::vtk::internalWriter::writeCellIDs() bool Foam::vtk::internalWriter::writeProcIDs() { - if (!Pstream::parRun()) + if (!parallel_) { - // Skip serial output (meaningless) + // Disabled in serial output (meaningless) return false; } diff --git a/src/conversion/vtk/output/foamVtkPatchWriter.C b/src/conversion/vtk/output/foamVtkPatchWriter.C index 6b1f796cae47485834c86ca9e6a324e080120ffb..b47c59cb323ea3e8343990b2012b44cc63dbbffe 100644 --- a/src/conversion/vtk/output/foamVtkPatchWriter.C +++ b/src/conversion/vtk/output/foamVtkPatchWriter.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -663,4 +663,236 @@ void Foam::vtk::patchWriter::writePatchIDs() } +bool Foam::vtk::patchWriter::writeProcIDs() +{ + // This is different than for internalWriter. + // Here we allow procIDs whenever running in parallel, even if the + // output is serial. This allow diagnosis of processor patches. + + if (!Pstream::parRun()) + { + // Skip in non-parallel + return false; + } + + if (isState(outputState::CELL_DATA)) + { + ++nCellData_; + } + else + { + FatalErrorInFunction + << "Bad writer state (" << stateNames[state_] + << ") - should be (" << stateNames[outputState::CELL_DATA] + << ") for patchID field" << nl << endl + << exit(FatalError); + } + + label nFaces = nLocalFaces_; + + if (parallel_) + { + reduce(nFaces, sumOp<label>()); + } + + if (format_) + { + if (legacy()) + { + legacy::intField<1>(format(), "procID", nFaces); // 1 component + } + else + { + const uint64_t payLoad = + vtk::sizeofData<label>(nFaces); + + format().beginDataArray<label>("procID"); + format().writeSize(payLoad); + } + } + + bool good = false; + + if (parallel_) + { + globalIndex procSizes(nLocalFaces_); + + if (Pstream::master()) + { + // Per-processor ids + for (label proci=0; proci < Pstream::nProcs(); ++proci) + { + label len = procSizes.localSize(proci); + + while (len--) + { + format().write(proci); + } + } + + good = true; + } + } + else + { + const label proci = Pstream::myProcNo(); + + label len = nLocalFaces_; + + while (len--) + { + format().write(proci); + } + + good = true; + } + + + if (format_) + { + format().flush(); + format().endDataArray(); + } + + // MPI barrier + return parallel_ ? returnReduce(good, orOp<bool>()) : good; +} + + +bool Foam::vtk::patchWriter::writeNeighIDs() +{ + if (!Pstream::parRun()) + { + // Skip in non-parallel + return false; + } + + if (isState(outputState::CELL_DATA)) + { + ++nCellData_; + } + else + { + FatalErrorInFunction + << "Bad writer state (" << stateNames[state_] + << ") - should be (" << stateNames[outputState::CELL_DATA] + << ") for patchID field" << nl << endl + << exit(FatalError); + } + + const polyBoundaryMesh& patches = mesh_.boundaryMesh(); + + label nFaces = nLocalFaces_; + + if (parallel_) + { + reduce(nFaces, sumOp<label>()); + } + + if (format_) + { + if (legacy()) + { + legacy::intField<1>(format(), "neighID", nFaces); // 1 component + } + else + { + const uint64_t payLoad = + vtk::sizeofData<label>(nFaces); + + format().beginDataArray<label>("neighID"); + format().writeSize(payLoad); + } + } + + bool good = false; + + if (parallel_ ? Pstream::master() : true) + { + for (const label patchId : patchIDs_) + { + label count = patches[patchId].size(); + + const auto* pp = isA<processorPolyPatch>(patches[patchId]); + + const label val = (pp ? pp->neighbProcNo() : -1); + + while (count--) + { + format().write(val); + } + } + + good = true; + } + + if (parallel_) + { + if (Pstream::master()) + { + labelList recv; + + // Receive each pair + for + ( + int slave=Pstream::firstSlave(); + slave<=Pstream::lastSlave(); + ++slave + ) + { + IPstream fromSlave(Pstream::commsTypes::blocking, slave); + + fromSlave >> recv; + + for (label i=0; i < recv.size(); ++i) + { + label count = recv[i]; + ++i; + const label val = recv[i]; + + while (count--) + { + format().write(val); + } + } + } + } + else + { + // Send to master + OPstream toMaster + ( + Pstream::commsTypes::blocking, + Pstream::masterNo() + ); + + labelList send(2*patchIDs_.size()); + + // Encode as [size, id] pairs + label i = 0; + for (const label patchId : patchIDs_) + { + const auto* pp = isA<processorPolyPatch>(patches[patchId]); + + send[i] = patches[patchId].size(); + send[i+1] = (pp ? pp->neighbProcNo() : -1); + + i += 2; + } + + toMaster << send; + } + } + + if (format_) + { + format().flush(); + format().endDataArray(); + } + + // MPI barrier + return parallel_ ? returnReduce(good, orOp<bool>()) : good; +} + + // ************************************************************************* // diff --git a/src/conversion/vtk/output/foamVtkPatchWriter.H b/src/conversion/vtk/output/foamVtkPatchWriter.H index 3f19285ff0fc64c438f385462c58193747463b24..4e1b901a0e5d1f0865fe98656e68795debf19834 100644 --- a/src/conversion/vtk/output/foamVtkPatchWriter.H +++ b/src/conversion/vtk/output/foamVtkPatchWriter.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -222,6 +222,14 @@ public: // Must be called within the CELL_DATA state. void writePatchIDs(); + //- Write processor ids as CellData. This is no-op in serial. + // Must be called within the CELL_DATA state. + bool writeProcIDs(); + + //- Write processor neighbour ids as CellData. This is no-op in serial. + // Must be called within the CELL_DATA state. + bool writeNeighIDs(); + // Write