Merge branch 'master' into develop

This commit is contained in:
Mark Olesen
2018-01-23 16:11:28 +01:00
14 changed files with 345 additions and 150 deletions

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -74,7 +74,7 @@ bool writeCloudField
template<class Type> template<class Type>
bool writeCloudField bool writeCloudField
( (
const IOobject& fieldObject, IOobject& fieldObject,
const bool exists, const bool exists,
autoPtr<ensightFile>& output autoPtr<ensightFile>& output
); );

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / 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 License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -36,8 +36,8 @@ License
template<class Type> template<class Type>
bool Foam::ensightCloud::writeCloudField bool Foam::ensightCloud::writeCloudField
( (
const Foam::IOField<Type>& field, const IOField<Type>& field,
Foam::ensightFile& os ensightFile& os
) )
{ {
const bool exists = (returnReduce(field.size(), sumOp<label>()) > 0); const bool exists = (returnReduce(field.size(), sumOp<label>()) > 0);
@ -125,14 +125,23 @@ bool Foam::ensightCloud::writeCloudField
template<class Type> template<class Type>
bool Foam::ensightCloud::writeCloudField bool Foam::ensightCloud::writeCloudField
( (
const Foam::IOobject& fieldObject, IOobject& fieldObject,
const bool exists, const bool exists,
Foam::autoPtr<Foam::ensightFile>& output autoPtr<ensightFile>& output
) )
{ {
if (exists) 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); IOField<Type> field(fieldObject);
fieldObject.readOpt() = rOpt;
writeCloudField(field, output.rawRef()); writeCloudField(field, output.rawRef());
} }

View File

@ -7,7 +7,7 @@ HashTable<HashTable<word>> cloudFields;
if (timeDirs.size() && !noLagrangian) if (timeDirs.size() && !noLagrangian)
{ {
const fileName& baseDir = mesh.time().path(); const fileName& baseDir = mesh.time().path();
const fileName& cloudPrefix = regionPrefix/cloud::prefix; const fileName cloudPrefix(regionPrefix/cloud::prefix);
Info<< "Searching for lagrangian ... " << flush; Info<< "Searching for lagrangian ... " << flush;
@ -35,11 +35,12 @@ if (timeDirs.size() && !noLagrangian)
cloudPrefix/cloudName cloudPrefix/cloudName
); );
// Clouds always have "positions" (v1706 and lower) or "coordinates" // Clouds require "coordinates".
if (cloudObjs.found("positions") || cloudObjs.found("coordinates")) // The "positions" are for v1706 and lower.
if (cloudObjs.found("coordinates") || cloudObjs.found("positions"))
{ {
// Save the cloud fields on a per cloud basis // Save the cloud fields on a per cloud basis
auto fieldsPerCloud = cloudFields(cloudName); auto& fieldsPerCloud = cloudFields(cloudName);
forAllConstIters(cloudObjs, fieldIter) forAllConstIters(cloudObjs, fieldIter)
{ {
@ -59,6 +60,12 @@ if (timeDirs.size() && !noLagrangian)
cloudIter().erase("positions"); cloudIter().erase("positions");
} }
if (Pstream::parRun())
{
Pstream::mapCombineGather(cloudFields, HashTablePlusEqOp<word>());
Pstream::mapCombineScatter(cloudFields);
}
if (cloudFields.empty()) if (cloudFields.empty())
{ {
Info<< "none detected." << endl; Info<< "none detected." << endl;

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / 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 License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -72,6 +72,8 @@ Note
#include "IOobjectList.H" #include "IOobjectList.H"
#include "IOmanip.H" #include "IOmanip.H"
#include "OFstream.H" #include "OFstream.H"
#include "PstreamCombineReduceOps.H"
#include "HashTableOps.H"
#include "fvc.H" #include "fvc.H"
#include "volFields.H" #include "volFields.H"
@ -622,8 +624,13 @@ int main(int argc, char *argv[])
Info<< "Write " << cloudName << " ("; Info<< "Write " << cloudName << " (";
bool cloudExists = currentCloudDirs.found(cloudName); const bool cloudExists =
reduce(cloudExists, orOp<bool>()); returnReduce
(
currentCloudDirs.found(cloudName),
orOp<bool>()
);
{ {
autoPtr<ensightFile> os = ensCase.newCloud(cloudName); 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& fieldName = fieldIter.key();
const word& fieldType = fieldIter(); const word& fieldType = fieldIter.object();
IOobject fieldObject IOobject fieldObject
( (
@ -657,10 +664,13 @@ int main(int argc, char *argv[])
IOobject::MUST_READ IOobject::MUST_READ
); );
// cannot have field without cloud positions bool fieldExists = cloudExists; // No field without positions
bool fieldExists = cloudExists;
if (cloudExists) if (cloudExists)
{ {
// Want MUST_READ (globally) and valid=false (locally),
// but that combination does not work.
// So check the header and sync globally
fieldExists = fieldExists =
fieldObject.typeHeaderOk<IOField<scalar>>(false); fieldObject.typeHeaderOk<IOField<scalar>>(false);

View File

@ -8,8 +8,8 @@ HashTable<HashTable<word>> cloudFields;
if (timeDirs.size()) if (timeDirs.size())
{ {
const fileName& cloudPrefix = regionPrefix/cloud::prefix;
const word& lastTimeName = timeDirs.last().name(); const word& lastTimeName = timeDirs.last().name();
const fileName cloudPrefix(regionPrefix/cloud::prefix);
IOobjectList objs(mesh, lastTimeName); IOobjectList objs(mesh, lastTimeName);
@ -28,7 +28,7 @@ if (timeDirs.size())
// //
// now check for lagrangian/<cloudName> // Now check for lagrangian/<cloudName>
// //
fileNameList cloudDirs; fileNameList cloudDirs;
if (!noLagrangian) if (!noLagrangian)
@ -46,48 +46,45 @@ if (timeDirs.size())
{ {
const word& cloudName = cloudDirs[cloudI]; const word& cloudName = cloudDirs[cloudI];
// Create a new hash table for each cloud IOobjectList cloudObjs
cloudFields.insert(cloudName, HashTable<word>());
// Identify the new cloud within the hash table
HashTable<HashTable<word>>::iterator cloudIter =
cloudFields.find(cloudName);
IOobjectList objs
( (
mesh, mesh,
lastTimeName, lastTimeName,
cloudPrefix/cloudName cloudPrefix/cloudName
); );
bool hasCoordinates = false; // Clouds require "coordinates".
forAllConstIter(IOobjectList, objs, fieldIter) // The "positions" are for v1706 and lower.
if (cloudObjs.found("coordinates") || cloudObjs.found("positions"))
{ {
const IOobject obj = *fieldIter(); // Save the cloud fields on a per cloud basis
const word& fieldName = obj.name(); auto& fieldsPerCloud = cloudFields(cloudName);
const word& fieldType = obj.headerClassName();
if (fieldName == "positions" || fieldName == "coordinates") forAllConstIters(cloudObjs, fieldIter)
{ {
hasCoordinates = true; const IOobject* obj = fieldIter();
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);
}
} }
else if (cloudFieldTypes.found(fieldType))
{
// simply ignore types that we don't handle
cloudIter().insert(fieldName, fieldType);
} }
} }
// drop this cloud if it has no positions or is otherwise empty // Only retain a cloud that actually has fields
if (!hasCoordinates || cloudIter().empty()) cloudFields.filterValues
{ (
Info<< "removing cloud " << cloudName << endl; [](const HashTable<word>& v){ return v.size(); }
cloudFields.erase(cloudIter); );
}
}
// //
// 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) for (label i=0; volumeFields.size() && i < timeDirs.size(); ++i)
{ {
@ -114,3 +111,6 @@ if (timeDirs.size())
volumeFields.erase(missing); volumeFields.erase(missing);
} }
} }
// ************************************************************************* //

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -275,10 +275,10 @@ int main(int argc, char *argv[])
Info<< "Write volume field (" << flush; Info<< "Write volume field (" << flush;
forAllConstIter(HashTable<word>, volumeFields, fieldIter) forAllConstIters(volumeFields, fieldIter)
{ {
const word& fieldName = fieldIter.key(); const word& fieldName = fieldIter.key();
const word& fieldType = fieldIter(); const word& fieldType = fieldIter.object();
IOobject fieldObject IOobject fieldObject
( (
@ -364,10 +364,12 @@ int main(int argc, char *argv[])
Info<< " )" << endl; Info<< " )" << endl;
// Check for clouds // Check for clouds
forAllConstIter(HashTable<HashTable<word>>, cloudFields, cloudIter) forAllConstIters(cloudFields, cloudIter)
{ {
const word& cloudName = cloudIter.key(); 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)) if (!isDir(runTime.timePath()/cloudPrefix/cloudName))
{ {
@ -381,13 +383,15 @@ int main(int argc, char *argv[])
cloudPrefix/cloudName cloudPrefix/cloudName
); );
// Check that the positions/coordinates field is present for this // Clouds require "coordinates".
// time // The "positions" are for v1706 and lower.
if const bool cloudExists =
( (
!cloudObjs.found("positions") cloudObjs.found("coordinates")
|| !cloudObjs.found("coordinates") || cloudObjs.found("positions")
) );
if (!cloudExists)
{ {
continue; continue;
} }
@ -403,18 +407,17 @@ int main(int argc, char *argv[])
Info<< " positions"; Info<< " positions";
forAllConstIter(HashTable<word>, cloudIter(), fieldIter) forAllConstIters(theseCloudFields, fieldIter)
{ {
const word& fieldName = fieldIter.key(); const word& fieldName = fieldIter.key();
const word& fieldType = fieldIter(); const word& fieldType = fieldIter.object();
IOobject *fieldObject = cloudObjs.lookup(fieldName); IOobject *fieldObject = cloudObjs.lookup(fieldName);
if (!fieldObject) if (!fieldObject)
{ {
Info<< "missing " Info<< "missing "
<< runTime.timeName()/cloudPrefix/cloudName << runTime.timeName()/cloudPrefix/cloudName/fieldName
/ fieldName
<< endl; << endl;
continue; continue;
} }

View File

@ -1,12 +1,12 @@
// check all time directories for the following: // check all time directories for the following:
// Any cloud names: // Any cloud names:
HashSet<fileName> allCloudDirs; HashSet<word> allCloudDirs;
if (timeDirs.size() && !noLagrangian) if (timeDirs.size() && !noLagrangian)
{ {
const fileName& baseDir = mesh.time().path(); const fileName& baseDir = mesh.time().path();
const fileName& cloudPrefix = regionPrefix/cloud::prefix; const fileName cloudPrefix(regionPrefix/cloud::prefix);
Info<< "Searching for lagrangian ... " << flush; Info<< "Searching for lagrangian ... " << flush;
@ -32,14 +32,15 @@ if (timeDirs.size() && !noLagrangian)
cloudPrefix/cloudName cloudPrefix/cloudName
); );
// Clouds always require "positions"/"coordinates" // Clouds require "coordinates".
if (cloudObjs.found("positions") || cloudObjs.found("coordinates")) // The "positions" are for v1706 and lower.
if (cloudObjs.found("coordinates") || cloudObjs.found("positions"))
{ {
if (allCloudDirs.insert(cloudName)) if (allCloudDirs.insert(cloudName))
{ {
Info<< "At time: " << timeName Info<< nl << " At time: " << timeName
<< " detected cloud directory : " << cloudName << " detected cloud directory : " << cloudName
<< endl; << flush;
} }
} }
} }
@ -49,14 +50,21 @@ if (timeDirs.size() && !noLagrangian)
{ {
Info<< "none detected." << endl; 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()) if (cloudNames.size())
{ {
// complete the echo information // Complete the echo information
Info<< "("; Info<< "(";
for (const word& cloudName : cloudNames) for (const word& cloudName : cloudNames)
{ {

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / 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 License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -146,6 +146,8 @@ Note
#include "pointMesh.H" #include "pointMesh.H"
#include "volPointInterpolation.H" #include "volPointInterpolation.H"
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "PstreamCombineReduceOps.H"
#include "HashTableOps.H"
#include "labelIOField.H" #include "labelIOField.H"
#include "scalarIOField.H" #include "scalarIOField.H"
#include "sphericalTensorIOField.H" #include "sphericalTensorIOField.H"
@ -156,7 +158,6 @@ Note
#include "passiveParticle.H" #include "passiveParticle.H"
#include "stringOps.H" #include "stringOps.H"
#include "areaFields.H" #include "areaFields.H"
#include "meshSubsetHelper.H" #include "meshSubsetHelper.H"
#include "readFields.H" #include "readFields.H"
#include "faceSet.H" #include "faceSet.H"
@ -190,14 +191,18 @@ 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)
{ {
if (flds.size())
{
os << msg;
forAll(flds, i) forAll(flds, i)
{ {
os << ' ' << flds[i]; os << ' ' << flds[i];
} }
os << endl; os << endl;
} }
}
labelList getSelectedPatches labelList getSelectedPatches
@ -617,6 +622,16 @@ int main(int argc, char *argv[])
pointTensorField::typeName pointTensorField::typeName
}; };
// Supported cloud (lagrangian) field types
const wordHashSet cFieldTypes
{
labelIOField::typeName,
scalarIOField::typeName,
vectorIOField::typeName,
symmTensorIOField::typeName,
tensorIOField::typeName
};
forAll(timeDirs, timei) forAll(timeDirs, timei)
{ {
runTime.setTime(timeDirs[timei], 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. // Always create the cloud directory.
mkDir(fvPath/cloud::prefix/cloudName); mkDir(fvPath/cloud::prefix/cloudName);
@ -1459,50 +1474,84 @@ int main(int argc, char *argv[])
Info<< " Lagrangian: " Info<< " Lagrangian: "
<< relativeName(runTime, outputName) << nl; << relativeName(runTime, outputName) << nl;
IOobjectList sprayObjs IOobjectList cloudObjs
( (
mesh, mesh,
runTime.timeName(), runTime.timeName(),
cloud::prefix/cloudName 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)); // Limited to types that we explicitly handle
Info<< " labels :"; HashTable<wordHashSet> cloudFields = cloudObjs.classes();
print(Info, labelNames); cloudFields.retain(cFieldTypes);
wordList scalarNames(sprayObjs.names(scalarIOField::typeName)); // The number of cloud fields (locally)
Info<< " scalars :"; label nCloudFields = 0;
print(Info, scalarNames); forAllConstIters(cloudFields, citer)
{
nCloudFields += citer.object().size();
}
wordList vectorNames(sprayObjs.names(vectorIOField::typeName)); // Ensure all processes have identical information
Info<< " vectors :"; if (Pstream::parRun())
print(Info, vectorNames); {
Pstream::mapCombineGather
wordList sphereNames
( (
sprayObjs.names cloudFields,
( HashSetPlusEqOp<word>()
sphericalTensorIOField::typeName
)
); );
Info<< " sphTensors :"; Pstream::mapCombineScatter(cloudFields);
print(Info, sphereNames); }
wordList symmNames
// Build lists of field names and echo some information
const wordList labelNames
( (
sprayObjs.names cloudFields(labelIOField::typeName).sortedToc()
(
symmTensorIOField::typeName
)
); );
Info<< " symmTensors :"; print(" labels :", Info, labelNames);
print(Info, symmNames);
wordList tensorNames(sprayObjs.names(tensorIOField::typeName)); const wordList scalarNames
Info<< " tensors :"; (
print(Info, tensorNames); 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 vtk::lagrangianWriter writer
( (
@ -1512,22 +1561,14 @@ int main(int argc, char *argv[])
fmtType fmtType
); );
// Write number of fields // Write number of fields (on this processor)
writer.beginParcelData writer.beginParcelData(nCloudFields);
(
labelNames.size()
+ scalarNames.size()
+ vectorNames.size()
+ sphereNames.size()
+ symmNames.size()
+ tensorNames.size()
);
// Fields // Fields
writer.writeIOField<label>(labelNames); writer.writeIOField<label>(labelNames);
writer.writeIOField<scalar>(scalarNames); writer.writeIOField<scalar>(scalarNames);
writer.writeIOField<vector>(vectorNames); writer.writeIOField<vector>(vectorNames);
writer.writeIOField<sphericalTensor>(sphereNames); writer.writeIOField<sphericalTensor>(sphNames);
writer.writeIOField<symmTensor>(symmNames); writer.writeIOField<symmTensor>(symmNames);
writer.writeIOField<tensor>(tensorNames); writer.writeIOField<tensor>(tensorNames);

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / 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 License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -65,7 +65,8 @@ void Foam::vtk::lagrangianWriter::writePoints()
} }
else 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) format().tag(vtk::fileTag::POINTS)
.openDataArray<float,3>(vtk::dataArrayAttr::POINTS) .openDataArray<float,3>(vtk::dataArrayAttr::POINTS)
@ -219,16 +220,12 @@ Foam::vtk::lagrangianWriter::lagrangianWriter
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::vtk::lagrangianWriter::~lagrangianWriter()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vtk::lagrangianWriter::beginParcelData(label nFields) void Foam::vtk::lagrangianWriter::beginParcelData(label nFields)
{ {
if (!nParcels_) return; // Skip if there are no parcels
const vtk::fileTag dataType = const vtk::fileTag dataType =
( (
useVerts_ useVerts_
@ -249,6 +246,8 @@ void Foam::vtk::lagrangianWriter::beginParcelData(label nFields)
void Foam::vtk::lagrangianWriter::endParcelData() void Foam::vtk::lagrangianWriter::endParcelData()
{ {
if (!nParcels_) return; // Skip if there are no parcels
const vtk::fileTag dataType = const vtk::fileTag dataType =
( (
useVerts_ useVerts_

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
\\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. \\/ M anipulation | Copyright (C) 2016-2018 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -25,7 +25,7 @@ Class
Foam::vtk::lagrangianWriter Foam::vtk::lagrangianWriter
Description Description
Write fields (internal). Write lagrangian positions and fields (clouds).
SourceFiles SourceFiles
lagrangianWriter.C lagrangianWriter.C
@ -36,11 +36,11 @@ SourceFiles
#ifndef foamVtkLagrangianWriter_H #ifndef foamVtkLagrangianWriter_H
#define foamVtkLagrangianWriter_H #define foamVtkLagrangianWriter_H
#include "OFstream.H"
#include "Cloud.H" #include "Cloud.H"
#include "volFields.H" #include "volFields.H"
#include "pointFields.H" #include "pointFields.H"
#include "foamVtkOutputOptions.H" #include "foamVtkOutputOptions.H"
#include <fstream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -115,7 +115,7 @@ public:
//- Destructor //- Destructor
~lagrangianWriter(); ~lagrangianWriter() = default;
// Member Functions // Member Functions
@ -135,15 +135,17 @@ public:
return nParcels_; return nParcels_;
} }
//- Begin parcel data (point data).
// The nFields parameter is only needed for legacy format.
void beginParcelData(label nFields); void beginParcelData(label nFields);
void endParcelData(); void endParcelData();
//- Write file footer //- Write file footer
void writeFooter(); void writeFooter();
//- Write IOField //- Write IOFields
template<class Type> template<class Type>
void writeIOField(const wordList& objectNames); void writeIOField(const wordList& fieldNames);
}; };

View File

@ -3,7 +3,7 @@
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | \\ / O peration |
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation \\ / 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 License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,30 +29,48 @@ License
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> template<class Type>
void Foam::vtk::lagrangianWriter::writeIOField void Foam::vtk::lagrangianWriter::writeIOField(const wordList& fieldNames)
(
const wordList& objectNames
)
{ {
const int nCmpt(pTraits<Type>::nComponents); const int nCmpt(pTraits<Type>::nComponents);
const bool useIntField = const bool useIntField =
std::is_integral<typename pTraits<Type>::cmptType>(); 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, fldName,
mesh_.time().timeName(), mesh_.time().timeName(),
cloud::prefix/cloudName_, cloudDir,
mesh_, mesh_,
IOobject::MUST_READ, IOobject::READ_IF_PRESENT
IOobject::NO_WRITE,
false // no register
); );
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) if (useIntField)
{ {

View File

@ -0,0 +1,92 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
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/>.
InNamspace
Foam
Description
Various functions to operate on HashTables.
SourceFiles
HashTableOps.H
\*---------------------------------------------------------------------------*/
#ifndef HashTableOps_H
#define HashTableOps_H
#include "HashSet.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
//- Combine HashSet operation. Equivalent to 'a += b'
template<class Key=word, class Hash=string::hash>
struct HashSetPlusEqOp
{
typedef HashSet<Key, Hash> value_type;
void operator()(value_type& a, const value_type& b) const
{
a += b;
}
};
//- Combine HashTable operation. Equivalent to 'a += b'
template<class T, class Key=word, class Hash=string::hash>
struct HashTablePlusEqOp
{
typedef HashTable<T, Key, Hash> value_type;
void operator()(value_type& a, const value_type& b) const
{
if (b.size())
{
if (a.size())
{
forAllConstIters(b, citer)
{
a.insert(citer.key(), citer.object());
}
}
else
{
a = b;
}
}
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -81,7 +81,12 @@ tmp<volScalarField::Internal> kOmegaSSTLM<BasicTurbulenceModel>::Fthetat
const volScalarField::Internal& omega = this->omega_(); const volScalarField::Internal& omega = this->omega_();
const volScalarField::Internal& y = this->y_(); const volScalarField::Internal& y = this->y_();
const volScalarField::Internal delta(375*Omega*nu*ReThetat_()*y/sqr(Us)); dimensionedScalar deltaMin("deltaMin", dimLength, SMALL);
volScalarField::Internal delta
(
max(375*Omega*nu*ReThetat_()*y/sqr(Us), deltaMin)
);
const volScalarField::Internal ReOmega(sqr(y)*omega/nu); const volScalarField::Internal ReOmega(sqr(y)*omega/nu);
const volScalarField::Internal Fwake(exp(-sqr(ReOmega/1e5))); const volScalarField::Internal Fwake(exp(-sqr(ReOmega/1e5)));
@ -617,11 +622,11 @@ void kOmegaSSTLM<BasicTurbulenceModel>::correct()
return; return;
} }
// Correct ReThetat and gammaInt
correctReThetatGammaInt();
// Correct k and omega // Correct k and omega
kOmegaSST<BasicTurbulenceModel>::correct(); kOmegaSST<BasicTurbulenceModel>::correct();
// Correct ReThetat and gammaInt
correctReThetatGammaInt();
} }

View File

@ -236,6 +236,7 @@ bool Foam::noiseModel::read(const dictionary& dict)
readWriteOption(optDict, "writePrmsf", writePrmsf_); readWriteOption(optDict, "writePrmsf", writePrmsf_);
readWriteOption(optDict, "writeSPL", writeSPL_); readWriteOption(optDict, "writeSPL", writeSPL_);
readWriteOption(optDict, "writePSD", writePSD_); readWriteOption(optDict, "writePSD", writePSD_);
readWriteOption(optDict, "writePSDf", writePSDf_);
readWriteOption(optDict, "writeOctaves", writeOctaves_); readWriteOption(optDict, "writeOctaves", writeOctaves_);