mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'master' into develop
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
\\ / 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.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -74,7 +74,7 @@ bool writeCloudField
|
||||
template<class Type>
|
||||
bool writeCloudField
|
||||
(
|
||||
const IOobject& fieldObject,
|
||||
IOobject& fieldObject,
|
||||
const bool exists,
|
||||
autoPtr<ensightFile>& output
|
||||
);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,8 +36,8 @@ License
|
||||
template<class Type>
|
||||
bool Foam::ensightCloud::writeCloudField
|
||||
(
|
||||
const Foam::IOField<Type>& field,
|
||||
Foam::ensightFile& os
|
||||
const IOField<Type>& field,
|
||||
ensightFile& os
|
||||
)
|
||||
{
|
||||
const bool exists = (returnReduce(field.size(), sumOp<label>()) > 0);
|
||||
@ -125,14 +125,23 @@ bool Foam::ensightCloud::writeCloudField
|
||||
template<class Type>
|
||||
bool Foam::ensightCloud::writeCloudField
|
||||
(
|
||||
const Foam::IOobject& fieldObject,
|
||||
IOobject& fieldObject,
|
||||
const bool exists,
|
||||
Foam::autoPtr<Foam::ensightFile>& output
|
||||
autoPtr<ensightFile>& output
|
||||
)
|
||||
{
|
||||
if (exists)
|
||||
{
|
||||
// when exists == true, it exists globally,
|
||||
// but can still be missing on the local processor.
|
||||
// Handle this by READ_IF_PRESENT instead.
|
||||
|
||||
const IOobject::readOption rOpt = fieldObject.readOpt();
|
||||
fieldObject.readOpt() = IOobject::READ_IF_PRESENT;
|
||||
|
||||
IOField<Type> field(fieldObject);
|
||||
fieldObject.readOpt() = rOpt;
|
||||
|
||||
writeCloudField(field, output.rawRef());
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ HashTable<HashTable<word>> cloudFields;
|
||||
if (timeDirs.size() && !noLagrangian)
|
||||
{
|
||||
const fileName& baseDir = mesh.time().path();
|
||||
const fileName& cloudPrefix = regionPrefix/cloud::prefix;
|
||||
const fileName cloudPrefix(regionPrefix/cloud::prefix);
|
||||
|
||||
Info<< "Searching for lagrangian ... " << flush;
|
||||
|
||||
@ -35,11 +35,12 @@ if (timeDirs.size() && !noLagrangian)
|
||||
cloudPrefix/cloudName
|
||||
);
|
||||
|
||||
// Clouds always have "positions" (v1706 and lower) or "coordinates"
|
||||
if (cloudObjs.found("positions") || cloudObjs.found("coordinates"))
|
||||
// Clouds require "coordinates".
|
||||
// The "positions" are for v1706 and lower.
|
||||
if (cloudObjs.found("coordinates") || cloudObjs.found("positions"))
|
||||
{
|
||||
// Save the cloud fields on a per cloud basis
|
||||
auto fieldsPerCloud = cloudFields(cloudName);
|
||||
auto& fieldsPerCloud = cloudFields(cloudName);
|
||||
|
||||
forAllConstIters(cloudObjs, fieldIter)
|
||||
{
|
||||
@ -59,6 +60,12 @@ if (timeDirs.size() && !noLagrangian)
|
||||
cloudIter().erase("positions");
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
Pstream::mapCombineGather(cloudFields, HashTablePlusEqOp<word>());
|
||||
Pstream::mapCombineScatter(cloudFields);
|
||||
}
|
||||
|
||||
if (cloudFields.empty())
|
||||
{
|
||||
Info<< "none detected." << endl;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -72,6 +72,8 @@ Note
|
||||
#include "IOobjectList.H"
|
||||
#include "IOmanip.H"
|
||||
#include "OFstream.H"
|
||||
#include "PstreamCombineReduceOps.H"
|
||||
#include "HashTableOps.H"
|
||||
|
||||
#include "fvc.H"
|
||||
#include "volFields.H"
|
||||
@ -622,8 +624,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "Write " << cloudName << " (";
|
||||
|
||||
bool cloudExists = currentCloudDirs.found(cloudName);
|
||||
reduce(cloudExists, orOp<bool>());
|
||||
const bool cloudExists =
|
||||
returnReduce
|
||||
(
|
||||
currentCloudDirs.found(cloudName),
|
||||
orOp<bool>()
|
||||
);
|
||||
|
||||
|
||||
{
|
||||
autoPtr<ensightFile> os = ensCase.newCloud(cloudName);
|
||||
@ -643,10 +650,10 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
forAllConstIter(HashTable<word>, theseCloudFields, fieldIter)
|
||||
forAllConstIters(theseCloudFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
const word& fieldType = fieldIter.object();
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
@ -657,10 +664,13 @@ int main(int argc, char *argv[])
|
||||
IOobject::MUST_READ
|
||||
);
|
||||
|
||||
// cannot have field without cloud positions
|
||||
bool fieldExists = cloudExists;
|
||||
bool fieldExists = cloudExists; // No field without positions
|
||||
if (cloudExists)
|
||||
{
|
||||
// Want MUST_READ (globally) and valid=false (locally),
|
||||
// but that combination does not work.
|
||||
// So check the header and sync globally
|
||||
|
||||
fieldExists =
|
||||
fieldObject.typeHeaderOk<IOField<scalar>>(false);
|
||||
|
||||
|
||||
@ -8,8 +8,8 @@ HashTable<HashTable<word>> cloudFields;
|
||||
|
||||
if (timeDirs.size())
|
||||
{
|
||||
const fileName& cloudPrefix = regionPrefix/cloud::prefix;
|
||||
const word& lastTimeName = timeDirs.last().name();
|
||||
const fileName cloudPrefix(regionPrefix/cloud::prefix);
|
||||
|
||||
IOobjectList objs(mesh, lastTimeName);
|
||||
|
||||
@ -28,7 +28,7 @@ if (timeDirs.size())
|
||||
|
||||
|
||||
//
|
||||
// now check for lagrangian/<cloudName>
|
||||
// Now check for lagrangian/<cloudName>
|
||||
//
|
||||
fileNameList cloudDirs;
|
||||
if (!noLagrangian)
|
||||
@ -46,48 +46,45 @@ if (timeDirs.size())
|
||||
{
|
||||
const word& cloudName = cloudDirs[cloudI];
|
||||
|
||||
// Create a new hash table for each cloud
|
||||
cloudFields.insert(cloudName, HashTable<word>());
|
||||
|
||||
// Identify the new cloud within the hash table
|
||||
HashTable<HashTable<word>>::iterator cloudIter =
|
||||
cloudFields.find(cloudName);
|
||||
|
||||
IOobjectList objs
|
||||
IOobjectList cloudObjs
|
||||
(
|
||||
mesh,
|
||||
lastTimeName,
|
||||
cloudPrefix/cloudName
|
||||
);
|
||||
|
||||
bool hasCoordinates = false;
|
||||
forAllConstIter(IOobjectList, objs, fieldIter)
|
||||
// Clouds require "coordinates".
|
||||
// The "positions" are for v1706 and lower.
|
||||
if (cloudObjs.found("coordinates") || cloudObjs.found("positions"))
|
||||
{
|
||||
const IOobject obj = *fieldIter();
|
||||
const word& fieldName = obj.name();
|
||||
const word& fieldType = obj.headerClassName();
|
||||
// Save the cloud fields on a per cloud basis
|
||||
auto& fieldsPerCloud = cloudFields(cloudName);
|
||||
|
||||
if (fieldName == "positions" || fieldName == "coordinates")
|
||||
forAllConstIters(cloudObjs, fieldIter)
|
||||
{
|
||||
hasCoordinates = true;
|
||||
}
|
||||
else if (cloudFieldTypes.found(fieldType))
|
||||
{
|
||||
// simply ignore types that we don't handle
|
||||
cloudIter().insert(fieldName, fieldType);
|
||||
}
|
||||
}
|
||||
const IOobject* obj = fieldIter();
|
||||
|
||||
// drop this cloud if it has no positions or is otherwise empty
|
||||
if (!hasCoordinates || cloudIter().empty())
|
||||
{
|
||||
Info<< "removing cloud " << cloudName << endl;
|
||||
cloudFields.erase(cloudIter);
|
||||
const word& fieldName = obj->name();
|
||||
const word& fieldType = obj->headerClassName();
|
||||
|
||||
if (cloudFieldTypes.found(fieldType))
|
||||
{
|
||||
// Field name/type - ignore types that we don't handle
|
||||
fieldsPerCloud.insert(fieldName, fieldType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only retain a cloud that actually has fields
|
||||
cloudFields.filterValues
|
||||
(
|
||||
[](const HashTable<word>& v){ return v.size(); }
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// verify that the variable is present for all times
|
||||
// Verify that the variable is present for all times
|
||||
//
|
||||
for (label i=0; volumeFields.size() && i < timeDirs.size(); ++i)
|
||||
{
|
||||
@ -114,3 +111,6 @@ if (timeDirs.size())
|
||||
volumeFields.erase(missing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / 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.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -275,10 +275,10 @@ int main(int argc, char *argv[])
|
||||
|
||||
Info<< "Write volume field (" << flush;
|
||||
|
||||
forAllConstIter(HashTable<word>, volumeFields, fieldIter)
|
||||
forAllConstIters(volumeFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
const word& fieldType = fieldIter.object();
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
@ -364,10 +364,12 @@ int main(int argc, char *argv[])
|
||||
Info<< " )" << endl;
|
||||
|
||||
// Check for clouds
|
||||
forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter)
|
||||
forAllConstIters(cloudFields, cloudIter)
|
||||
{
|
||||
const word& cloudName = cloudIter.key();
|
||||
const fileName& cloudPrefix = regionPrefix/cloud::prefix;
|
||||
const HashTable<word>& theseCloudFields = cloudIter.object();
|
||||
|
||||
const fileName cloudPrefix(regionPrefix/cloud::prefix);
|
||||
|
||||
if (!isDir(runTime.timePath()/cloudPrefix/cloudName))
|
||||
{
|
||||
@ -381,13 +383,15 @@ int main(int argc, char *argv[])
|
||||
cloudPrefix/cloudName
|
||||
);
|
||||
|
||||
// Check that the positions/coordinates field is present for this
|
||||
// time
|
||||
if
|
||||
// Clouds require "coordinates".
|
||||
// The "positions" are for v1706 and lower.
|
||||
const bool cloudExists =
|
||||
(
|
||||
!cloudObjs.found("positions")
|
||||
|| !cloudObjs.found("coordinates")
|
||||
)
|
||||
cloudObjs.found("coordinates")
|
||||
|| cloudObjs.found("positions")
|
||||
);
|
||||
|
||||
if (!cloudExists)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -403,18 +407,17 @@ int main(int argc, char *argv[])
|
||||
Info<< " positions";
|
||||
|
||||
|
||||
forAllConstIter(HashTable<word>, cloudIter(), fieldIter)
|
||||
forAllConstIters(theseCloudFields, fieldIter)
|
||||
{
|
||||
const word& fieldName = fieldIter.key();
|
||||
const word& fieldType = fieldIter();
|
||||
const word& fieldType = fieldIter.object();
|
||||
|
||||
IOobject *fieldObject = cloudObjs.lookup(fieldName);
|
||||
|
||||
if (!fieldObject)
|
||||
{
|
||||
Info<< "missing "
|
||||
<< runTime.timeName()/cloudPrefix/cloudName
|
||||
/ fieldName
|
||||
<< runTime.timeName()/cloudPrefix/cloudName/fieldName
|
||||
<< endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
// check all time directories for the following:
|
||||
|
||||
// Any cloud names:
|
||||
HashSet<fileName> allCloudDirs;
|
||||
HashSet<word> allCloudDirs;
|
||||
|
||||
if (timeDirs.size() && !noLagrangian)
|
||||
{
|
||||
const fileName& baseDir = mesh.time().path();
|
||||
const fileName& cloudPrefix = regionPrefix/cloud::prefix;
|
||||
const fileName cloudPrefix(regionPrefix/cloud::prefix);
|
||||
|
||||
Info<< "Searching for lagrangian ... " << flush;
|
||||
|
||||
@ -32,14 +32,15 @@ if (timeDirs.size() && !noLagrangian)
|
||||
cloudPrefix/cloudName
|
||||
);
|
||||
|
||||
// Clouds always require "positions"/"coordinates"
|
||||
if (cloudObjs.found("positions") || cloudObjs.found("coordinates"))
|
||||
// Clouds require "coordinates".
|
||||
// The "positions" are for v1706 and lower.
|
||||
if (cloudObjs.found("coordinates") || cloudObjs.found("positions"))
|
||||
{
|
||||
if (allCloudDirs.insert(cloudName))
|
||||
{
|
||||
Info<< "At time: " << timeName
|
||||
Info<< nl << " At time: " << timeName
|
||||
<< " detected cloud directory : " << cloudName
|
||||
<< endl;
|
||||
<< flush;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,14 +50,21 @@ if (timeDirs.size() && !noLagrangian)
|
||||
{
|
||||
Info<< "none detected." << endl;
|
||||
}
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
Pstream::combineGather(allCloudDirs, HashSetPlusEqOp<word>());
|
||||
Pstream::combineScatter(allCloudDirs);
|
||||
}
|
||||
}
|
||||
|
||||
// sorted list of cloud names
|
||||
const fileNameList cloudNames(allCloudDirs.sortedToc());
|
||||
|
||||
// Sorted list of cloud names
|
||||
const wordList cloudNames(allCloudDirs.sortedToc());
|
||||
|
||||
if (cloudNames.size())
|
||||
{
|
||||
// complete the echo information
|
||||
// Complete the echo information
|
||||
Info<< "(";
|
||||
for (const word& cloudName : cloudNames)
|
||||
{
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -146,6 +146,8 @@ Note
|
||||
#include "pointMesh.H"
|
||||
#include "volPointInterpolation.H"
|
||||
#include "emptyPolyPatch.H"
|
||||
#include "PstreamCombineReduceOps.H"
|
||||
#include "HashTableOps.H"
|
||||
#include "labelIOField.H"
|
||||
#include "scalarIOField.H"
|
||||
#include "sphericalTensorIOField.H"
|
||||
@ -156,7 +158,6 @@ Note
|
||||
#include "passiveParticle.H"
|
||||
#include "stringOps.H"
|
||||
#include "areaFields.H"
|
||||
|
||||
#include "meshSubsetHelper.H"
|
||||
#include "readFields.H"
|
||||
#include "faceSet.H"
|
||||
@ -190,13 +191,17 @@ void print(const char* msg, Ostream& os, const UPtrList<const GeoField>& flds)
|
||||
}
|
||||
|
||||
|
||||
void print(Ostream& os, const wordList& flds)
|
||||
void print(const char* msg, Ostream& os, const wordList& flds)
|
||||
{
|
||||
forAll(flds, i)
|
||||
if (flds.size())
|
||||
{
|
||||
os << ' ' << flds[i];
|
||||
os << msg;
|
||||
forAll(flds, i)
|
||||
{
|
||||
os << ' ' << flds[i];
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
os << endl;
|
||||
}
|
||||
|
||||
|
||||
@ -617,6 +622,16 @@ int main(int argc, char *argv[])
|
||||
pointTensorField::typeName
|
||||
};
|
||||
|
||||
// Supported cloud (lagrangian) field types
|
||||
const wordHashSet cFieldTypes
|
||||
{
|
||||
labelIOField::typeName,
|
||||
scalarIOField::typeName,
|
||||
vectorIOField::typeName,
|
||||
symmTensorIOField::typeName,
|
||||
tensorIOField::typeName
|
||||
};
|
||||
|
||||
forAll(timeDirs, timei)
|
||||
{
|
||||
runTime.setTime(timeDirs[timei], timei);
|
||||
@ -1446,7 +1461,7 @@ int main(int argc, char *argv[])
|
||||
//
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
for (const fileName& cloudName : cloudNames)
|
||||
for (const word& cloudName : cloudNames)
|
||||
{
|
||||
// Always create the cloud directory.
|
||||
mkDir(fvPath/cloud::prefix/cloudName);
|
||||
@ -1459,50 +1474,84 @@ int main(int argc, char *argv[])
|
||||
Info<< " Lagrangian: "
|
||||
<< relativeName(runTime, outputName) << nl;
|
||||
|
||||
IOobjectList sprayObjs
|
||||
IOobjectList cloudObjs
|
||||
(
|
||||
mesh,
|
||||
runTime.timeName(),
|
||||
cloud::prefix/cloudName
|
||||
);
|
||||
|
||||
if (sprayObjs.found("positions") || sprayObjs.found("coordinates"))
|
||||
// Clouds require "coordinates".
|
||||
// The "positions" are for v1706 and lower.
|
||||
bool cloudExists =
|
||||
(
|
||||
cloudObjs.found("coordinates")
|
||||
|| cloudObjs.found("positions")
|
||||
);
|
||||
reduce(cloudExists, orOp<bool>());
|
||||
|
||||
if (cloudExists)
|
||||
{
|
||||
wordList labelNames(sprayObjs.names(labelIOField::typeName));
|
||||
Info<< " labels :";
|
||||
print(Info, labelNames);
|
||||
// Limited to types that we explicitly handle
|
||||
HashTable<wordHashSet> cloudFields = cloudObjs.classes();
|
||||
cloudFields.retain(cFieldTypes);
|
||||
|
||||
wordList scalarNames(sprayObjs.names(scalarIOField::typeName));
|
||||
Info<< " scalars :";
|
||||
print(Info, scalarNames);
|
||||
// The number of cloud fields (locally)
|
||||
label nCloudFields = 0;
|
||||
forAllConstIters(cloudFields, citer)
|
||||
{
|
||||
nCloudFields += citer.object().size();
|
||||
}
|
||||
|
||||
wordList vectorNames(sprayObjs.names(vectorIOField::typeName));
|
||||
Info<< " vectors :";
|
||||
print(Info, vectorNames);
|
||||
|
||||
wordList sphereNames
|
||||
(
|
||||
sprayObjs.names
|
||||
// Ensure all processes have identical information
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
Pstream::mapCombineGather
|
||||
(
|
||||
sphericalTensorIOField::typeName
|
||||
)
|
||||
);
|
||||
Info<< " sphTensors :";
|
||||
print(Info, sphereNames);
|
||||
cloudFields,
|
||||
HashSetPlusEqOp<word>()
|
||||
);
|
||||
Pstream::mapCombineScatter(cloudFields);
|
||||
}
|
||||
|
||||
wordList symmNames
|
||||
|
||||
// Build lists of field names and echo some information
|
||||
|
||||
const wordList labelNames
|
||||
(
|
||||
sprayObjs.names
|
||||
(
|
||||
symmTensorIOField::typeName
|
||||
)
|
||||
cloudFields(labelIOField::typeName).sortedToc()
|
||||
);
|
||||
Info<< " symmTensors :";
|
||||
print(Info, symmNames);
|
||||
print(" labels :", Info, labelNames);
|
||||
|
||||
wordList tensorNames(sprayObjs.names(tensorIOField::typeName));
|
||||
Info<< " tensors :";
|
||||
print(Info, tensorNames);
|
||||
const wordList scalarNames
|
||||
(
|
||||
cloudFields(scalarIOField::typeName).sortedToc()
|
||||
);
|
||||
print(" scalars :", Info, scalarNames);
|
||||
|
||||
const wordList vectorNames
|
||||
(
|
||||
cloudFields(vectorIOField::typeName).sortedToc()
|
||||
);
|
||||
print(" vectors :", Info, vectorNames);
|
||||
|
||||
const wordList sphNames
|
||||
(
|
||||
cloudFields(sphericalTensorIOField::typeName).sortedToc()
|
||||
);
|
||||
print(" sphTensors :", Info, sphNames);
|
||||
|
||||
const wordList symmNames
|
||||
(
|
||||
cloudFields(symmTensorIOField::typeName).sortedToc()
|
||||
);
|
||||
print(" symmTensors :", Info, symmNames);
|
||||
|
||||
const wordList tensorNames
|
||||
(
|
||||
cloudFields(tensorIOField::typeName).sortedToc()
|
||||
);
|
||||
print(" tensors :", Info, tensorNames);
|
||||
|
||||
vtk::lagrangianWriter writer
|
||||
(
|
||||
@ -1512,22 +1561,14 @@ int main(int argc, char *argv[])
|
||||
fmtType
|
||||
);
|
||||
|
||||
// Write number of fields
|
||||
writer.beginParcelData
|
||||
(
|
||||
labelNames.size()
|
||||
+ scalarNames.size()
|
||||
+ vectorNames.size()
|
||||
+ sphereNames.size()
|
||||
+ symmNames.size()
|
||||
+ tensorNames.size()
|
||||
);
|
||||
// Write number of fields (on this processor)
|
||||
writer.beginParcelData(nCloudFields);
|
||||
|
||||
// Fields
|
||||
writer.writeIOField<label>(labelNames);
|
||||
writer.writeIOField<scalar>(scalarNames);
|
||||
writer.writeIOField<vector>(vectorNames);
|
||||
writer.writeIOField<sphericalTensor>(sphereNames);
|
||||
writer.writeIOField<sphericalTensor>(sphNames);
|
||||
writer.writeIOField<symmTensor>(symmNames);
|
||||
writer.writeIOField<tensor>(tensorNames);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -65,7 +65,8 @@ void Foam::vtk::lagrangianWriter::writePoints()
|
||||
}
|
||||
else
|
||||
{
|
||||
beginPiece(); // Tricky - hide in here
|
||||
beginPiece(); // Tricky - hide begin piece in here
|
||||
if (!nParcels_) return; // No parcels? ... skip everything else
|
||||
|
||||
format().tag(vtk::fileTag::POINTS)
|
||||
.openDataArray<float,3>(vtk::dataArrayAttr::POINTS)
|
||||
@ -219,16 +220,12 @@ Foam::vtk::lagrangianWriter::lagrangianWriter
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::vtk::lagrangianWriter::~lagrangianWriter()
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::vtk::lagrangianWriter::beginParcelData(label nFields)
|
||||
{
|
||||
if (!nParcels_) return; // Skip if there are no parcels
|
||||
|
||||
const vtk::fileTag dataType =
|
||||
(
|
||||
useVerts_
|
||||
@ -249,6 +246,8 @@ void Foam::vtk::lagrangianWriter::beginParcelData(label nFields)
|
||||
|
||||
void Foam::vtk::lagrangianWriter::endParcelData()
|
||||
{
|
||||
if (!nParcels_) return; // Skip if there are no parcels
|
||||
|
||||
const vtk::fileTag dataType =
|
||||
(
|
||||
useVerts_
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / 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.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -25,7 +25,7 @@ Class
|
||||
Foam::vtk::lagrangianWriter
|
||||
|
||||
Description
|
||||
Write fields (internal).
|
||||
Write lagrangian positions and fields (clouds).
|
||||
|
||||
SourceFiles
|
||||
lagrangianWriter.C
|
||||
@ -36,11 +36,11 @@ SourceFiles
|
||||
#ifndef foamVtkLagrangianWriter_H
|
||||
#define foamVtkLagrangianWriter_H
|
||||
|
||||
#include "OFstream.H"
|
||||
#include "Cloud.H"
|
||||
#include "volFields.H"
|
||||
#include "pointFields.H"
|
||||
#include "foamVtkOutputOptions.H"
|
||||
#include <fstream>
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -115,7 +115,7 @@ public:
|
||||
|
||||
|
||||
//- Destructor
|
||||
~lagrangianWriter();
|
||||
~lagrangianWriter() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
@ -135,15 +135,17 @@ public:
|
||||
return nParcels_;
|
||||
}
|
||||
|
||||
//- Begin parcel data (point data).
|
||||
// The nFields parameter is only needed for legacy format.
|
||||
void beginParcelData(label nFields);
|
||||
void endParcelData();
|
||||
|
||||
//- Write file footer
|
||||
void writeFooter();
|
||||
|
||||
//- Write IOField
|
||||
//- Write IOFields
|
||||
template<class Type>
|
||||
void writeIOField(const wordList& objectNames);
|
||||
void writeIOField(const wordList& fieldNames);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -29,30 +29,48 @@ License
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
void Foam::vtk::lagrangianWriter::writeIOField
|
||||
(
|
||||
const wordList& objectNames
|
||||
)
|
||||
void Foam::vtk::lagrangianWriter::writeIOField(const wordList& fieldNames)
|
||||
{
|
||||
const int nCmpt(pTraits<Type>::nComponents);
|
||||
|
||||
const bool useIntField =
|
||||
std::is_integral<typename pTraits<Type>::cmptType>();
|
||||
|
||||
for (const word& fldName : objectNames)
|
||||
const fileName cloudDir(cloud::prefix/cloudName_);
|
||||
|
||||
for (const word& fldName : fieldNames)
|
||||
{
|
||||
IOobject header
|
||||
// Globally the field is expected to exist (MUST_READ), but can
|
||||
// be missing on a local processor.
|
||||
//
|
||||
// However, constructing IOField with MUST_READ and valid=false fails.
|
||||
// Workaround: READ_IF_PRESENT and verify the header globally
|
||||
|
||||
IOobject fieldObject
|
||||
(
|
||||
fldName,
|
||||
mesh_.time().timeName(),
|
||||
cloud::prefix/cloudName_,
|
||||
cloudDir,
|
||||
mesh_,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // no register
|
||||
IOobject::READ_IF_PRESENT
|
||||
);
|
||||
|
||||
IOField<Type> fld(header);
|
||||
// Check global existence - could make an error
|
||||
const bool fieldExists =
|
||||
returnReduce
|
||||
(
|
||||
fieldObject.typeHeaderOk<IOField<Type>>(false),
|
||||
orOp<bool>()
|
||||
);
|
||||
|
||||
if (!fieldExists)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
IOField<Type> fld(fieldObject);
|
||||
|
||||
// NOTE: Could skip if there are no local parcels...
|
||||
|
||||
if (useIntField)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user