- ensure that the string-related classes have consistently similar matching methods. Use operator()(const std::string) as an entry point for the match() method, which makes it easier to use for filters and predicates. In some cases this will also permit using a HashSet as a match predicate. regExp ==== - the set method now returns a bool to signal that the requested pattern was compiled. wordRe ==== - have separate constructors with the compilation option (was previously a default parameter). This leaves the single parameter constructor explicit, but the two parameter version is now non-explicit, which makes it easier to use when building lists. - renamed compile-option from REGEX (to REGEXP) for consistency with with the <regex.h>, <regex> header names etc. wordRes ==== - renamed from wordReListMatcher -> wordRes. For reduced typing and since it behaves as an entity only slightly related to its underlying list nature. - Provide old name as typedef and include for code transition. - pass through some list methods into wordRes hashedWordList ==== - hashedWordList[const word& name] now returns a -1 if the name is is not found in the list of indices. That has been a pending change ever since hashedWordList was generalized out of speciesTable (Oct-2010). - add operator()(const word& name) for easy use as a predicate STYLE: adjust parameter names in stringListOps - reflect if the parameter is being used as a primary matcher, or the matcher will be derived from the parameter. For example, (const char* re), which first creates a regExp versus (const regExp& matcher) which is used directly.
1304 lines
37 KiB
C
1304 lines
37 KiB
C
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
\\/ M anipulation | Copyright (C) 2016 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 <http://www.gnu.org/licenses/>.
|
|
|
|
Application
|
|
foamToVTK
|
|
|
|
Group
|
|
grpPostProcessingUtilities
|
|
|
|
Description
|
|
Legacy VTK file format writer.
|
|
|
|
- Handles volFields, pointFields, surfaceScalarField, surfaceVectorField
|
|
fields.
|
|
- Mesh topo changes.
|
|
- Both ascii and binary.
|
|
- Single time step writing.
|
|
- Write subset only.
|
|
- Automatic decomposition of cells; polygons on boundary undecomposed since
|
|
handled by vtk.
|
|
|
|
Usage
|
|
\b foamToVTK [OPTION]
|
|
|
|
Options:
|
|
- \par -ascii
|
|
Write VTK data in ASCII format instead of binary.
|
|
|
|
- \par -mesh \<name\>
|
|
Use a different mesh name (instead of -region)
|
|
|
|
- \par -fields \<fields\>
|
|
Convert selected fields only. For example,
|
|
\verbatim
|
|
-fields "( p T U )"
|
|
\endverbatim
|
|
The quoting is required to avoid shell expansions and to pass the
|
|
information as a single argument.
|
|
|
|
- \par -surfaceFields
|
|
Write surfaceScalarFields (e.g., phi)
|
|
|
|
- \par -cellSet \<name\>
|
|
- \par -faceSet \<name\>
|
|
|
|
- \par -pointSet \<name\>
|
|
Restrict conversion to the cellSet, faceSet or pointSet.
|
|
|
|
- \par -nearCellValue
|
|
Output cell value on patches instead of patch value itself
|
|
|
|
- \par -noInternal
|
|
Do not generate file for mesh, only for patches
|
|
|
|
- \par -noLagrangian
|
|
Suppress writing lagrangian positions and fields.
|
|
|
|
- \par -noPointValues
|
|
No pointFields
|
|
|
|
- \par -noFaceZones
|
|
No faceZones
|
|
|
|
- \par -noLinks
|
|
(in parallel) do not link processor files to master
|
|
|
|
- \par poly
|
|
write polyhedral cells without tet/pyramid decomposition
|
|
|
|
- \par -allPatches
|
|
Combine all patches into a single file
|
|
|
|
- \par -excludePatches \<patchNames\>
|
|
Specify patches (wildcards) to exclude. For example,
|
|
\verbatim
|
|
-excludePatches '( inlet_1 inlet_2 "proc.*")'
|
|
\endverbatim
|
|
The quoting is required to avoid shell expansions and to pass the
|
|
information as a single argument. The double quotes denote a regular
|
|
expression.
|
|
|
|
- \par -useTimeName
|
|
use the time index in the VTK file name instead of the time index
|
|
|
|
Note
|
|
mesh subset is handled by vtkMesh. Slight inconsistency in
|
|
interpolation: on the internal field it interpolates the whole volField
|
|
to the whole-mesh pointField and then selects only those values it
|
|
needs for the subMesh (using the fvMeshSubset cellMap(), pointMap()
|
|
functions). For the patches however it uses the
|
|
fvMeshSubset.interpolate function to directly interpolate the
|
|
whole-mesh values onto the subset patch.
|
|
|
|
Note
|
|
\par new file format:
|
|
no automatic timestep recognition.
|
|
However can have .pvd file format which refers to time simulation
|
|
if XML *.vtu files are available:
|
|
|
|
\verbatim
|
|
<?xml version="1.0"?>
|
|
<VTKFile type="Collection"
|
|
version="0.1"
|
|
byte_order="LittleEndian"
|
|
compressor="vtkZLibDataCompressor">
|
|
<Collection>
|
|
<DataSet timestep="50" file="pitzDaily_2.vtu"/>
|
|
<DataSet timestep="100" file="pitzDaily_3.vtu"/>
|
|
<DataSet timestep="150" file="pitzDaily_4.vtu"/>
|
|
<DataSet timestep="200" file="pitzDaily_5.vtu"/>
|
|
<DataSet timestep="250" file="pitzDaily_6.vtu"/>
|
|
<DataSet timestep="300" file="pitzDaily_7.vtu"/>
|
|
<DataSet timestep="350" file="pitzDaily_8.vtu"/>
|
|
<DataSet timestep="400" file="pitzDaily_9.vtu"/>
|
|
<DataSet timestep="450" file="pitzDaily_10.vtu"/>
|
|
<DataSet timestep="500" file="pitzDaily_11.vtu"/>
|
|
</Collection>
|
|
</VTKFile>
|
|
\endverbatim
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include "fvCFD.H"
|
|
#include "pointMesh.H"
|
|
#include "volPointInterpolation.H"
|
|
#include "emptyPolyPatch.H"
|
|
#include "labelIOField.H"
|
|
#include "scalarIOField.H"
|
|
#include "sphericalTensorIOField.H"
|
|
#include "symmTensorIOField.H"
|
|
#include "tensorIOField.H"
|
|
#include "faceZoneMesh.H"
|
|
#include "Cloud.H"
|
|
#include "passiveParticle.H"
|
|
#include "stringListOps.H"
|
|
|
|
#include "vtkMesh.H"
|
|
#include "readFields.H"
|
|
#include "writeFuns.H"
|
|
|
|
#include "internalWriter.H"
|
|
#include "patchWriter.H"
|
|
#include "lagrangianWriter.H"
|
|
|
|
#include "writeFaceSet.H"
|
|
#include "writePointSet.H"
|
|
#include "surfaceMeshWriter.H"
|
|
#include "writeSurfFields.H"
|
|
|
|
#include "memInfo.H"
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
template<class GeoField>
|
|
void print(const char* msg, Ostream& os, const PtrList<const GeoField>& flds)
|
|
{
|
|
if (flds.size())
|
|
{
|
|
os << msg;
|
|
forAll(flds, i)
|
|
{
|
|
os << ' ' << flds[i].name();
|
|
}
|
|
os << endl;
|
|
}
|
|
}
|
|
|
|
|
|
void print(Ostream& os, const wordList& flds)
|
|
{
|
|
forAll(flds, i)
|
|
{
|
|
os << ' ' << flds[i];
|
|
}
|
|
os << endl;
|
|
}
|
|
|
|
|
|
labelList getSelectedPatches
|
|
(
|
|
const polyBoundaryMesh& patches,
|
|
const wordRes& excludePatches
|
|
)
|
|
{
|
|
DynamicList<label> patchIDs(patches.size());
|
|
|
|
Info<< "Combining patches:" << endl;
|
|
|
|
forAll(patches, patchi)
|
|
{
|
|
const polyPatch& pp = patches[patchi];
|
|
|
|
if
|
|
(
|
|
isType<emptyPolyPatch>(pp)
|
|
|| (Pstream::parRun() && isType<processorPolyPatch>(pp))
|
|
)
|
|
{
|
|
Info<< " discarding empty/processor patch " << patchi
|
|
<< " " << pp.name() << endl;
|
|
}
|
|
else if (excludePatches.match(pp.name()))
|
|
{
|
|
Info<< " excluding patch " << patchi
|
|
<< " " << pp.name() << endl;
|
|
}
|
|
else
|
|
{
|
|
patchIDs.append(patchi);
|
|
Info<< " patch " << patchi << " " << pp.name() << endl;
|
|
}
|
|
}
|
|
return patchIDs.shrink();
|
|
}
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
argList::addNote
|
|
(
|
|
"legacy VTK file format writer"
|
|
);
|
|
timeSelector::addOptions();
|
|
|
|
#include "addRegionOption.H"
|
|
argList::addOption
|
|
(
|
|
"fields",
|
|
"wordList",
|
|
"only convert the specified fields - eg '(p T U)'"
|
|
);
|
|
argList::addOption
|
|
(
|
|
"cellSet",
|
|
"name",
|
|
"convert a mesh subset corresponding to the specified cellSet"
|
|
);
|
|
argList::addOption
|
|
(
|
|
"faceSet",
|
|
"name",
|
|
"restrict conversion to the specified faceSet"
|
|
);
|
|
argList::addOption
|
|
(
|
|
"pointSet",
|
|
"name",
|
|
"restrict conversion to the specified pointSet"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"ascii",
|
|
"write in ASCII format instead of binary"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"poly",
|
|
"write polyhedral cells without tet/pyramid decomposition"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"surfaceFields",
|
|
"write surfaceScalarFields (e.g., phi)"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"nearCellValue",
|
|
"use cell value on patches instead of patch value itself"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"noInternal",
|
|
"do not generate file for mesh, only for patches"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"noLagrangian",
|
|
"suppress writing lagrangian positions and fields"
|
|
);
|
|
|
|
argList::addBoolOption
|
|
(
|
|
"noPointValues",
|
|
"no pointFields"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"allPatches",
|
|
"combine all patches into a single file"
|
|
);
|
|
argList::addOption
|
|
(
|
|
"excludePatches",
|
|
"wordReList",
|
|
"a list of patches to exclude - eg '( inlet \".*Wall\" )' "
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"noFaceZones",
|
|
"no faceZones"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"noLinks",
|
|
"don't link processor VTK files - parallel only"
|
|
);
|
|
argList::addBoolOption
|
|
(
|
|
"useTimeName",
|
|
"use the time name instead of the time index when naming the files"
|
|
);
|
|
|
|
#include "setRootCase.H"
|
|
|
|
cpuTime timer;
|
|
memInfo mem;
|
|
Info<< "Initial memory "
|
|
<< mem.update().size() << " kB" << endl;
|
|
|
|
#include "createTime.H"
|
|
|
|
const bool doWriteInternal = !args.optionFound("noInternal");
|
|
const bool doFaceZones = !args.optionFound("noFaceZones");
|
|
const bool doLinks = !args.optionFound("noLinks");
|
|
bool binary = !args.optionFound("ascii");
|
|
const bool useTimeName = args.optionFound("useTimeName");
|
|
const bool noLagrangian = args.optionFound("noLagrangian");
|
|
|
|
// Decomposition of polyhedral cells into tets/pyramids cells
|
|
vtkTopo::decomposePoly = !args.optionFound("poly");
|
|
|
|
if (binary && (sizeof(floatScalar) != 4 || sizeof(label) != 4))
|
|
{
|
|
WarningInFunction
|
|
<< "Using ASCII rather than binary VTK format because "
|
|
"floatScalar and/or label are not 4 bytes in size."
|
|
<< nl << endl;
|
|
binary = false;
|
|
}
|
|
|
|
const bool nearCellValue = args.optionFound("nearCellValue");
|
|
|
|
if (nearCellValue)
|
|
{
|
|
WarningInFunction
|
|
<< "Using neighbouring cell value instead of patch value"
|
|
<< nl << endl;
|
|
}
|
|
|
|
const bool noPointValues = args.optionFound("noPointValues");
|
|
|
|
if (noPointValues)
|
|
{
|
|
WarningInFunction
|
|
<< "Outputting cell values only" << nl << endl;
|
|
}
|
|
|
|
const bool allPatches = args.optionFound("allPatches");
|
|
|
|
wordReList excludePatches;
|
|
if (args.optionFound("excludePatches"))
|
|
{
|
|
args.optionLookup("excludePatches")() >> excludePatches;
|
|
|
|
Info<< "Not including patches " << excludePatches << nl << endl;
|
|
}
|
|
|
|
word cellSetName;
|
|
word faceSetName;
|
|
word pointSetName;
|
|
string vtkName = runTime.caseName();
|
|
|
|
if (args.optionReadIfPresent("cellSet", cellSetName))
|
|
{
|
|
vtkName = cellSetName;
|
|
}
|
|
else if (Pstream::parRun())
|
|
{
|
|
// Strip off leading casename, leaving just processor_DDD ending.
|
|
string::size_type i = vtkName.rfind("processor");
|
|
|
|
if (i != string::npos)
|
|
{
|
|
vtkName = vtkName.substr(i);
|
|
}
|
|
}
|
|
args.optionReadIfPresent("faceSet", faceSetName);
|
|
args.optionReadIfPresent("pointSet", pointSetName);
|
|
|
|
|
|
instantList timeDirs = timeSelector::select0(runTime, args);
|
|
|
|
#include "createNamedMesh.H"
|
|
|
|
// VTK/ directory in the case
|
|
fileName fvPath(runTime.path()/"VTK");
|
|
|
|
// Directory of mesh (region0 gets filtered out)
|
|
fileName regionPrefix;
|
|
if (regionName != polyMesh::defaultRegion)
|
|
{
|
|
fvPath = fvPath/regionName;
|
|
regionPrefix = regionName;
|
|
}
|
|
|
|
if (isDir(fvPath))
|
|
{
|
|
if
|
|
(
|
|
args.optionFound("time")
|
|
|| args.optionFound("latestTime")
|
|
|| cellSetName.size()
|
|
|| faceSetName.size()
|
|
|| pointSetName.size()
|
|
|| regionName != polyMesh::defaultRegion
|
|
)
|
|
{
|
|
Info<< "Keeping old VTK files in " << fvPath << nl << endl;
|
|
}
|
|
else
|
|
{
|
|
Info<< "Deleting old VTK files in " << fvPath << nl << endl;
|
|
|
|
rmDir(fvPath);
|
|
}
|
|
}
|
|
|
|
mkDir(fvPath);
|
|
|
|
// Mesh wrapper: does subsetting and decomposition
|
|
vtkMesh vMesh(mesh, cellSetName);
|
|
|
|
Info<< "VTK mesh topology: "
|
|
<< timer.cpuTimeIncrement() << " s, "
|
|
<< mem.update().size() << " kB" << endl;
|
|
|
|
#include "findClouds.H"
|
|
|
|
forAll(timeDirs, timeI)
|
|
{
|
|
runTime.setTime(timeDirs[timeI], timeI);
|
|
|
|
Info<< "Time: " << runTime.timeName() << endl;
|
|
|
|
const word timeDesc =
|
|
useTimeName ? runTime.timeName() : Foam::name(runTime.timeIndex());
|
|
|
|
// Check for new polyMesh/ and update mesh, fvMeshSubset and cell
|
|
// decomposition.
|
|
polyMesh::readUpdateState meshState = vMesh.readUpdate();
|
|
|
|
const fvMesh& mesh = vMesh.mesh();
|
|
|
|
if
|
|
(
|
|
meshState == polyMesh::TOPO_CHANGE
|
|
|| meshState == polyMesh::TOPO_PATCH_CHANGE
|
|
)
|
|
{
|
|
Info<< " Read new mesh" << nl << endl;
|
|
}
|
|
|
|
|
|
// If faceSet: write faceSet only (as polydata)
|
|
if (faceSetName.size())
|
|
{
|
|
// Load the faceSet
|
|
faceSet set(mesh, faceSetName);
|
|
|
|
// Filename as if patch with same name.
|
|
mkDir(fvPath/set.name());
|
|
|
|
fileName patchFileName
|
|
(
|
|
fvPath/set.name()/set.name()
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk"
|
|
);
|
|
|
|
Info<< " FaceSet : " << patchFileName << endl;
|
|
|
|
writeFaceSet(binary, vMesh.mesh(), set, patchFileName);
|
|
|
|
continue;
|
|
}
|
|
// If pointSet: write pointSet only (as polydata)
|
|
if (pointSetName.size())
|
|
{
|
|
// Load the pointSet
|
|
pointSet set(mesh, pointSetName);
|
|
|
|
// Filename as if patch with same name.
|
|
mkDir(fvPath/set.name());
|
|
|
|
fileName patchFileName
|
|
(
|
|
fvPath/set.name()/set.name()
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk"
|
|
);
|
|
|
|
Info<< " pointSet : " << patchFileName << endl;
|
|
|
|
writePointSet(binary, vMesh.mesh(), set, patchFileName);
|
|
|
|
continue;
|
|
}
|
|
|
|
|
|
// Search for list of objects for this time
|
|
IOobjectList objects(mesh, runTime.timeName());
|
|
|
|
HashSet<word> selectedFields;
|
|
bool specifiedFields = args.optionReadIfPresent
|
|
(
|
|
"fields",
|
|
selectedFields
|
|
);
|
|
|
|
// Construct the vol fields (on the original mesh if subsetted)
|
|
|
|
PtrList<const volScalarField> vsf;
|
|
PtrList<const volVectorField> vvf;
|
|
PtrList<const volSphericalTensorField> vSpheretf;
|
|
PtrList<const volSymmTensorField> vSymmtf;
|
|
PtrList<const volTensorField> vtf;
|
|
|
|
if (!specifiedFields || selectedFields.size())
|
|
{
|
|
readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vsf);
|
|
print(" volScalarFields :", Info, vsf);
|
|
|
|
readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vvf);
|
|
print(" volVectorFields :", Info, vvf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
vSpheretf
|
|
);
|
|
print(" volSphericalTensorFields :", Info, vSpheretf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
vSymmtf
|
|
);
|
|
print(" volSymmTensorFields :", Info, vSymmtf);
|
|
|
|
readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, vtf);
|
|
print(" volTensorFields :", Info, vtf);
|
|
}
|
|
|
|
label nVolFields =
|
|
vsf.size()
|
|
+ vvf.size()
|
|
+ vSpheretf.size()
|
|
+ vSymmtf.size()
|
|
+ vtf.size();
|
|
|
|
|
|
// Construct dimensioned fields
|
|
PtrList<const volScalarField::Internal> dsf;
|
|
PtrList<const volVectorField::Internal> dvf;
|
|
PtrList<const volSphericalTensorField::Internal> dSpheretf;
|
|
PtrList<const volSymmTensorField::Internal> dSymmtf;
|
|
PtrList<const volTensorField::Internal> dtf;
|
|
|
|
if (!specifiedFields || selectedFields.size())
|
|
{
|
|
readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dsf);
|
|
print(" volScalarFields::Internal :", Info, dsf);
|
|
|
|
readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dvf);
|
|
print(" volVectorFields::Internal :", Info, dvf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
dSpheretf
|
|
);
|
|
print(" volSphericalTensorFields::Internal :", Info, dSpheretf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
dSymmtf
|
|
);
|
|
print(" volSymmTensorFields::Internal :", Info, dSymmtf);
|
|
|
|
readFields(vMesh, vMesh.baseMesh(), objects, selectedFields, dtf);
|
|
print(" volTensorFields::Internal :", Info, dtf);
|
|
}
|
|
|
|
label nDimFields =
|
|
dsf.size()
|
|
+ dvf.size()
|
|
+ dSpheretf.size()
|
|
+ dSymmtf.size()
|
|
+ dtf.size();
|
|
|
|
|
|
// Construct pointMesh only if necessary since constructs edge
|
|
// addressing (expensive on polyhedral meshes)
|
|
if (noPointValues)
|
|
{
|
|
Info<< " pointScalarFields : switched off"
|
|
<< " (\"-noPointValues\" (at your option)\n";
|
|
Info<< " pointVectorFields : switched off"
|
|
<< " (\"-noPointValues\" (at your option)\n";
|
|
}
|
|
|
|
PtrList<const pointScalarField> psf;
|
|
PtrList<const pointVectorField> pvf;
|
|
PtrList<const pointSphericalTensorField> pSpheretf;
|
|
PtrList<const pointSymmTensorField> pSymmtf;
|
|
PtrList<const pointTensorField> ptf;
|
|
|
|
if (!noPointValues && !(specifiedFields && selectedFields.empty()))
|
|
{
|
|
readFields
|
|
(
|
|
vMesh,
|
|
pointMesh::New(vMesh.baseMesh()),
|
|
objects,
|
|
selectedFields,
|
|
psf
|
|
);
|
|
print(" pointScalarFields :", Info, psf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
pointMesh::New(vMesh.baseMesh()),
|
|
objects,
|
|
selectedFields,
|
|
pvf
|
|
);
|
|
print(" pointVectorFields :", Info, pvf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
pointMesh::New(vMesh.baseMesh()),
|
|
objects,
|
|
selectedFields,
|
|
pSpheretf
|
|
);
|
|
print(" pointSphericalTensorFields :", Info, pSpheretf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
pointMesh::New(vMesh.baseMesh()),
|
|
objects,
|
|
selectedFields,
|
|
pSymmtf
|
|
);
|
|
print(" pointSymmTensorFields :", Info, pSymmtf);
|
|
|
|
readFields
|
|
(
|
|
vMesh,
|
|
pointMesh::New(vMesh.baseMesh()),
|
|
objects,
|
|
selectedFields,
|
|
ptf
|
|
);
|
|
print(" pointTensorFields :", Info, ptf);
|
|
}
|
|
Info<< endl;
|
|
|
|
label nPointFields =
|
|
psf.size()
|
|
+ pvf.size()
|
|
+ pSpheretf.size()
|
|
+ pSymmtf.size()
|
|
+ ptf.size();
|
|
|
|
if (doWriteInternal)
|
|
{
|
|
// Create file and write header
|
|
fileName vtkFileName
|
|
(
|
|
fvPath/vtkName
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk"
|
|
);
|
|
|
|
Info<< " Internal : " << vtkFileName << endl;
|
|
|
|
// Write mesh
|
|
internalWriter writer(vMesh, binary, vtkFileName);
|
|
|
|
// VolFields + cellID
|
|
writeFuns::writeCellDataHeader
|
|
(
|
|
writer.os(),
|
|
vMesh.nFieldCells(),
|
|
1 + nVolFields + nDimFields
|
|
);
|
|
|
|
// Write cellID field
|
|
writer.writeCellIDs();
|
|
|
|
// Write volFields
|
|
writer.write(vsf);
|
|
writer.write(vvf);
|
|
writer.write(vSpheretf);
|
|
writer.write(vSymmtf);
|
|
writer.write(vtf);
|
|
|
|
// Write dimensionedFields
|
|
writer.write<scalar, volMesh>(dsf);
|
|
writer.write<vector, volMesh>(dvf);
|
|
writer.write<sphericalTensor, volMesh>(dSpheretf);
|
|
writer.write<symmTensor, volMesh>(dSymmtf);
|
|
writer.write<tensor, volMesh>(dtf);
|
|
|
|
if (!noPointValues)
|
|
{
|
|
writeFuns::writePointDataHeader
|
|
(
|
|
writer.os(),
|
|
vMesh.nFieldPoints(),
|
|
nVolFields + nDimFields + nPointFields
|
|
);
|
|
|
|
// pointFields
|
|
writer.write(psf);
|
|
writer.write(pvf);
|
|
writer.write(pSpheretf);
|
|
writer.write(pSymmtf);
|
|
writer.write(ptf);
|
|
|
|
// Interpolated volFields
|
|
volPointInterpolation pInterp(mesh);
|
|
writer.write(pInterp, vsf);
|
|
writer.write(pInterp, vvf);
|
|
writer.write(pInterp, vSpheretf);
|
|
writer.write(pInterp, vSymmtf);
|
|
writer.write(pInterp, vtf);
|
|
|
|
writer.write<scalar, volMesh>(pInterp, dsf);
|
|
writer.write<vector, volMesh>(pInterp, dvf);
|
|
writer.write<sphericalTensor, volMesh>(pInterp, dSpheretf);
|
|
writer.write<symmTensor, volMesh>(pInterp, dSymmtf);
|
|
writer.write<tensor, volMesh>(pInterp, dtf);
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// Write surface fields
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
if (args.optionFound("surfaceFields"))
|
|
{
|
|
PtrList<const surfaceScalarField> ssf;
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
ssf
|
|
);
|
|
print(" surfScalarFields :", Info, ssf);
|
|
|
|
PtrList<const surfaceVectorField> svf;
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
svf
|
|
);
|
|
print(" surfVectorFields :", Info, svf);
|
|
|
|
if (ssf.size() + svf.size() > 0)
|
|
{
|
|
// Rework the scalar fields into vectorfields.
|
|
label sz = svf.size();
|
|
|
|
svf.setSize(sz+ssf.size());
|
|
|
|
surfaceVectorField n(mesh.Sf()/mesh.magSf());
|
|
|
|
forAll(ssf, i)
|
|
{
|
|
surfaceVectorField* ssfiPtr = (ssf[i]*n).ptr();
|
|
ssfiPtr->rename(ssf[i].name());
|
|
svf.set(sz+i, ssfiPtr);
|
|
}
|
|
ssf.clear();
|
|
|
|
mkDir(fvPath / "surfaceFields");
|
|
|
|
fileName surfFileName
|
|
(
|
|
fvPath
|
|
/"surfaceFields"
|
|
/"surfaceFields"
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk"
|
|
);
|
|
|
|
writeSurfFields
|
|
(
|
|
binary,
|
|
vMesh.mesh(),
|
|
surfFileName,
|
|
svf
|
|
);
|
|
}
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// Write patches (POLYDATA file, one for each patch)
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
|
|
|
if (allPatches)
|
|
{
|
|
mkDir(fvPath/"allPatches");
|
|
|
|
fileName patchFileName;
|
|
|
|
if (vMesh.useSubMesh())
|
|
{
|
|
patchFileName =
|
|
fvPath/"allPatches"/cellSetName
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk";
|
|
}
|
|
else
|
|
{
|
|
patchFileName =
|
|
fvPath/"allPatches"/"allPatches"
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk";
|
|
}
|
|
|
|
Info<< " Combined patches : " << patchFileName << endl;
|
|
|
|
patchWriter writer
|
|
(
|
|
vMesh.mesh(),
|
|
binary,
|
|
nearCellValue,
|
|
patchFileName,
|
|
getSelectedPatches(patches, excludePatches)
|
|
);
|
|
|
|
// VolFields + patchID
|
|
writeFuns::writeCellDataHeader
|
|
(
|
|
writer.os(),
|
|
writer.nFaces(),
|
|
1+nVolFields
|
|
);
|
|
|
|
// Write patchID field
|
|
writer.writePatchIDs();
|
|
|
|
// Write volFields
|
|
writer.write(vsf);
|
|
writer.write(vvf);
|
|
writer.write(vSpheretf);
|
|
writer.write(vSymmtf);
|
|
writer.write(vtf);
|
|
|
|
if (!noPointValues)
|
|
{
|
|
writeFuns::writePointDataHeader
|
|
(
|
|
writer.os(),
|
|
writer.nPoints(),
|
|
nPointFields
|
|
);
|
|
|
|
// Write pointFields
|
|
writer.write(psf);
|
|
writer.write(pvf);
|
|
writer.write(pSpheretf);
|
|
writer.write(pSymmtf);
|
|
writer.write(ptf);
|
|
|
|
// no interpolated volFields since I cannot be bothered to
|
|
// create the patchInterpolation for all subpatches.
|
|
}
|
|
}
|
|
else
|
|
{
|
|
forAll(patches, patchi)
|
|
{
|
|
const polyPatch& pp = patches[patchi];
|
|
|
|
if (!findStrings(excludePatches, pp.name()))
|
|
{
|
|
mkDir(fvPath/pp.name());
|
|
|
|
fileName patchFileName;
|
|
|
|
if (vMesh.useSubMesh())
|
|
{
|
|
patchFileName =
|
|
fvPath/pp.name()/cellSetName
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk";
|
|
}
|
|
else
|
|
{
|
|
patchFileName =
|
|
fvPath/pp.name()/pp.name()
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk";
|
|
}
|
|
|
|
Info<< " Patch : " << patchFileName << endl;
|
|
|
|
patchWriter writer
|
|
(
|
|
vMesh.mesh(),
|
|
binary,
|
|
nearCellValue,
|
|
patchFileName,
|
|
labelList(1, patchi)
|
|
);
|
|
|
|
if (!isA<emptyPolyPatch>(pp))
|
|
{
|
|
// VolFields + patchID
|
|
writeFuns::writeCellDataHeader
|
|
(
|
|
writer.os(),
|
|
writer.nFaces(),
|
|
1+nVolFields
|
|
);
|
|
|
|
// Write patchID field
|
|
writer.writePatchIDs();
|
|
|
|
// Write volFields
|
|
writer.write(vsf);
|
|
writer.write(vvf);
|
|
writer.write(vSpheretf);
|
|
writer.write(vSymmtf);
|
|
writer.write(vtf);
|
|
|
|
if (!noPointValues)
|
|
{
|
|
writeFuns::writePointDataHeader
|
|
(
|
|
writer.os(),
|
|
writer.nPoints(),
|
|
nVolFields
|
|
+ nPointFields
|
|
);
|
|
|
|
// Write pointFields
|
|
writer.write(psf);
|
|
writer.write(pvf);
|
|
writer.write(pSpheretf);
|
|
writer.write(pSymmtf);
|
|
writer.write(ptf);
|
|
|
|
PrimitivePatchInterpolation<primitivePatch> pInter
|
|
(
|
|
pp
|
|
);
|
|
|
|
// Write interpolated volFields
|
|
writer.write(pInter, vsf);
|
|
writer.write(pInter, vvf);
|
|
writer.write(pInter, vSpheretf);
|
|
writer.write(pInter, vSymmtf);
|
|
writer.write(pInter, vtf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// Write faceZones (POLYDATA file, one for each zone)
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
if (doFaceZones)
|
|
{
|
|
PtrList<const surfaceScalarField> ssf;
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
ssf
|
|
);
|
|
print(" surfScalarFields :", Info, ssf);
|
|
|
|
PtrList<const surfaceVectorField> svf;
|
|
readFields
|
|
(
|
|
vMesh,
|
|
vMesh.baseMesh(),
|
|
objects,
|
|
selectedFields,
|
|
svf
|
|
);
|
|
print(" surfVectorFields :", Info, svf);
|
|
|
|
const faceZoneMesh& zones = mesh.faceZones();
|
|
|
|
forAll(zones, zoneI)
|
|
{
|
|
const faceZone& fz = zones[zoneI];
|
|
|
|
mkDir(fvPath/fz.name());
|
|
|
|
fileName patchFileName;
|
|
|
|
if (vMesh.useSubMesh())
|
|
{
|
|
patchFileName =
|
|
fvPath/fz.name()/cellSetName
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk";
|
|
}
|
|
else
|
|
{
|
|
patchFileName =
|
|
fvPath/fz.name()/fz.name()
|
|
+ "_"
|
|
+ timeDesc
|
|
+ ".vtk";
|
|
}
|
|
|
|
Info<< " FaceZone : " << patchFileName << endl;
|
|
|
|
indirectPrimitivePatch pp
|
|
(
|
|
IndirectList<face>(mesh.faces(), fz),
|
|
mesh.points()
|
|
);
|
|
|
|
surfaceMeshWriter writer
|
|
(
|
|
binary,
|
|
pp,
|
|
fz.name(),
|
|
patchFileName
|
|
);
|
|
|
|
// Number of fields
|
|
writeFuns::writeCellDataHeader
|
|
(
|
|
writer.os(),
|
|
pp.size(),
|
|
ssf.size()+svf.size()
|
|
);
|
|
|
|
writer.write(ssf);
|
|
writer.write(svf);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// Write lagrangian data
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
forAll(cloudNames, cloudNo)
|
|
{
|
|
const fileName& cloudName = cloudNames[cloudNo];
|
|
|
|
// Always create the cloud directory.
|
|
mkDir(fvPath/cloud::prefix/cloudName);
|
|
|
|
fileName lagrFileName
|
|
(
|
|
fvPath/cloud::prefix/cloudName/cloudName
|
|
+ "_" + timeDesc + ".vtk"
|
|
);
|
|
|
|
Info<< " Lagrangian: " << lagrFileName << endl;
|
|
|
|
|
|
IOobjectList sprayObjs
|
|
(
|
|
mesh,
|
|
runTime.timeName(),
|
|
cloud::prefix/cloudName
|
|
);
|
|
|
|
if (sprayObjs.found("positions"))
|
|
{
|
|
wordList labelNames(sprayObjs.names(labelIOField::typeName));
|
|
Info<< " labels :";
|
|
print(Info, labelNames);
|
|
|
|
wordList scalarNames(sprayObjs.names(scalarIOField::typeName));
|
|
Info<< " scalars :";
|
|
print(Info, scalarNames);
|
|
|
|
wordList vectorNames(sprayObjs.names(vectorIOField::typeName));
|
|
Info<< " vectors :";
|
|
print(Info, vectorNames);
|
|
|
|
wordList sphereNames
|
|
(
|
|
sprayObjs.names
|
|
(
|
|
sphericalTensorIOField::typeName
|
|
)
|
|
);
|
|
Info<< " spherical tensors :";
|
|
print(Info, sphereNames);
|
|
|
|
wordList symmNames
|
|
(
|
|
sprayObjs.names
|
|
(
|
|
symmTensorIOField::typeName
|
|
)
|
|
);
|
|
Info<< " symm tensors :";
|
|
print(Info, symmNames);
|
|
|
|
wordList tensorNames(sprayObjs.names(tensorIOField::typeName));
|
|
Info<< " tensors :";
|
|
print(Info, tensorNames);
|
|
|
|
lagrangianWriter writer
|
|
(
|
|
vMesh.mesh(),
|
|
binary,
|
|
lagrFileName,
|
|
cloudName,
|
|
false
|
|
);
|
|
|
|
// Write number of fields
|
|
writer.writeParcelHeader
|
|
(
|
|
labelNames.size()
|
|
+ scalarNames.size()
|
|
+ vectorNames.size()
|
|
+ sphereNames.size()
|
|
+ symmNames.size()
|
|
+ tensorNames.size()
|
|
);
|
|
|
|
// Fields
|
|
writer.writeIOField<label>(labelNames);
|
|
writer.writeIOField<scalar>(scalarNames);
|
|
writer.writeIOField<vector>(vectorNames);
|
|
writer.writeIOField<sphericalTensor>(sphereNames);
|
|
writer.writeIOField<symmTensor>(symmNames);
|
|
writer.writeIOField<tensor>(tensorNames);
|
|
}
|
|
else
|
|
{
|
|
lagrangianWriter writer
|
|
(
|
|
vMesh.mesh(),
|
|
binary,
|
|
lagrFileName,
|
|
cloudName,
|
|
true
|
|
);
|
|
|
|
// Write number of fields
|
|
writer.writeParcelHeader(0);
|
|
}
|
|
}
|
|
|
|
Info<< "Wrote in "
|
|
<< timer.cpuTimeIncrement() << " s, "
|
|
<< mem.update().size() << " kB" << endl;
|
|
}
|
|
|
|
|
|
//---------------------------------------------------------------------
|
|
//
|
|
// Link parallel outputs back to undecomposed case for ease of loading
|
|
//
|
|
//---------------------------------------------------------------------
|
|
|
|
if (Pstream::parRun() && doLinks)
|
|
{
|
|
mkDir(runTime.path()/".."/"VTK");
|
|
chDir(runTime.path()/".."/"VTK");
|
|
|
|
Info<< "Linking all processor files to " << runTime.path()/".."/"VTK"
|
|
<< endl;
|
|
|
|
// Get list of vtk files
|
|
fileName procVTK
|
|
(
|
|
fileName("..")
|
|
/"processor" + name(Pstream::myProcNo())
|
|
/"VTK"
|
|
);
|
|
|
|
fileNameList dirs(readDir(procVTK, fileName::DIRECTORY));
|
|
label sz = dirs.size();
|
|
dirs.setSize(sz+1);
|
|
dirs[sz] = ".";
|
|
|
|
forAll(dirs, i)
|
|
{
|
|
fileNameList subFiles(readDir(procVTK/dirs[i], fileName::FILE));
|
|
|
|
forAll(subFiles, j)
|
|
{
|
|
fileName procFile(procVTK/dirs[i]/subFiles[j]);
|
|
|
|
if (exists(procFile))
|
|
{
|
|
string cmd
|
|
(
|
|
"ln -s "
|
|
+ procFile
|
|
+ " "
|
|
+ "processor"
|
|
+ name(Pstream::myProcNo())
|
|
+ "_"
|
|
+ procFile.name()
|
|
);
|
|
if (Foam::system(cmd.c_str()) == -1)
|
|
{
|
|
WarningInFunction
|
|
<< "Could not execute command " << cmd << endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Info<< "\nEnd: "
|
|
<< timer.elapsedCpuTime() << " s, "
|
|
<< mem.update().peak() << " kB (peak)\n" << endl;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|