mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add probes sampleOnExecute option (#2358)
- supports sampling/probing of values to obtain min/max/average/size at execution intervals without writing any output or generating output directories. - 'verbose' option for additional output
This commit is contained in:
@ -1,6 +1,5 @@
|
|||||||
probes/probes.C
|
probes/probes.C
|
||||||
probes/patchProbes.C
|
probes/patchProbes.C
|
||||||
probes/probesGrouping.C
|
|
||||||
|
|
||||||
sampledSet/circle/circleSet.C
|
sampledSet/circle/circleSet.C
|
||||||
sampledSet/cloud/cloudSet.C
|
sampledSet/cloud/cloudSet.C
|
||||||
|
|||||||
@ -201,13 +201,16 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
|
|||||||
// - faceList_ : faces (now patch faces)
|
// - faceList_ : faces (now patch faces)
|
||||||
// - patchIDList_ : patch corresponding to faceList
|
// - patchIDList_ : patch corresponding to faceList
|
||||||
// - processor_ : processor
|
// - processor_ : processor
|
||||||
elementList_.setSize(nearest.size());
|
elementList_.resize_nocopy(nearest.size());
|
||||||
elementList_ = -1;
|
elementList_ = -1;
|
||||||
faceList_.setSize(nearest.size());
|
|
||||||
|
faceList_.resize_nocopy(nearest.size());
|
||||||
faceList_ = -1;
|
faceList_ = -1;
|
||||||
processor_.setSize(nearest.size());
|
|
||||||
|
processor_.resize_nocopy(nearest.size());
|
||||||
processor_ = -1;
|
processor_ = -1;
|
||||||
patchIDList_.setSize(nearest.size());
|
|
||||||
|
patchIDList_.resize_nocopy(nearest.size());
|
||||||
patchIDList_ = -1;
|
patchIDList_ = -1;
|
||||||
|
|
||||||
forAll(nearest, sampleI)
|
forAll(nearest, sampleI)
|
||||||
@ -236,13 +239,13 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
|
|||||||
Foam::patchProbes::patchProbes
|
Foam::patchProbes::patchProbes
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const Time& t,
|
const Time& runTime,
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
const bool loadFromFiles,
|
const bool loadFromFiles,
|
||||||
const bool readFields
|
const bool readFields
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
probes(name, t, dict, loadFromFiles, false)
|
probes(name, runTime, dict, loadFromFiles, false)
|
||||||
{
|
{
|
||||||
if (readFields)
|
if (readFields)
|
||||||
{
|
{
|
||||||
@ -253,27 +256,43 @@ Foam::patchProbes::patchProbes
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
bool Foam::patchProbes::write()
|
bool Foam::patchProbes::performAction(unsigned request)
|
||||||
{
|
{
|
||||||
if (this->size() && prepare())
|
if (!pointField::empty() && request && prepare(request))
|
||||||
{
|
{
|
||||||
sampleAndWrite(scalarFields_);
|
performAction(scalarFields_, request);
|
||||||
sampleAndWrite(vectorFields_);
|
performAction(vectorFields_, request);
|
||||||
sampleAndWrite(sphericalTensorFields_);
|
performAction(sphericalTensorFields_, request);
|
||||||
sampleAndWrite(symmTensorFields_);
|
performAction(symmTensorFields_, request);
|
||||||
sampleAndWrite(tensorFields_);
|
performAction(tensorFields_, request);
|
||||||
|
|
||||||
sampleAndWriteSurfaceFields(surfaceScalarFields_);
|
performAction(surfaceScalarFields_, request);
|
||||||
sampleAndWriteSurfaceFields(surfaceVectorFields_);
|
performAction(surfaceVectorFields_, request);
|
||||||
sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
|
performAction(surfaceSphericalTensorFields_, request);
|
||||||
sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
|
performAction(surfaceSymmTensorFields_, request);
|
||||||
sampleAndWriteSurfaceFields(surfaceTensorFields_);
|
performAction(surfaceTensorFields_, request);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchProbes::execute()
|
||||||
|
{
|
||||||
|
if (onExecute_)
|
||||||
|
{
|
||||||
|
return performAction(ACTION_ALL & ~ACTION_WRITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::patchProbes::write()
|
||||||
|
{
|
||||||
|
return performAction(ACTION_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::patchProbes::read(const dictionary& dict)
|
bool Foam::patchProbes::read(const dictionary& dict)
|
||||||
{
|
{
|
||||||
if (!dict.readIfPresent("patches", patchNames_))
|
if (!dict.readIfPresent("patches", patchNames_))
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2020 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -64,14 +64,14 @@ Description
|
|||||||
}
|
}
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
patchProbes.C
|
patchProbes.C
|
||||||
|
patchProbesTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef patchProbes_H
|
#ifndef Foam_patchProbes_H
|
||||||
#define patchProbes_H
|
#define Foam_patchProbes_H
|
||||||
|
|
||||||
#include "probes.H"
|
#include "probes.H"
|
||||||
|
|
||||||
@ -80,12 +80,6 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declaration of classes
|
|
||||||
class objectRegistry;
|
|
||||||
class dictionary;
|
|
||||||
class fvMesh;
|
|
||||||
class mapPolyMesh;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class patchProbes Declaration
|
Class patchProbes Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -96,7 +90,7 @@ class patchProbes
|
|||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected data
|
// Protected Data
|
||||||
|
|
||||||
//- Patches to sample
|
//- Patches to sample
|
||||||
wordRes patchNames_;
|
wordRes patchNames_;
|
||||||
@ -104,52 +98,35 @@ protected:
|
|||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Sample and write a particular volume field
|
|
||||||
template<class Type>
|
|
||||||
void sampleAndWrite
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Sample and write a particular surface field
|
|
||||||
template<class Type>
|
|
||||||
void sampleAndWrite
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&
|
|
||||||
);
|
|
||||||
|
|
||||||
//- Sample and write all the fields of the given type
|
|
||||||
template<class Type>
|
|
||||||
void sampleAndWrite(const fieldGroup<Type>&);
|
|
||||||
|
|
||||||
//- Sample and write all the surface fields of the given type
|
|
||||||
template<class Type>
|
|
||||||
void sampleAndWriteSurfaceFields(const fieldGroup<Type>&);
|
|
||||||
|
|
||||||
//- Sample a volume field at all locations
|
|
||||||
template<class Type>
|
|
||||||
tmp<Field<Type>> sample
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sample a surface field at all locations
|
|
||||||
template<class Type>
|
|
||||||
tmp<Field<Type>> sample
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sample a single field on all sample locations
|
|
||||||
template<class Type>
|
|
||||||
tmp<Field<Type>> sample(const word& fieldName) const;
|
|
||||||
|
|
||||||
//- Find elements containing patchProbes
|
//- Find elements containing patchProbes
|
||||||
virtual void findElements(const fvMesh&);
|
virtual void findElements(const fvMesh& mesh); // override
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Write field values
|
||||||
|
template<class Type>
|
||||||
|
void writeValues
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalar timeValue
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Sample and store/write applicable volume/surface fields
|
||||||
|
template<class GeoField>
|
||||||
|
void performAction
|
||||||
|
(
|
||||||
|
const fieldGroup<GeoField>& fieldNames, /* must be sorted */
|
||||||
|
unsigned request
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Perform sampling action with store/write
|
||||||
|
bool performAction(unsigned request);
|
||||||
|
|
||||||
|
|
||||||
//- No copy construct
|
//- No copy construct
|
||||||
patchProbes(const patchProbes&) = delete;
|
patchProbes(const patchProbes&) = delete;
|
||||||
|
|
||||||
@ -169,7 +146,7 @@ public:
|
|||||||
patchProbes
|
patchProbes
|
||||||
(
|
(
|
||||||
const word& name,
|
const word& name,
|
||||||
const Time& time,
|
const Time& runTime,
|
||||||
const dictionary& dict,
|
const dictionary& dict,
|
||||||
const bool loadFromFiles = false,
|
const bool loadFromFiles = false,
|
||||||
const bool readFields = true
|
const bool readFields = true
|
||||||
@ -179,13 +156,35 @@ public:
|
|||||||
virtual ~patchProbes() = default;
|
virtual ~patchProbes() = default;
|
||||||
|
|
||||||
|
|
||||||
//- Public members
|
// Member Functions
|
||||||
|
|
||||||
|
//- Sample and store result if the sampleOnExecute is enabled.
|
||||||
|
virtual bool execute();
|
||||||
|
|
||||||
//- Sample and write
|
//- Sample and write
|
||||||
virtual bool write();
|
virtual bool write();
|
||||||
|
|
||||||
//- Read
|
//- Read
|
||||||
virtual bool read(const dictionary&);
|
virtual bool read(const dictionary&);
|
||||||
|
|
||||||
|
|
||||||
|
// Sampling
|
||||||
|
|
||||||
|
//- Sample a volume field at all locations
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sample(const VolumeField<Type>&) const;
|
||||||
|
|
||||||
|
//- Sample a surface field at all locations
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sample(const SurfaceField<Type>&) const;
|
||||||
|
|
||||||
|
//- Sample a single field on all sample locations
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sample(const word& fieldName) const;
|
||||||
|
|
||||||
|
//- Sample a surface field at all locations
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sampleSurfaceField(const word& fieldName) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2021 OpenCFD Ltd.
|
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -28,153 +28,57 @@ License
|
|||||||
|
|
||||||
#include "patchProbes.H"
|
#include "patchProbes.H"
|
||||||
#include "volFields.H"
|
#include "volFields.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::patchProbes::sampleAndWrite
|
void Foam::patchProbes::writeValues
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vField
|
const word& fieldName,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalar timeValue
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Field<Type> values(sample(vField));
|
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
unsigned int w = IOstream::defaultPrecision() + 7;
|
const unsigned int w = IOstream::defaultPrecision() + 7;
|
||||||
OFstream& probeStream = *probeFilePtrs_[vField.name()];
|
OFstream& os = *probeFilePtrs_[fieldName];
|
||||||
|
|
||||||
probeStream
|
os << setw(w) << timeValue;
|
||||||
<< setw(w)
|
|
||||||
<< vField.time().timeOutputValue();
|
|
||||||
|
|
||||||
for (const auto& v : values)
|
for (const auto& v : values)
|
||||||
{
|
{
|
||||||
probeStream << ' ' << setw(w) << v;
|
os << ' ' << setw(w) << v;
|
||||||
}
|
}
|
||||||
probeStream << endl;
|
os << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const word& fieldName = vField.name();
|
|
||||||
this->setResult("average(" + fieldName + ")", average(values));
|
|
||||||
this->setResult("min(" + fieldName + ")", min(values));
|
|
||||||
this->setResult("max(" + fieldName + ")", max(values));
|
|
||||||
this->setResult("size(" + fieldName + ")", values.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class GeoField>
|
||||||
void Foam::patchProbes::sampleAndWrite
|
void Foam::patchProbes::performAction
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
|
const fieldGroup<GeoField>& fieldNames,
|
||||||
|
unsigned request
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Field<Type> values(sample(sField));
|
for (const word& fieldName : fieldNames)
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
{
|
||||||
unsigned int w = IOstream::defaultPrecision() + 7;
|
tmp<GeoField> tfield = getOrLoadField<GeoField>(fieldName);
|
||||||
OFstream& probeStream = *probeFilePtrs_[sField.name()];
|
|
||||||
|
|
||||||
probeStream
|
if (tfield)
|
||||||
<< setw(w)
|
|
||||||
<< sField.time().timeOutputValue();
|
|
||||||
|
|
||||||
for (const auto& v : values)
|
|
||||||
{
|
{
|
||||||
probeStream << ' ' << setw(w) << v;
|
const auto& field = tfield();
|
||||||
}
|
const scalar timeValue = field.time().timeOutputValue();
|
||||||
probeStream << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const word& fieldName = sField.name();
|
Field<typename GeoField::value_type> values(sample(field));
|
||||||
this->setResult("average(" + fieldName + ")", average(values));
|
|
||||||
this->setResult("min(" + fieldName + ")", min(values));
|
|
||||||
this->setResult("max(" + fieldName + ")", max(values));
|
|
||||||
this->setResult("size(" + fieldName + ")", values.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this->storeResults(fieldName, values);
|
||||||
template<class Type>
|
if (request & ACTION_WRITE)
|
||||||
void Foam::patchProbes::sampleAndWrite
|
|
||||||
(
|
|
||||||
const fieldGroup<Type>& fields
|
|
||||||
)
|
|
||||||
{
|
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
|
||||||
|
|
||||||
for (const auto& fieldName : fields)
|
|
||||||
{
|
|
||||||
if (loadFromFiles_)
|
|
||||||
{
|
|
||||||
sampleAndWrite
|
|
||||||
(
|
|
||||||
VolFieldType
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
mesh_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
objectRegistry::const_iterator iter = mesh_.find(fieldName);
|
|
||||||
|
|
||||||
if (iter.found() && iter()->type() == VolFieldType::typeName)
|
|
||||||
{
|
{
|
||||||
sampleAndWrite(mesh_.lookupObject<VolFieldType>(fieldName));
|
this->writeValues(fieldName, values, timeValue);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::patchProbes::sampleAndWriteSurfaceFields
|
|
||||||
(
|
|
||||||
const fieldGroup<Type>& fields
|
|
||||||
)
|
|
||||||
{
|
|
||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
|
||||||
|
|
||||||
for (const auto& fieldName : fields)
|
|
||||||
{
|
|
||||||
if (loadFromFiles_)
|
|
||||||
{
|
|
||||||
sampleAndWrite
|
|
||||||
(
|
|
||||||
SurfaceFieldType
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
mesh_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
objectRegistry::const_iterator iter = mesh_.find(fieldName);
|
|
||||||
|
|
||||||
if (iter.found() && iter()->type() == SurfaceFieldType::typeName)
|
|
||||||
{
|
|
||||||
sampleAndWrite(mesh_.lookupObject<SurfaceFieldType>(fieldName));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,17 +89,15 @@ void Foam::patchProbes::sampleAndWriteSurfaceFields
|
|||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::patchProbes::sample
|
Foam::patchProbes::sample(const VolumeField<Type>& vField) const
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vField
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||||
|
|
||||||
auto tValues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||||
auto& values = tValues.ref();
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
const auto& bField = vField.boundaryField();
|
||||||
|
|
||||||
forAll(*this, probei)
|
forAll(*this, probei)
|
||||||
{
|
{
|
||||||
@ -205,14 +107,45 @@ Foam::patchProbes::sample
|
|||||||
{
|
{
|
||||||
label patchi = patches.whichPatch(facei);
|
label patchi = patches.whichPatch(facei);
|
||||||
label localFacei = patches[patchi].whichFace(facei);
|
label localFacei = patches[patchi].whichFace(facei);
|
||||||
values[probei] = vField.boundaryField()[patchi][localFacei];
|
values[probei] = bField[patchi][localFacei];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
||||||
Pstream::listCombineScatter(values);
|
Pstream::listCombineScatter(values);
|
||||||
|
|
||||||
return tValues;
|
return tvalues;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>>
|
||||||
|
Foam::patchProbes::sample(const SurfaceField<Type>& sField) const
|
||||||
|
{
|
||||||
|
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||||
|
|
||||||
|
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||||
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
|
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
||||||
|
const auto& bField = sField.boundaryField();
|
||||||
|
|
||||||
|
forAll(*this, probei)
|
||||||
|
{
|
||||||
|
label facei = faceList_[probei];
|
||||||
|
|
||||||
|
if (facei >= 0)
|
||||||
|
{
|
||||||
|
label patchi = patches.whichPatch(facei);
|
||||||
|
label localFacei = patches[patchi].whichFace(facei);
|
||||||
|
values[probei] = bField[patchi][localFacei];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
||||||
|
Pstream::listCombineScatter(values);
|
||||||
|
|
||||||
|
return tvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -220,46 +153,15 @@ template<class Type>
|
|||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::patchProbes::sample(const word& fieldName) const
|
Foam::patchProbes::sample(const word& fieldName) const
|
||||||
{
|
{
|
||||||
return sample
|
return sample(mesh_.lookupObject<VolumeField<Type>>(fieldName));
|
||||||
(
|
|
||||||
mesh_.lookupObject<GeometricField<Type, fvPatchField, volMesh>>
|
|
||||||
(
|
|
||||||
fieldName
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::patchProbes::sample
|
Foam::patchProbes::sampleSurfaceField(const word& fieldName) const
|
||||||
(
|
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
return sample(mesh_.lookupObject<SurfaceField<Type>>(fieldName));
|
||||||
|
|
||||||
auto tValues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
|
||||||
auto& values = tValues.ref();
|
|
||||||
|
|
||||||
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
|
|
||||||
|
|
||||||
forAll(*this, probei)
|
|
||||||
{
|
|
||||||
label facei = faceList_[probei];
|
|
||||||
|
|
||||||
if (facei >= 0)
|
|
||||||
{
|
|
||||||
label patchi = patches.whichPatch(facei);
|
|
||||||
label localFacei = patches[patchi].whichFace(facei);
|
|
||||||
values[probei] = sField.boundaryField()[patchi][localFacei];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
|
||||||
Pstream::listCombineScatter(values);
|
|
||||||
|
|
||||||
return tValues;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -27,8 +27,9 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "probes.H"
|
#include "probes.H"
|
||||||
#include "volFields.H"
|
|
||||||
#include "dictionary.H"
|
#include "dictionary.H"
|
||||||
|
#include "volFields.H"
|
||||||
|
#include "surfaceFields.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "IOmanip.H"
|
#include "IOmanip.H"
|
||||||
#include "mapPolyMesh.H"
|
#include "mapPolyMesh.H"
|
||||||
@ -55,18 +56,14 @@ void Foam::probes::findElements(const fvMesh& mesh)
|
|||||||
{
|
{
|
||||||
DebugInfo<< "probes: resetting sample locations" << endl;
|
DebugInfo<< "probes: resetting sample locations" << endl;
|
||||||
|
|
||||||
elementList_.clear();
|
elementList_.resize_nocopy(pointField::size());
|
||||||
elementList_.setSize(size());
|
faceList_.resize_nocopy(pointField::size());
|
||||||
|
processor_.resize_nocopy(pointField::size());
|
||||||
faceList_.clear();
|
|
||||||
faceList_.setSize(size());
|
|
||||||
|
|
||||||
processor_.setSize(size());
|
|
||||||
processor_ = -1;
|
processor_ = -1;
|
||||||
|
|
||||||
forAll(*this, probei)
|
forAll(*this, probei)
|
||||||
{
|
{
|
||||||
const vector& location = operator[](probei);
|
const point& location = (*this)[probei];
|
||||||
|
|
||||||
const label celli = mesh.findCell(location);
|
const label celli = mesh.findCell(location);
|
||||||
|
|
||||||
@ -107,7 +104,7 @@ void Foam::probes::findElements(const fvMesh& mesh)
|
|||||||
// Check if all probes have been found.
|
// Check if all probes have been found.
|
||||||
forAll(elementList_, probei)
|
forAll(elementList_, probei)
|
||||||
{
|
{
|
||||||
const vector& location = operator[](probei);
|
const point& location = operator[](probei);
|
||||||
label celli = elementList_[probei];
|
label celli = elementList_[probei];
|
||||||
label facei = faceList_[probei];
|
label facei = faceList_[probei];
|
||||||
|
|
||||||
@ -171,15 +168,53 @@ void Foam::probes::findElements(const fvMesh& mesh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::probes::prepare()
|
Foam::label Foam::probes::prepare(unsigned request)
|
||||||
{
|
{
|
||||||
const label nFields = classifyFields();
|
// Prefilter on selection
|
||||||
|
HashTable<wordHashSet> selected =
|
||||||
|
(
|
||||||
|
loadFromFiles_
|
||||||
|
? IOobjectList(mesh_, mesh_.time().timeName()).classes(fieldSelection_)
|
||||||
|
: mesh_.classes(fieldSelection_)
|
||||||
|
);
|
||||||
|
|
||||||
// adjust file streams
|
// Classify and count fields
|
||||||
|
label nFields = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#undef doLocalCode
|
||||||
|
#define doLocalCode(InputType, Target) \
|
||||||
|
{ \
|
||||||
|
Target.clear(); /* Remove old values */ \
|
||||||
|
const auto iter = selected.cfind(InputType::typeName); \
|
||||||
|
if (iter.found()) \
|
||||||
|
{ \
|
||||||
|
/* Add new (current) values */ \
|
||||||
|
Target.append(iter.val().sortedToc()); \
|
||||||
|
nFields += Target.size(); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
doLocalCode(volScalarField, scalarFields_);
|
||||||
|
doLocalCode(volVectorField, vectorFields_)
|
||||||
|
doLocalCode(volSphericalTensorField, sphericalTensorFields_);
|
||||||
|
doLocalCode(volSymmTensorField, symmTensorFields_);
|
||||||
|
doLocalCode(volTensorField, tensorFields_);
|
||||||
|
|
||||||
|
doLocalCode(surfaceScalarField, surfaceScalarFields_);
|
||||||
|
doLocalCode(surfaceVectorField, surfaceVectorFields_);
|
||||||
|
doLocalCode(surfaceSphericalTensorField, surfaceSphericalTensorFields_);
|
||||||
|
doLocalCode(surfaceSymmTensorField, surfaceSymmTensorFields_);
|
||||||
|
doLocalCode(surfaceTensorField, surfaceTensorFields_);
|
||||||
|
#undef doLocalCode
|
||||||
|
}
|
||||||
|
while (false);
|
||||||
|
|
||||||
|
|
||||||
|
// Adjust file streams
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
wordHashSet currentFields;
|
wordHashSet currentFields(2*nFields);
|
||||||
|
|
||||||
currentFields.insert(scalarFields_);
|
currentFields.insert(scalarFields_);
|
||||||
currentFields.insert(vectorFields_);
|
currentFields.insert(vectorFields_);
|
||||||
currentFields.insert(sphericalTensorFields_);
|
currentFields.insert(sphericalTensorFields_);
|
||||||
@ -197,27 +232,7 @@ Foam::label Foam::probes::prepare()
|
|||||||
<< "Probing locations: " << *this << nl
|
<< "Probing locations: " << *this << nl
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
|
// Close streams for fields that no longer exist
|
||||||
fileName probeSubDir = name();
|
|
||||||
|
|
||||||
if (mesh_.name() != polyMesh::defaultRegion)
|
|
||||||
{
|
|
||||||
probeSubDir = probeSubDir/mesh_.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put in undecomposed case
|
|
||||||
// (Note: gives problems for distributed data running)
|
|
||||||
|
|
||||||
fileName probeDir
|
|
||||||
(
|
|
||||||
mesh_.time().globalPath()
|
|
||||||
/ functionObject::outputPrefix
|
|
||||||
/ probeSubDir
|
|
||||||
/ mesh_.time().timeName()
|
|
||||||
);
|
|
||||||
probeDir.clean(); // Remove unneeded ".."
|
|
||||||
|
|
||||||
// ignore known fields, close streams for fields that no longer exist
|
|
||||||
forAllIters(probeFilePtrs_, iter)
|
forAllIters(probeFilePtrs_, iter)
|
||||||
{
|
{
|
||||||
if (!currentFields.erase(iter.key()))
|
if (!currentFields.erase(iter.key()))
|
||||||
@ -228,28 +243,59 @@ Foam::label Foam::probes::prepare()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// currentFields now just has the new fields - open streams for them
|
if (!(request & ACTION_WRITE))
|
||||||
for (const word& fieldName : currentFields)
|
|
||||||
{
|
{
|
||||||
// Create directory if does not exist.
|
// No writing - can return now
|
||||||
mkDir(probeDir);
|
return nFields;
|
||||||
|
}
|
||||||
|
else if (currentFields.empty())
|
||||||
|
{
|
||||||
|
// No new fields - can return now
|
||||||
|
return nFields;
|
||||||
|
}
|
||||||
|
|
||||||
auto fPtr = autoPtr<OFstream>::New(probeDir/fieldName);
|
|
||||||
auto& fout = *fPtr;
|
|
||||||
|
|
||||||
DebugInfo<< "open probe stream: " << fout.name() << endl;
|
// Have new fields - open streams for them
|
||||||
|
|
||||||
probeFilePtrs_.insert(fieldName, fPtr);
|
// Put in undecomposed case
|
||||||
|
// (Note: gives problems for distributed data running)
|
||||||
|
|
||||||
unsigned int w = IOstream::defaultPrecision() + 7;
|
fileName probeSubDir = name();
|
||||||
|
if (mesh_.name() != polyMesh::defaultRegion)
|
||||||
|
{
|
||||||
|
probeSubDir = probeSubDir/mesh_.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName probeDir
|
||||||
|
(
|
||||||
|
mesh_.time().globalPath()
|
||||||
|
/ functionObject::outputPrefix
|
||||||
|
/ probeSubDir
|
||||||
|
/ mesh_.time().timeName()
|
||||||
|
);
|
||||||
|
probeDir.clean(); // Remove unneeded ".."
|
||||||
|
|
||||||
|
// Create directory if needed
|
||||||
|
mkDir(probeDir);
|
||||||
|
|
||||||
|
for (const word& fieldName : currentFields.sortedToc())
|
||||||
|
{
|
||||||
|
auto osPtr = autoPtr<OFstream>::New(probeDir/fieldName);
|
||||||
|
auto& os = *osPtr;
|
||||||
|
|
||||||
|
probeFilePtrs_.insert(fieldName, osPtr);
|
||||||
|
|
||||||
|
DebugInfo<< "open probe stream: " << os.name() << endl;
|
||||||
|
|
||||||
|
const unsigned int w = IOstream::defaultPrecision() + 7;
|
||||||
|
|
||||||
forAll(*this, probei)
|
forAll(*this, probei)
|
||||||
{
|
{
|
||||||
fout<< "# Probe " << probei << ' ' << operator[](probei);
|
os << "# Probe " << probei << ' ' << operator[](probei);
|
||||||
|
|
||||||
if (processor_[probei] == -1)
|
if (processor_[probei] == -1)
|
||||||
{
|
{
|
||||||
fout<< " # Not Found";
|
os << " # Not Found";
|
||||||
}
|
}
|
||||||
// Only for patchProbes
|
// Only for patchProbes
|
||||||
else if (probei < patchIDList_.size())
|
else if (probei < patchIDList_.size())
|
||||||
@ -264,31 +310,31 @@ Foam::label Foam::probes::prepare()
|
|||||||
|| processor_[probei] == Pstream::myProcNo()
|
|| processor_[probei] == Pstream::myProcNo()
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
fout<< " at patch " << bm[patchi].name();
|
os << " at patch " << bm[patchi].name();
|
||||||
}
|
}
|
||||||
fout<< " with a distance of "
|
os << " with a distance of "
|
||||||
<< mag(operator[](probei)-oldPoints_[probei])
|
<< mag(operator[](probei)-oldPoints_[probei])
|
||||||
<< " m to the original point "
|
<< " m to the original point "
|
||||||
<< oldPoints_[probei];
|
<< oldPoints_[probei];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fout<< endl;
|
os << nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
fout<< '#' << setw(IOstream::defaultPrecision() + 6)
|
os << '#' << setw(IOstream::defaultPrecision() + 6)
|
||||||
<< "Probe";
|
<< "Probe";
|
||||||
|
|
||||||
forAll(*this, probei)
|
forAll(*this, probei)
|
||||||
{
|
{
|
||||||
if (includeOutOfBounds_ || processor_[probei] != -1)
|
if (includeOutOfBounds_ || processor_[probei] != -1)
|
||||||
{
|
{
|
||||||
fout<< ' ' << setw(w) << probei;
|
os << ' ' << setw(w) << probei;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fout<< endl;
|
os << nl;
|
||||||
|
|
||||||
fout<< '#' << setw(IOstream::defaultPrecision() + 6)
|
os << '#' << setw(IOstream::defaultPrecision() + 6)
|
||||||
<< "Time" << endl;
|
<< "Time" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,23 +354,15 @@ Foam::probes::probes
|
|||||||
const bool readFields
|
const bool readFields
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
stateFunctionObject(name, runTime),
|
functionObjects::fvMeshFunctionObject(name, runTime, dict),
|
||||||
pointField(0),
|
pointField(),
|
||||||
mesh_
|
|
||||||
(
|
|
||||||
refCast<const fvMesh>
|
|
||||||
(
|
|
||||||
runTime.lookupObject<objectRegistry>
|
|
||||||
(
|
|
||||||
dict.getOrDefault("region", polyMesh::defaultRegion)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
loadFromFiles_(loadFromFiles),
|
loadFromFiles_(loadFromFiles),
|
||||||
fieldSelection_(),
|
|
||||||
fixedLocations_(true),
|
fixedLocations_(true),
|
||||||
interpolationScheme_("cell"),
|
includeOutOfBounds_(true),
|
||||||
includeOutOfBounds_(true)
|
verbose_(false),
|
||||||
|
onExecute_(false),
|
||||||
|
fieldSelection_(),
|
||||||
|
samplePointScheme_("cell")
|
||||||
{
|
{
|
||||||
if (readFields)
|
if (readFields)
|
||||||
{
|
{
|
||||||
@ -335,15 +373,28 @@ Foam::probes::probes
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::probes::verbose(const bool on) noexcept
|
||||||
|
{
|
||||||
|
bool old(verbose_);
|
||||||
|
verbose_ = on;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::probes::read(const dictionary& dict)
|
bool Foam::probes::read(const dictionary& dict)
|
||||||
{
|
{
|
||||||
dict.readEntry("probeLocations", static_cast<pointField&>(*this));
|
dict.readEntry("probeLocations", static_cast<pointField&>(*this));
|
||||||
dict.readEntry("fields", fieldSelection_);
|
dict.readEntry("fields", fieldSelection_);
|
||||||
|
|
||||||
dict.readIfPresent("fixedLocations", fixedLocations_);
|
dict.readIfPresent("fixedLocations", fixedLocations_);
|
||||||
if (dict.readIfPresent("interpolationScheme", interpolationScheme_))
|
dict.readIfPresent("includeOutOfBounds", includeOutOfBounds_);
|
||||||
|
|
||||||
|
verbose_ = dict.getOrDefault("verbose", false);
|
||||||
|
onExecute_ = dict.getOrDefault("sampleOnExecute", false);
|
||||||
|
|
||||||
|
if (dict.readIfPresent("interpolationScheme", samplePointScheme_))
|
||||||
{
|
{
|
||||||
if (!fixedLocations_ && interpolationScheme_ != "cell")
|
if (!fixedLocations_ && samplePointScheme_ != "cell")
|
||||||
{
|
{
|
||||||
WarningInFunction
|
WarningInFunction
|
||||||
<< "Only cell interpolation can be applied when "
|
<< "Only cell interpolation can be applied when "
|
||||||
@ -352,41 +403,51 @@ bool Foam::probes::read(const dictionary& dict)
|
|||||||
<< endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dict.readIfPresent("includeOutOfBounds", includeOutOfBounds_);
|
|
||||||
|
|
||||||
// Initialise cells to sample from supplied locations
|
// Initialise cells to sample from supplied locations
|
||||||
findElements(mesh_);
|
findElements(mesh_);
|
||||||
|
|
||||||
prepare();
|
// Close old (ununsed) streams
|
||||||
|
prepare(ACTION_NONE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::probes::performAction(unsigned request)
|
||||||
|
{
|
||||||
|
if (!pointField::empty() && request && prepare(request))
|
||||||
|
{
|
||||||
|
performAction(scalarFields_, request);
|
||||||
|
performAction(vectorFields_, request);
|
||||||
|
performAction(sphericalTensorFields_, request);
|
||||||
|
performAction(symmTensorFields_, request);
|
||||||
|
performAction(tensorFields_, request);
|
||||||
|
|
||||||
|
performAction(surfaceScalarFields_, request);
|
||||||
|
performAction(surfaceVectorFields_, request);
|
||||||
|
performAction(surfaceSphericalTensorFields_, request);
|
||||||
|
performAction(surfaceSymmTensorFields_, request);
|
||||||
|
performAction(surfaceTensorFields_, request);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::probes::execute()
|
bool Foam::probes::execute()
|
||||||
{
|
{
|
||||||
|
if (onExecute_)
|
||||||
|
{
|
||||||
|
return performAction(ACTION_ALL & ~ACTION_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Foam::probes::write()
|
bool Foam::probes::write()
|
||||||
{
|
{
|
||||||
if (size() && prepare())
|
return performAction(ACTION_ALL);
|
||||||
{
|
|
||||||
sampleAndWrite(scalarFields_);
|
|
||||||
sampleAndWrite(vectorFields_);
|
|
||||||
sampleAndWrite(sphericalTensorFields_);
|
|
||||||
sampleAndWrite(symmTensorFields_);
|
|
||||||
sampleAndWrite(tensorFields_);
|
|
||||||
|
|
||||||
sampleAndWriteSurfaceFields(surfaceScalarFields_);
|
|
||||||
sampleAndWriteSurfaceFields(surfaceVectorFields_);
|
|
||||||
sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
|
|
||||||
sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
|
|
||||||
sampleAndWriteSurfaceFields(surfaceTensorFields_);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2016-2021 OpenCFD Ltd.
|
Copyright (C) 2016-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -50,7 +50,7 @@ Description
|
|||||||
writeInterval 1;
|
writeInterval 1;
|
||||||
|
|
||||||
// Fields to be probed
|
// Fields to be probed
|
||||||
fields (p U);
|
fields (U "p.*");
|
||||||
|
|
||||||
// Optional: do not recalculate cells if mesh moves
|
// Optional: do not recalculate cells if mesh moves
|
||||||
fixedLocations false;
|
fixedLocations false;
|
||||||
@ -72,15 +72,28 @@ Description
|
|||||||
}
|
}
|
||||||
\endverbatim
|
\endverbatim
|
||||||
|
|
||||||
|
Entries:
|
||||||
|
\table
|
||||||
|
Property | Description | Required | Default
|
||||||
|
type | Type-name: probes | yes |
|
||||||
|
probeLocations | Probe locations | yes |
|
||||||
|
fields | word/regex list of fields to sample | yes |
|
||||||
|
interpolationScheme | scheme to obtain values | no | cell
|
||||||
|
fixedLocations | Do not recalculate cells if mesh moves | no | true
|
||||||
|
includeOutOfBounds | Include out-of-bounds locations | no | true
|
||||||
|
sampleOnExecute | Sample on execution and store results | no | false
|
||||||
|
\endtable
|
||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
probes.C
|
probes.C
|
||||||
|
probesTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef probes_H
|
#ifndef Foam_probes_H
|
||||||
#define probes_H
|
#define Foam_probes_H
|
||||||
|
|
||||||
#include "stateFunctionObject.H"
|
#include "fvMeshFunctionObject.H"
|
||||||
#include "HashPtrTable.H"
|
#include "HashPtrTable.H"
|
||||||
#include "OFstream.H"
|
#include "OFstream.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
@ -89,15 +102,14 @@ SourceFiles
|
|||||||
#include "surfaceFieldsFwd.H"
|
#include "surfaceFieldsFwd.H"
|
||||||
#include "surfaceMesh.H"
|
#include "surfaceMesh.H"
|
||||||
#include "wordRes.H"
|
#include "wordRes.H"
|
||||||
|
#include "IOobjectList.H"
|
||||||
using namespace Foam::functionObjects;
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
// Forward declaration of classes
|
// Forward Declarations
|
||||||
class Time;
|
class Time;
|
||||||
class objectRegistry;
|
class objectRegistry;
|
||||||
class dictionary;
|
class dictionary;
|
||||||
@ -110,70 +122,75 @@ class mapPolyMesh;
|
|||||||
|
|
||||||
class probes
|
class probes
|
||||||
:
|
:
|
||||||
public stateFunctionObject,
|
public functionObjects::fvMeshFunctionObject,
|
||||||
public pointField
|
public pointField
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Protected classes
|
// Protected Classes
|
||||||
|
|
||||||
//- Class used for grouping field types
|
//- Grouping of field names by GeometricField type
|
||||||
template<class Type>
|
template<class GeoField>
|
||||||
class fieldGroup
|
struct fieldGroup : public DynamicList<word> {};
|
||||||
:
|
|
||||||
public DynamicList<word>
|
|
||||||
|
// Data Types
|
||||||
|
|
||||||
|
//- Local control for sampling actions
|
||||||
|
enum sampleActionType : unsigned
|
||||||
{
|
{
|
||||||
public:
|
ACTION_NONE = 0,
|
||||||
//- Construct null
|
ACTION_WRITE = 0x1,
|
||||||
fieldGroup()
|
ACTION_STORE = 0x2,
|
||||||
:
|
ACTION_ALL = 0xF
|
||||||
DynamicList<word>(0)
|
|
||||||
{}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Protected data
|
// Protected Data
|
||||||
|
|
||||||
//- Const reference to fvMesh
|
|
||||||
const fvMesh& mesh_;
|
|
||||||
|
|
||||||
//- Load fields from files (not from objectRegistry)
|
//- Load fields from files (not from objectRegistry)
|
||||||
bool loadFromFiles_;
|
bool loadFromFiles_;
|
||||||
|
|
||||||
|
//- Fixed locations (default: true)
|
||||||
// Read from dictionary
|
|
||||||
|
|
||||||
//- Names of fields to probe
|
|
||||||
wordRes fieldSelection_;
|
|
||||||
|
|
||||||
//- Fixed locations, default = yes
|
|
||||||
// Note: set to false for moving mesh calculations where locations
|
// Note: set to false for moving mesh calculations where locations
|
||||||
// should move with the mesh
|
// should move with the mesh
|
||||||
bool fixedLocations_;
|
bool fixedLocations_;
|
||||||
|
|
||||||
//- Interpolation scheme name
|
//- Include probes that were not found (default: true)
|
||||||
// Note: only possible when fixedLocations_ is true
|
|
||||||
word interpolationScheme_;
|
|
||||||
|
|
||||||
//- Include probes that were not found
|
|
||||||
bool includeOutOfBounds_;
|
bool includeOutOfBounds_;
|
||||||
|
|
||||||
|
//- Output verbosity
|
||||||
|
bool verbose_;
|
||||||
|
|
||||||
// Calculated
|
//- Perform sample actions on execute as well
|
||||||
|
bool onExecute_;
|
||||||
|
|
||||||
//- Categorized scalar/vector/tensor vol fields
|
//- Requested names of fields to probe
|
||||||
fieldGroup<scalar> scalarFields_;
|
wordRes fieldSelection_;
|
||||||
fieldGroup<vector> vectorFields_;
|
|
||||||
fieldGroup<sphericalTensor> sphericalTensorFields_;
|
|
||||||
fieldGroup<symmTensor> symmTensorFields_;
|
|
||||||
fieldGroup<tensor> tensorFields_;
|
|
||||||
|
|
||||||
//- Categorized scalar/vector/tensor surf fields
|
//- Interpolation/sample scheme to obtain values at the points
|
||||||
fieldGroup<scalar> surfaceScalarFields_;
|
// Note: only possible when fixedLocations_ is true
|
||||||
fieldGroup<vector> surfaceVectorFields_;
|
word samplePointScheme_;
|
||||||
fieldGroup<sphericalTensor> surfaceSphericalTensorFields_;
|
|
||||||
fieldGroup<symmTensor> surfaceSymmTensorFields_;
|
|
||||||
fieldGroup<tensor> surfaceTensorFields_;
|
// Calculated
|
||||||
|
|
||||||
|
//- Current list of field names selected for sampling
|
||||||
|
DynamicList<word> selectedFieldNames_;
|
||||||
|
|
||||||
|
//- Categorized scalar/vector/tensor volume fields
|
||||||
|
fieldGroup<volScalarField> scalarFields_;
|
||||||
|
fieldGroup<volVectorField> vectorFields_;
|
||||||
|
fieldGroup<volSphericalTensorField> sphericalTensorFields_;
|
||||||
|
fieldGroup<volSymmTensorField> symmTensorFields_;
|
||||||
|
fieldGroup<volTensorField> tensorFields_;
|
||||||
|
|
||||||
|
//- Categorized scalar/vector/tensor surface fields
|
||||||
|
fieldGroup<surfaceScalarField> surfaceScalarFields_;
|
||||||
|
fieldGroup<surfaceVectorField> surfaceVectorFields_;
|
||||||
|
fieldGroup<surfaceSphericalTensorField> surfaceSphericalTensorFields_;
|
||||||
|
fieldGroup<surfaceSymmTensorField> surfaceSymmTensorFields_;
|
||||||
|
fieldGroup<surfaceTensorField> surfaceTensorFields_;
|
||||||
|
|
||||||
//- Cells to be probed (obtained from the locations)
|
//- Cells to be probed (obtained from the locations)
|
||||||
labelList elementList_;
|
labelList elementList_;
|
||||||
@ -185,58 +202,57 @@ protected:
|
|||||||
// on any processor)
|
// on any processor)
|
||||||
labelList processor_;
|
labelList processor_;
|
||||||
|
|
||||||
//- Current open files
|
//- Current open files (non-empty on master only)
|
||||||
HashPtrTable<OFstream> probeFilePtrs_;
|
HashPtrTable<OFstream> probeFilePtrs_;
|
||||||
|
|
||||||
// Additional fields for patchProbes
|
//- Patch IDs on which the new probes are located (for patchProbes)
|
||||||
|
labelList patchIDList_;
|
||||||
|
|
||||||
//- Patch IDs on which the new probes are located
|
//- Original probes location (only used for patchProbes)
|
||||||
labelList patchIDList_;
|
pointField oldPoints_;
|
||||||
|
|
||||||
//- Original probes location (only used for patchProbes)
|
|
||||||
pointField oldPoints_;
|
|
||||||
|
|
||||||
|
|
||||||
// Protected Member Functions
|
// Protected Member Functions
|
||||||
|
|
||||||
//- Clear old field groups
|
|
||||||
void clearFieldGroups();
|
|
||||||
|
|
||||||
//- Classify field types, returns the number of fields
|
|
||||||
label classifyFields();
|
|
||||||
|
|
||||||
//- Find cells and faces containing probes
|
//- Find cells and faces containing probes
|
||||||
virtual void findElements(const fvMesh& mesh);
|
virtual void findElements(const fvMesh& mesh);
|
||||||
|
|
||||||
//- Classify field type and open/close file streams,
|
//- Classify field types, close/open file streams
|
||||||
// returns number of fields to sample
|
// \return number of fields to sample
|
||||||
label prepare();
|
label prepare(unsigned request);
|
||||||
|
|
||||||
|
//- Get from registry or load from disk
|
||||||
|
template<class GeoField>
|
||||||
|
tmp<GeoField> getOrLoadField(const word& fieldName) const;
|
||||||
|
|
||||||
|
//- Store results: min/max/average/size
|
||||||
|
template<class Type>
|
||||||
|
void storeResults(const word& fieldName, const Field<Type>& values);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//- Sample and write a particular volume field
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Write field values
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void sampleAndWrite
|
void writeValues
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>&
|
const word& fieldName,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalar timeValue
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Sample and store/write all applicable sampled fields
|
||||||
//- Sample and write a particular surface field
|
template<class GeoField>
|
||||||
template<class Type>
|
void performAction
|
||||||
void sampleAndWrite
|
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&
|
const fieldGroup<GeoField>& fieldNames, /* must be sorted */
|
||||||
|
unsigned request
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Sample and write all the fields of the given type
|
//- Perform sampling action with store/write
|
||||||
template<class Type>
|
bool performAction(unsigned request);
|
||||||
void sampleAndWrite(const fieldGroup<Type>&);
|
|
||||||
|
|
||||||
//- Sample and write all the surface fields of the given type
|
|
||||||
template<class Type>
|
|
||||||
void sampleAndWriteSurfaceFields(const fieldGroup<Type>&);
|
|
||||||
|
|
||||||
//- No copy construct
|
//- No copy construct
|
||||||
probes(const probes&) = delete;
|
probes(const probes&) = delete;
|
||||||
@ -244,7 +260,6 @@ private:
|
|||||||
//- No copy assignment
|
//- No copy assignment
|
||||||
void operator=(const probes&) = delete;
|
void operator=(const probes&) = delete;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//- Runtime type information
|
//- Runtime type information
|
||||||
@ -270,14 +285,18 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
//- Enable/disable verbose output
|
||||||
|
// \return old value
|
||||||
|
bool verbose(const bool on) noexcept;
|
||||||
|
|
||||||
//- Return names of fields to probe
|
//- Return names of fields to probe
|
||||||
virtual const wordRes& fieldNames() const
|
virtual const wordRes& fieldNames() const noexcept
|
||||||
{
|
{
|
||||||
return fieldSelection_;
|
return fieldSelection_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return locations to probe
|
//- Return locations to probe
|
||||||
virtual const pointField& probeLocations() const
|
virtual const pointField& probeLocations() const noexcept
|
||||||
{
|
{
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -289,7 +308,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
//- Cells to be probed (obtained from the locations)
|
//- Cells to be probed (obtained from the locations)
|
||||||
const labelList& elements() const
|
const labelList& elements() const noexcept
|
||||||
{
|
{
|
||||||
return elementList_;
|
return elementList_;
|
||||||
}
|
}
|
||||||
@ -297,7 +316,7 @@ public:
|
|||||||
//- Read the probes
|
//- Read the probes
|
||||||
virtual bool read(const dictionary&);
|
virtual bool read(const dictionary&);
|
||||||
|
|
||||||
//- Execute, currently does nothing
|
//- Sample and store result if the sampleOnExecute is enabled.
|
||||||
virtual bool execute();
|
virtual bool execute();
|
||||||
|
|
||||||
//- Sample and write
|
//- Sample and write
|
||||||
@ -313,27 +332,24 @@ public:
|
|||||||
virtual void readUpdate(const polyMesh::readUpdateState state)
|
virtual void readUpdate(const polyMesh::readUpdateState state)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Sampling
|
||||||
|
|
||||||
//- Sample a volume field at all locations
|
//- Sample a volume field at all locations
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>> sample
|
tmp<Field<Type>> sample(const VolumeField<Type>&) const;
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Sample a single vol field on all sample locations
|
|
||||||
template<class Type>
|
|
||||||
tmp<Field<Type>> sample(const word& fieldName) const;
|
|
||||||
|
|
||||||
//- Sample a single scalar field on all sample locations
|
|
||||||
template<class Type>
|
|
||||||
tmp<Field<Type>> sampleSurfaceFields(const word& fieldName) const;
|
|
||||||
|
|
||||||
//- Sample a surface field at all locations
|
//- Sample a surface field at all locations
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<Field<Type>> sample
|
tmp<Field<Type>> sample(const SurfaceField<Type>&) const;
|
||||||
(
|
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>&
|
//- Sample a volume field at all locations
|
||||||
) const;
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sample(const word& fieldName) const;
|
||||||
|
|
||||||
|
//- Sample a surface field at all locations
|
||||||
|
template<class Type>
|
||||||
|
tmp<Field<Type>> sampleSurfaceField(const word& fieldName) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,127 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------*\
|
|
||||||
========= |
|
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
||||||
\\ / O peration |
|
|
||||||
\\ / A nd | www.openfoam.com
|
|
||||||
\\/ M anipulation |
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
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/>.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "probes.H"
|
|
||||||
#include "volFields.H"
|
|
||||||
#include "surfaceFields.H"
|
|
||||||
#include "IOobjectList.H"
|
|
||||||
#include "stringListOps.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::probes::clearFieldGroups()
|
|
||||||
{
|
|
||||||
scalarFields_.clear();
|
|
||||||
vectorFields_.clear();
|
|
||||||
sphericalTensorFields_.clear();
|
|
||||||
symmTensorFields_.clear();
|
|
||||||
tensorFields_.clear();
|
|
||||||
|
|
||||||
surfaceScalarFields_.clear();
|
|
||||||
surfaceVectorFields_.clear();
|
|
||||||
surfaceSphericalTensorFields_.clear();
|
|
||||||
surfaceSymmTensorFields_.clear();
|
|
||||||
surfaceTensorFields_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::probes::classifyFields()
|
|
||||||
{
|
|
||||||
label nFields = 0;
|
|
||||||
clearFieldGroups();
|
|
||||||
|
|
||||||
HashTable<wordHashSet> available =
|
|
||||||
(
|
|
||||||
loadFromFiles_
|
|
||||||
? IOobjectList(mesh_, mesh_.time().timeName()).classes(fieldSelection_)
|
|
||||||
: mesh_.classes(fieldSelection_)
|
|
||||||
);
|
|
||||||
|
|
||||||
forAllConstIters(available, iter)
|
|
||||||
{
|
|
||||||
const word& fieldType = iter.key();
|
|
||||||
const wordList fieldNames = iter.val().sortedToc();
|
|
||||||
|
|
||||||
const label count = fieldNames.size(); // pre-filtered, so non-empty
|
|
||||||
|
|
||||||
if (fieldType == volScalarField::typeName)
|
|
||||||
{
|
|
||||||
scalarFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volVectorField::typeName)
|
|
||||||
{
|
|
||||||
vectorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volSphericalTensorField::typeName)
|
|
||||||
{
|
|
||||||
sphericalTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volSymmTensorField::typeName)
|
|
||||||
{
|
|
||||||
symmTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == volTensorField::typeName)
|
|
||||||
{
|
|
||||||
tensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == surfaceScalarField::typeName)
|
|
||||||
{
|
|
||||||
surfaceScalarFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == surfaceVectorField::typeName)
|
|
||||||
{
|
|
||||||
surfaceVectorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == surfaceSphericalTensorField::typeName)
|
|
||||||
{
|
|
||||||
surfaceSphericalTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == surfaceSymmTensorField::typeName)
|
|
||||||
{
|
|
||||||
surfaceSymmTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
else if (fieldType == surfaceTensorField::typeName)
|
|
||||||
{
|
|
||||||
surfaceTensorFields_.append(fieldNames);
|
|
||||||
nFields += count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nFields;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -6,7 +6,7 @@
|
|||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
Copyright (C) 2017-2022 OpenCFD Ltd.
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
This file is part of OpenFOAM.
|
This file is part of OpenFOAM.
|
||||||
@ -38,10 +38,8 @@ namespace Foam
|
|||||||
{
|
{
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class isNotEqOp
|
struct isNotEqOp
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
void operator()(T& x, const T& y) const
|
void operator()(T& x, const T& y) const
|
||||||
{
|
{
|
||||||
const T unsetVal(-VGREAT*pTraits<T>::one);
|
const T unsetVal(-VGREAT*pTraits<T>::one);
|
||||||
@ -61,25 +59,87 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class GeoField>
|
||||||
|
Foam::tmp<GeoField>
|
||||||
|
Foam::probes::getOrLoadField(const word& fieldName) const
|
||||||
|
{
|
||||||
|
tmp<GeoField> tfield;
|
||||||
|
|
||||||
|
if (loadFromFiles_)
|
||||||
|
{
|
||||||
|
tfield.reset
|
||||||
|
(
|
||||||
|
new GeoField
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
fieldName,
|
||||||
|
mesh_.time().timeName(),
|
||||||
|
mesh_,
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
mesh_
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Slightly paranoid here
|
||||||
|
tfield.cref(mesh_.cfindObject<GeoField>(fieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::probes::storeResults
|
||||||
|
(
|
||||||
|
const word& fieldName,
|
||||||
|
const Field<Type>& values
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const MinMax<Type> limits(values);
|
||||||
|
const Type avgVal = average(values);
|
||||||
|
|
||||||
|
this->setResult("average(" + fieldName + ")", avgVal);
|
||||||
|
this->setResult("min(" + fieldName + ")", limits.min());
|
||||||
|
this->setResult("max(" + fieldName + ")", limits.max());
|
||||||
|
this->setResult("size(" + fieldName + ")", values.size());
|
||||||
|
|
||||||
|
if (verbose_)
|
||||||
|
{
|
||||||
|
Info<< name() << " : " << fieldName << nl
|
||||||
|
<< " avg: " << avgVal << nl
|
||||||
|
<< " min: " << limits.min() << nl
|
||||||
|
<< " max: " << limits.max() << nl << nl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::probes::sampleAndWrite
|
void Foam::probes::writeValues
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vField
|
const word& fieldName,
|
||||||
|
const Field<Type>& values,
|
||||||
|
const scalar timeValue
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Field<Type> values(sample(vField));
|
|
||||||
|
|
||||||
if (Pstream::master())
|
if (Pstream::master())
|
||||||
{
|
{
|
||||||
unsigned int w = IOstream::defaultPrecision() + 7;
|
const unsigned int w = IOstream::defaultPrecision() + 7;
|
||||||
OFstream& os = *probeFilePtrs_[vField.name()];
|
OFstream& os = *probeFilePtrs_[fieldName];
|
||||||
|
|
||||||
os << setw(w) << vField.time().timeOutputValue();
|
os << setw(w) << timeValue;
|
||||||
|
|
||||||
forAll(values, probei)
|
forAll(values, probei)
|
||||||
{
|
{
|
||||||
@ -90,144 +150,53 @@ void Foam::probes::sampleAndWrite
|
|||||||
}
|
}
|
||||||
os << endl;
|
os << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const word& fieldName = vField.name();
|
|
||||||
this->setResult("average(" + fieldName + ")", average(values));
|
|
||||||
this->setResult("min(" + fieldName + ")", min(values));
|
|
||||||
this->setResult("max(" + fieldName + ")", max(values));
|
|
||||||
this->setResult("size(" + fieldName + ")", values.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class GeoField>
|
||||||
void Foam::probes::sampleAndWrite
|
void Foam::probes::performAction
|
||||||
(
|
(
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
|
const fieldGroup<GeoField>& fieldNames,
|
||||||
|
unsigned request
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
Field<Type> values(sample(sField));
|
for (const word& fieldName : fieldNames)
|
||||||
|
|
||||||
if (Pstream::master())
|
|
||||||
{
|
{
|
||||||
unsigned int w = IOstream::defaultPrecision() + 7;
|
tmp<GeoField> tfield = getOrLoadField<GeoField>(fieldName);
|
||||||
OFstream& os = *probeFilePtrs_[sField.name()];
|
|
||||||
|
|
||||||
os << setw(w) << sField.time().timeOutputValue();
|
if (tfield)
|
||||||
|
|
||||||
forAll(values, probei)
|
|
||||||
{
|
{
|
||||||
if (includeOutOfBounds_ || processor_[probei] != -1)
|
const auto& field = tfield();
|
||||||
|
const scalar timeValue = field.time().timeOutputValue();
|
||||||
|
|
||||||
|
Field<typename GeoField::value_type> values(sample(field));
|
||||||
|
|
||||||
|
this->storeResults(fieldName, values);
|
||||||
|
if (request & ACTION_WRITE)
|
||||||
{
|
{
|
||||||
os << ' ' << setw(w) << values[probei];
|
this->writeValues(fieldName, values, timeValue);
|
||||||
}
|
|
||||||
}
|
|
||||||
os << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
const word& fieldName = sField.name();
|
|
||||||
this->setResult("average(" + fieldName + ")", average(values));
|
|
||||||
this->setResult("min(" + fieldName + ")", min(values));
|
|
||||||
this->setResult("max(" + fieldName + ")", max(values));
|
|
||||||
this->setResult("size(" + fieldName + ")", values.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::probes::sampleAndWrite(const fieldGroup<Type>& fields)
|
|
||||||
{
|
|
||||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
|
||||||
|
|
||||||
for (const auto& fieldName : fields)
|
|
||||||
{
|
|
||||||
if (loadFromFiles_)
|
|
||||||
{
|
|
||||||
sampleAndWrite
|
|
||||||
(
|
|
||||||
VolFieldType
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
mesh_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
objectRegistry::const_iterator iter = mesh_.find(fieldName);
|
|
||||||
|
|
||||||
if (iter.found() && iter()->type() == VolFieldType::typeName)
|
|
||||||
{
|
|
||||||
sampleAndWrite(mesh_.lookupObject<VolFieldType>(fieldName));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::probes::sampleAndWriteSurfaceFields(const fieldGroup<Type>& fields)
|
|
||||||
{
|
|
||||||
typedef GeometricField<Type, fvsPatchField, surfaceMesh> SurfaceFieldType;
|
|
||||||
|
|
||||||
for (const auto& fieldName : fields)
|
|
||||||
{
|
|
||||||
if (loadFromFiles_)
|
|
||||||
{
|
|
||||||
sampleAndWrite
|
|
||||||
(
|
|
||||||
SurfaceFieldType
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
mesh_.time().timeName(),
|
|
||||||
mesh_,
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
mesh_
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
objectRegistry::const_iterator iter = mesh_.find(fieldName);
|
|
||||||
|
|
||||||
if (iter.found() && iter()->type() == SurfaceFieldType::typeName)
|
|
||||||
{
|
|
||||||
sampleAndWrite(mesh_.lookupObject<SurfaceFieldType>(fieldName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::probes::sample
|
Foam::probes::sample(const VolumeField<Type>& vField) const
|
||||||
(
|
|
||||||
const GeometricField<Type, fvPatchField, volMesh>& vField
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||||
|
|
||||||
auto tValues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||||
auto& values = tValues.ref();
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
if (fixedLocations_)
|
if (fixedLocations_)
|
||||||
{
|
{
|
||||||
autoPtr<interpolation<Type>> interpolator
|
autoPtr<interpolation<Type>> interpPtr
|
||||||
(
|
(
|
||||||
interpolation<Type>::New(interpolationScheme_, vField)
|
interpolation<Type>::New(samplePointScheme_, vField)
|
||||||
);
|
);
|
||||||
|
|
||||||
forAll(*this, probei)
|
forAll(*this, probei)
|
||||||
@ -236,7 +205,7 @@ Foam::probes::sample
|
|||||||
{
|
{
|
||||||
const vector& position = operator[](probei);
|
const vector& position = operator[](probei);
|
||||||
|
|
||||||
values[probei] = interpolator().interpolate
|
values[probei] = interpPtr().interpolate
|
||||||
(
|
(
|
||||||
position,
|
position,
|
||||||
elementList_[probei],
|
elementList_[probei],
|
||||||
@ -259,35 +228,18 @@ Foam::probes::sample
|
|||||||
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
||||||
Pstream::listCombineScatter(values);
|
Pstream::listCombineScatter(values);
|
||||||
|
|
||||||
return tValues;
|
return tvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::probes::sample(const word& fieldName) const
|
Foam::probes::sample(const SurfaceField<Type>& sField) const
|
||||||
{
|
|
||||||
return sample
|
|
||||||
(
|
|
||||||
mesh_.lookupObject<GeometricField<Type, fvPatchField, volMesh>>
|
|
||||||
(
|
|
||||||
fieldName
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::Field<Type>>
|
|
||||||
Foam::probes::sample
|
|
||||||
(
|
|
||||||
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
const Type unsetVal(-VGREAT*pTraits<Type>::one);
|
||||||
|
|
||||||
auto tValues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
auto tvalues = tmp<Field<Type>>::New(Field<Type>(this->size(), unsetVal));
|
||||||
auto& values = tValues.ref();
|
auto& values = tvalues.ref();
|
||||||
|
|
||||||
forAll(*this, probei)
|
forAll(*this, probei)
|
||||||
{
|
{
|
||||||
@ -300,21 +252,24 @@ Foam::probes::sample
|
|||||||
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
Pstream::listCombineGather(values, isNotEqOp<Type>());
|
||||||
Pstream::listCombineScatter(values);
|
Pstream::listCombineScatter(values);
|
||||||
|
|
||||||
return tValues;
|
return tvalues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::Field<Type>>
|
Foam::tmp<Foam::Field<Type>>
|
||||||
Foam::probes::sampleSurfaceFields(const word& fieldName) const
|
Foam::probes::sample(const word& fieldName) const
|
||||||
{
|
{
|
||||||
return sample
|
return sample(mesh_.lookupObject<VolumeField<Type>>(fieldName));
|
||||||
(
|
|
||||||
mesh_.lookupObject<GeometricField<Type, fvsPatchField, surfaceMesh>>
|
|
||||||
(
|
|
||||||
fieldName
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
Foam::tmp<Foam::Field<Type>>
|
||||||
|
Foam::probes::sampleSurfaceField(const word& fieldName) const
|
||||||
|
{
|
||||||
|
return sample(mesh_.lookupObject<SurfaceField<Type>>(fieldName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -36,46 +36,40 @@ Volume3_v_fins
|
|||||||
|
|
||||||
probesFins
|
probesFins
|
||||||
{
|
{
|
||||||
type probes;
|
type probes;
|
||||||
libs (sampling);
|
libs (sampling);
|
||||||
writeControl timeStep;
|
writeControl timeStep;
|
||||||
writeInterval 1;
|
writeInterval 1;
|
||||||
interpolationScheme cell;
|
interpolationScheme cell;
|
||||||
region v_fins;
|
region v_fins;
|
||||||
setFormat raw;
|
|
||||||
log true;
|
fields ( T );
|
||||||
valueOutput false;
|
|
||||||
writeFields false;
|
|
||||||
|
|
||||||
probeLocations
|
probeLocations
|
||||||
(
|
(
|
||||||
(0.118 0.01 -0.125)
|
(0.118 0.01 -0.125)
|
||||||
(0.118 0.03 -0.125)
|
(0.118 0.03 -0.125)
|
||||||
);
|
);
|
||||||
|
|
||||||
fields ( T );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
probesFluid
|
probesFluid
|
||||||
{
|
{
|
||||||
type probes;
|
type probes;
|
||||||
libs (sampling);
|
libs (sampling);
|
||||||
writeControl timeStep;
|
writeControl timeStep;
|
||||||
writeInterval 1;
|
writeInterval 1;
|
||||||
interpolationScheme cell;
|
interpolationScheme cell;
|
||||||
region domain0;
|
region domain0;
|
||||||
setFormat raw;
|
|
||||||
log true;
|
log true;
|
||||||
valueOutput false;
|
verbose true;
|
||||||
writeFields false;
|
|
||||||
|
fields (T U);
|
||||||
|
|
||||||
probeLocations
|
probeLocations
|
||||||
(
|
(
|
||||||
(0.118 0.035 -0.125)
|
(0.118 0.035 -0.125)
|
||||||
(0.118 0.07 -0.125)
|
(0.118 0.07 -0.125)
|
||||||
);
|
);
|
||||||
|
|
||||||
fields ( T U);
|
|
||||||
}
|
}
|
||||||
#remove (_volFieldValue _surfaceFieldValue)
|
#remove (_volFieldValue _surfaceFieldValue)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user