ENH: include cloudFunction results in vtkCloud writing (#3094)

- process the contents of the cloud object registry, which enables
  output support for calculated values such as Reynolds, Weber numbers
  etc.

ENH: select any/all clouds by default instead of defaultCloud

- adds robustness
This commit is contained in:
Mark Olesen
2024-02-01 15:43:42 +01:00
parent 3a43aae7c0
commit 6dadd3d33e
6 changed files with 102 additions and 51 deletions

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2022 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -52,12 +52,16 @@ bool Foam::functionObjects::dataCloud::writeCloud
const word& cloudName
)
{
const auto* objPtr = mesh_.findObject<cloud>(cloudName);
if (!objPtr)
applyFilter_ = false;
const auto* cloudPtr = mesh_.findObject<cloud>(cloudName);
if (!cloudPtr)
{
return false;
}
const auto& currCloud = *cloudPtr;
objectRegistry obrTmp
(
IOobject
@ -71,7 +75,7 @@ bool Foam::functionObjects::dataCloud::writeCloud
)
);
objPtr->writeObjects(obrTmp);
currCloud.writeObjects(obrTmp);
const auto* pointsPtr = cloud::findIOPosition(obrTmp);
@ -86,7 +90,10 @@ bool Foam::functionObjects::dataCloud::writeCloud
// Number of parcels (locally)
label nParcels = (applyFilter_ ? parcelAddr_.count() : pointsPtr->size());
const label nParcels
(
applyFilter_ ? parcelAddr_.count() : pointsPtr->size()
);
// Total number of parcels on all processes
const label nTotParcels = returnReduce(nParcels, sumOp<label>());
@ -104,9 +111,9 @@ bool Foam::functionObjects::dataCloud::writeCloud
return false;
}
if (Pstream::master())
if (UPstream::master())
{
mkDir(outputName.path());
Foam::mkDir(outputName.path());
}
return
@ -163,12 +170,15 @@ bool Foam::functionObjects::dataCloud::read(const dictionary& dict)
selectClouds_.clear();
dict.readIfPresent("clouds", selectClouds_);
selectClouds_.uniq();
if (selectClouds_.empty())
{
selectClouds_.resize(1);
selectClouds_.first() =
dict.getOrDefault<word>("cloud", cloud::defaultName);
word cloudName;
if (dict.readIfPresent("cloud", cloudName))
{
selectClouds_.push_back(std::move(cloudName));
}
}
dict.readEntry("field", fieldName_);
@ -209,7 +219,12 @@ bool Foam::functionObjects::dataCloud::execute()
bool Foam::functionObjects::dataCloud::write()
{
const wordList cloudNames(mesh_.sortedNames<cloud>(selectClouds_));
const wordList cloudNames
(
selectClouds_.empty()
? mesh_.sortedNames<cloud>()
: mesh_.sortedNames<cloud>(selectClouds_)
);
if (cloudNames.empty())
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -48,10 +48,10 @@ Description
\heading Basic Usage
\table
Property | Description | Required | Default
type | Type name: dataCloud | yes |
type | Type name: dataCloud | yes |
clouds | List of clouds (name or regex) | no |
cloud | Cloud name | no | defaultCloud
field | Name of the field | yes |
cloud | Cloud name | no |
field | Name of the field | yes |
selection | Parcel selection control | no | empty-dict
\endtable
@ -103,7 +103,7 @@ class dataCloud
public fvMeshFunctionObject,
public Foam::Detail::parcelSelection
{
// Private data
// Private Data
//- The printf format for zero-padding names
string printf_;
@ -177,7 +177,7 @@ class dataCloud
bool writeField
(
const fileName& outputName,
const objectRegistry& obrTmp
const objectRegistry& obr
) const;

View File

@ -171,10 +171,10 @@ template<class Type>
bool Foam::functionObjects::dataCloud::writeField
(
const fileName& outputName,
const objectRegistry& obrTmp
const objectRegistry& obr
) const
{
const auto* pointsPtr = cloud::findIOPosition(obrTmp);
const auto* pointsPtr = cloud::findIOPosition(obr);
if (!pointsPtr)
{
@ -185,8 +185,8 @@ bool Foam::functionObjects::dataCloud::writeField
// Fields are not always on all processors (eg, multi-component parcels).
// Thus need to resolve between all processors.
const List<Type>* fldPtr = obrTmp.findObject<IOField<Type>>(fieldName_);
const List<Type>& values = (fldPtr ? *fldPtr : List<Type>());
const List<Type>* fldPtr = obr.findObject<IOField<Type>>(fieldName_);
const List<Type>& values = (fldPtr ? *fldPtr : List<Type>::null());
if (!returnReduceOr(fldPtr != nullptr))
{

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2022 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -101,12 +101,16 @@ bool Foam::functionObjects::vtkCloud::writeCloud
const word& cloudName
)
{
const auto* objPtr = mesh_.findObject<cloud>(cloudName);
if (!objPtr)
applyFilter_ = false;
const auto* cloudPtr = mesh_.cfindObject<cloud>(cloudName);
if (!cloudPtr)
{
return false;
}
const auto& currCloud = *cloudPtr;
objectRegistry obrTmp
(
IOobject
@ -120,7 +124,7 @@ bool Foam::functionObjects::vtkCloud::writeCloud
)
);
objPtr->writeObjects(obrTmp);
currCloud.writeObjects(obrTmp);
const auto* pointsPtr = cloud::findIOPosition(obrTmp);
@ -135,7 +139,10 @@ bool Foam::functionObjects::vtkCloud::writeCloud
// Number of parcels (locally)
label nParcels = (applyFilter_ ? parcelAddr_.count() : pointsPtr->size());
const label nParcels
(
applyFilter_ ? parcelAddr_.count() : pointsPtr->size()
);
// Total number of parcels on all processes
const label nTotParcels = returnReduce(nParcels, sumOp<label>());
@ -163,9 +170,9 @@ bool Foam::functionObjects::vtkCloud::writeCloud
<< exit(FatalError);
}
if (Pstream::master())
if (UPstream::master())
{
mkDir(file.path());
Foam::mkDir(file.path());
os.open(file);
format = writeOpts_.newFormatter(os);
@ -238,7 +245,7 @@ bool Foam::functionObjects::vtkCloud::writeCloud
}
if (Pstream::master())
if (UPstream::master())
{
format().flush();
format().endDataArray();
@ -270,7 +277,7 @@ bool Foam::functionObjects::vtkCloud::writeCloud
// Write fields
if (Pstream::master())
if (UPstream::master())
{
if (useVerts_)
{
@ -282,13 +289,28 @@ bool Foam::functionObjects::vtkCloud::writeCloud
}
}
DynamicList<word> written(obrTmp.size());
DynamicList<word> written(obrTmp.size() + currCloud.objectRegistry::size());
written.append(writeFields<label>(format, obrTmp, nTotParcels));
written.append(writeFields<scalar>(format, obrTmp, nTotParcels));
written.append(writeFields<vector>(format, obrTmp, nTotParcels));
written.push_back
(
writeFields<label>(format, obrTmp, nTotParcels)
);
written.push_back
(
writeFields<scalar>(format, obrTmp, nTotParcels)
);
written.push_back
(
writeFields<vector>(format, obrTmp, nTotParcels)
);
if (Pstream::master())
// Any cloudFunctions results
written.push_back
(
writeFields<scalar>(format, currCloud, nTotParcels)
);
if (UPstream::master())
{
if (useVerts_)
{
@ -415,12 +437,15 @@ bool Foam::functionObjects::vtkCloud::read(const dictionary& dict)
selectClouds_.clear();
dict.readIfPresent("clouds", selectClouds_);
selectClouds_.uniq();
if (selectClouds_.empty())
{
selectClouds_.resize(1);
selectClouds_.first() =
dict.getOrDefault<word>("cloud", cloud::defaultName);
word cloudName;
if (dict.readIfPresent("cloud", cloudName))
{
selectClouds_.push_back(std::move(cloudName));
}
}
selectFields_.clear();
@ -463,7 +488,12 @@ bool Foam::functionObjects::vtkCloud::execute()
bool Foam::functionObjects::vtkCloud::write()
{
const wordList cloudNames(mesh_.sortedNames<cloud>(selectClouds_));
const wordList cloudNames
(
selectClouds_.empty()
? mesh_.sortedNames<cloud>()
: mesh_.sortedNames<cloud>(selectClouds_)
);
if (cloudNames.empty())
{
@ -498,7 +528,7 @@ bool Foam::functionObjects::vtkCloud::write()
Log << " cloud : "
<< time_.relativePath(outputName) << endl;
if (Pstream::master())
if (UPstream::master())
{
// Add to file-series and emit as JSON
fileName seriesName(vtk::seriesWriter::base(outputName));

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -81,7 +81,7 @@ Description
Property | Description | Required | Default
type | Type name: vtkCloud | yes |
clouds | List of clouds (name or regex) | no |
cloud | Cloud name | no | defaultCloud
cloud | Cloud name | no |
fields | List of fields (name or regex) | no |
selection | Parcel selection control | no | empty-dict
\endtable
@ -160,7 +160,7 @@ class vtkCloud
public fvMeshFunctionObject,
public Foam::Detail::parcelSelection
{
// Private data
// Private Data
//- Writer options
vtk::outputOptions writeOpts_;
@ -209,7 +209,7 @@ class vtkCloud
wordList writeFields
(
autoPtr<vtk::formatter>& format,
const objectRegistry& obrTmp,
const objectRegistry& obr,
const label nTotParcels
) const;

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2022 OpenCFD Ltd.
Copyright (C) 2018-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,7 +33,7 @@ template<class Type>
Foam::wordList Foam::functionObjects::vtkCloud::writeFields
(
autoPtr<vtk::formatter>& format,
const objectRegistry& obrTmp,
const objectRegistry& obr,
const label nTotParcels
) const
{
@ -55,16 +55,22 @@ Foam::wordList Foam::functionObjects::vtkCloud::writeFields
// Fields are not always on all processors (eg, multi-component parcels).
// Thus need to resolve names between all processors.
wordList fieldNames(obrTmp.names<IOField<Type>>());
wordList fieldNames =
(
selectFields_.size()
? obr.names<IOField<Type>>(selectFields_)
: obr.names<IOField<Type>>()
);
Pstream::combineReduce(fieldNames, ListOps::uniqueEqOp<word>());
Foam::sort(fieldNames); // Consistent order
for (const word& fieldName : fieldNames)
{
const List<Type>* fldPtr = obrTmp.findObject<IOField<Type>>(fieldName);
const List<Type>& values = (fldPtr ? *fldPtr : List<Type>());
const List<Type>* fldPtr = obr.findObject<IOField<Type>>(fieldName);
const List<Type>& values = (fldPtr ? *fldPtr : List<Type>::null());
if (Pstream::master())
if (UPstream::master())
{
if (std::is_same<label, typename pTraits<Type>::cmptType>::value)
{
@ -93,7 +99,7 @@ Foam::wordList Foam::functionObjects::vtkCloud::writeFields
vtk::writeListParallel(format.ref(), values);
}
if (Pstream::master())
if (UPstream::master())
{
// Non-legacy
format().flush();