ENH: Adding surface fields to probes and patchProbes

This commit is contained in:
sergio
2012-02-15 16:16:59 +00:00
parent bf012bafae
commit 01ddfede1f
7 changed files with 397 additions and 11 deletions

View File

@ -2,7 +2,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-2012 OpenFOAM Foundation \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
@ -202,6 +202,7 @@ Foam::patchProbes::patchProbes
// Not easy to workaround (apart from feeding through flag into constructor) // Not easy to workaround (apart from feeding through flag into constructor)
// so clear out any cells found for now. // so clear out any cells found for now.
elementList_.clear(); elementList_.clear();
faceList_.clear();
read(dict); read(dict);
} }
@ -222,6 +223,12 @@ void Foam::patchProbes::write()
sampleAndWrite(sphericalTensorFields_); sampleAndWrite(sphericalTensorFields_);
sampleAndWrite(symmTensorFields_); sampleAndWrite(symmTensorFields_);
sampleAndWrite(tensorFields_); sampleAndWrite(tensorFields_);
sampleAndWriteSurfaceFields(surfaceScalarFields_);
sampleAndWriteSurfaceFields(surfaceVectorFields_);
sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
sampleAndWriteSurfaceFields(surfaceTensorFields_);
} }
} }

View File

@ -74,11 +74,24 @@ class patchProbes
); );
//- 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 //- Sample and write all the fields of the given type
template <class Type> template <class Type>
void sampleAndWrite(const fieldGroup<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 //- Sample a volume field at all locations
template<class Type> template<class Type>
tmp<Field<Type> > sample tmp<Field<Type> > sample
@ -87,6 +100,14 @@ class patchProbes
) const; ) 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 //- Sample a single field on all sample locations
template <class Type> template <class Type>
tmp<Field<Type> > sample(const word& fieldName) const; tmp<Field<Type> > sample(const word& fieldName) const;

View File

@ -54,6 +54,30 @@ void Foam::patchProbes::sampleAndWrite
} }
template<class Type>
void Foam::patchProbes::sampleAndWrite
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
)
{
Field<Type> values(sample(sField));
if (Pstream::master())
{
unsigned int w = IOstream::defaultPrecision() + 7;
OFstream& probeStream = *probeFilePtrs_[sField.name()];
probeStream << setw(w) << sField.time().value();
forAll(values, probeI)
{
probeStream << ' ' << setw(w) << values[probeI];
}
probeStream << endl;
}
}
template <class Type> template <class Type>
void Foam::patchProbes::sampleAndWrite void Foam::patchProbes::sampleAndWrite
( (
@ -106,6 +130,58 @@ void Foam::patchProbes::sampleAndWrite
} }
template<class Type>
void Foam::patchProbes::sampleAndWriteSurfaceFields
(
const fieldGroup<Type>& fields
)
{
forAll(fields, fieldI)
{
if (loadFromFiles_)
{
sampleAndWrite
(
GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fields[fieldI],
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
mesh_
)
);
}
else
{
objectRegistry::const_iterator iter = mesh_.find(fields[fieldI]);
if
(
iter != objectRegistry::end()
&& iter()->type()
== GeometricField<Type, fvsPatchField, surfaceMesh>::typeName
)
{
sampleAndWrite
(
mesh_.lookupObject
<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
fields[fieldI]
)
);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -159,4 +235,39 @@ Foam::patchProbes::sample(const word& fieldName) const
} }
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::patchProbes::sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& sField
) const
{
const Type unsetVal(-VGREAT*pTraits<Type>::one);
tmp<Field<Type> > tValues
(
new Field<Type>(this->size(), unsetVal)
);
Field<Type>& values = tValues();
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
forAll(*this, probeI)
{
label faceI = elementList_[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;
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -41,16 +41,45 @@ void Foam::probes::findElements(const fvMesh& mesh)
elementList_.clear(); elementList_.clear();
elementList_.setSize(size()); elementList_.setSize(size());
faceList_.clear();
faceList_.setSize(size());
forAll(*this, probeI) forAll(*this, probeI)
{ {
const vector& location = operator[](probeI); const vector& location = operator[](probeI);
elementList_[probeI] = mesh.findCell(location); const label cellI = mesh.findCell(location);
if (debug && elementList_[probeI] != -1) elementList_[probeI] = cellI;
if (cellI != -1)
{
const labelList& cellFaces = mesh.cells()[cellI];
const vector& cellCentre = mesh.cellCentres()[cellI];
scalar minDistance = GREAT;
label minFaceID = -1;
forAll (cellFaces, i)
{
label faceI = cellFaces[i];
vector dist = mesh.faceCentres()[faceI] - cellCentre;
if (mag(dist) < minDistance)
{
minDistance = mag(dist);
minFaceID = faceI;
}
}
faceList_[probeI] = minFaceID;
}
else
{
faceList_[probeI] = -1;
}
if (debug && (elementList_[probeI] != -1 || faceList_[probeI] != -1))
{ {
Pout<< "probes : found point " << location Pout<< "probes : found point " << location
<< " in cell " << elementList_[probeI] << endl; << " in cell " << elementList_[probeI]
<< " and face " << faceList_[probeI] << endl;
} }
} }
@ -60,25 +89,36 @@ void Foam::probes::findElements(const fvMesh& mesh)
{ {
const vector& location = operator[](probeI); const vector& location = operator[](probeI);
label cellI = elementList_[probeI]; label cellI = elementList_[probeI];
label faceI = faceList_[probeI];
// Check at least one processor with cell. // Check at least one processor with cell.
reduce(cellI, maxOp<label>()); reduce(cellI, maxOp<label>());
reduce(faceI, maxOp<label>());
if (cellI == -1) if (cellI == -1)
{ {
if (Pstream::master()) if (Pstream::master())
{ {
WarningIn("probes::read()") WarningIn("findElements::findElements(const fvMesh&)")
<< "Did not find location " << location << "Did not find location " << location
<< " in any cell. Skipping location." << endl; << " in any cell. Skipping location." << endl;
} }
} }
else if (faceI == -1)
{
if (Pstream::master())
{
WarningIn("probes::findElements(const fvMesh&)")
<< "Did not find location " << location
<< " in any face. Skipping location." << endl;
}
}
else else
{ {
// Make sure location not on two domains. // Make sure location not on two domains.
if (elementList_[probeI] != -1 && elementList_[probeI] != cellI) if (elementList_[probeI] != -1 && elementList_[probeI] != cellI)
{ {
WarningIn("probes::read()") WarningIn("probes::findElements(const fvMesh&)")
<< "Location " << location << "Location " << location
<< " seems to be on multiple domains:" << " seems to be on multiple domains:"
<< " cell " << elementList_[probeI] << " cell " << elementList_[probeI]
@ -89,6 +129,20 @@ void Foam::probes::findElements(const fvMesh& mesh)
<< " a processor patch. Change the location slightly" << " a processor patch. Change the location slightly"
<< " to prevent this." << endl; << " to prevent this." << endl;
} }
if (faceList_[probeI] != -1 && faceList_[probeI] != faceI)
{
WarningIn("probes::findElements(const fvMesh&)")
<< "Location " << location
<< " seems to be on multiple domains:"
<< " cell " << faceList_[probeI]
<< " on my domain " << Pstream::myProcNo()
<< " and face " << faceI << " on some other domain."
<< endl
<< "This might happen if the probe location is on"
<< " a processor patch. Change the location slightly"
<< " to prevent this." << endl;
}
} }
} }
} }
@ -109,6 +163,12 @@ Foam::label Foam::probes::prepare()
currentFields.insert(symmTensorFields_); currentFields.insert(symmTensorFields_);
currentFields.insert(tensorFields_); currentFields.insert(tensorFields_);
currentFields.insert(surfaceScalarFields_);
currentFields.insert(surfaceVectorFields_);
currentFields.insert(surfaceSphericalTensorFields_);
currentFields.insert(surfaceSymmTensorFields_);
currentFields.insert(surfaceTensorFields_);
if (debug) if (debug)
{ {
Info<< "Probing fields:" << currentFields << nl Info<< "Probing fields:" << currentFields << nl
@ -239,6 +299,12 @@ void Foam::probes::write()
sampleAndWrite(sphericalTensorFields_); sampleAndWrite(sphericalTensorFields_);
sampleAndWrite(symmTensorFields_); sampleAndWrite(symmTensorFields_);
sampleAndWrite(tensorFields_); sampleAndWrite(tensorFields_);
sampleAndWriteSurfaceFields(surfaceScalarFields_);
sampleAndWriteSurfaceFields(surfaceVectorFields_);
sampleAndWriteSurfaceFields(surfaceSphericalTensorFields_);
sampleAndWriteSurfaceFields(surfaceSymmTensorFields_);
sampleAndWriteSurfaceFields(surfaceTensorFields_);
} }
} }

View File

@ -42,7 +42,8 @@ SourceFiles
#include "polyMesh.H" #include "polyMesh.H"
#include "pointField.H" #include "pointField.H"
#include "volFieldsFwd.H" #include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "surfaceMesh.H"
#include "wordReList.H" #include "wordReList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -104,16 +105,26 @@ protected:
// Calculated // Calculated
//- Categorized scalar/vector/tensor fields //- Categorized scalar/vector/tensor vol fields
fieldGroup<scalar> scalarFields_; fieldGroup<scalar> scalarFields_;
fieldGroup<vector> vectorFields_; fieldGroup<vector> vectorFields_;
fieldGroup<sphericalTensor> sphericalTensorFields_; fieldGroup<sphericalTensor> sphericalTensorFields_;
fieldGroup<symmTensor> symmTensorFields_; fieldGroup<symmTensor> symmTensorFields_;
fieldGroup<tensor> tensorFields_; fieldGroup<tensor> tensorFields_;
//- Categorized scalar/vector/tensor surf fields
fieldGroup<scalar> surfaceScalarFields_;
fieldGroup<vector> surfaceVectorFields_;
fieldGroup<sphericalTensor> surfaceSphericalTensorFields_;
fieldGroup<symmTensor> surfaceSymmTensorFields_;
fieldGroup<tensor> surfaceTensorFields_;
// Cells to be probed (obtained from the locations) // Cells to be probed (obtained from the locations)
labelList elementList_; labelList elementList_;
// Faces to be probed
labelList faceList_;
//- Current open files //- Current open files
HashPtrTable<OFstream> probeFilePtrs_; HashPtrTable<OFstream> probeFilePtrs_;
@ -145,10 +156,22 @@ private:
const GeometricField<Type, fvPatchField, volMesh>& 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 //- Sample and write all the fields of the given type
template<class Type> template<class Type>
void sampleAndWrite(const fieldGroup<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>&);
//- Disallow default bitwise copy construct //- Disallow default bitwise copy construct
probes(const probes&); probes(const probes&);
@ -242,9 +265,21 @@ public:
const GeometricField<Type, fvPatchField, volMesh>& const GeometricField<Type, fvPatchField, volMesh>&
) const; ) const;
//- Sample a single field on all sample locations //- Sample a single vol field on all sample locations
template <class Type> template <class Type>
tmp<Field<Type> > sample(const word& fieldName) const; 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
template<class Type>
tmp<Field<Type> > sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>&
) const;
}; };

View File

@ -25,6 +25,7 @@ License
#include "probes.H" #include "probes.H"
#include "volFields.H" #include "volFields.H"
#include "surfaceFields.H"
#include "IOobjectList.H" #include "IOobjectList.H"
#include "stringListOps.H" #include "stringListOps.H"
@ -37,6 +38,12 @@ void Foam::probes::clearFieldGroups()
sphericalTensorFields_.clear(); sphericalTensorFields_.clear();
symmTensorFields_.clear(); symmTensorFields_.clear();
tensorFields_.clear(); tensorFields_.clear();
surfaceScalarFields_.clear();
surfaceVectorFields_.clear();
surfaceSphericalTensorFields_.clear();
surfaceSymmTensorFields_.clear();
surfaceTensorFields_.clear();
} }
@ -71,6 +78,31 @@ Foam::label Foam::probes::appendFieldGroup
tensorFields_.append(fieldName); tensorFields_.append(fieldName);
return 1; return 1;
} }
else if (fieldType == surfaceScalarField::typeName)
{
surfaceScalarFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceVectorField::typeName)
{
surfaceVectorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceSphericalTensorField::typeName)
{
surfaceSphericalTensorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceSymmTensorField::typeName)
{
surfaceSymmTensorFields_.append(fieldName);
return 1;
}
else if (fieldType == surfaceTensorField::typeName)
{
surfaceTensorFields_.append(fieldName);
return 1;
}
return 0; return 0;
} }

View File

@ -25,6 +25,7 @@ License
#include "probes.H" #include "probes.H"
#include "volFields.H" #include "volFields.H"
#include "surfaceFields.H"
#include "IOmanip.H" #include "IOmanip.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -86,11 +87,32 @@ void Foam::probes::sampleAndWrite
} }
template <class Type> template<class Type>
void Foam::probes::sampleAndWrite void Foam::probes::sampleAndWrite
( (
const fieldGroup<Type>& fields const GeometricField<Type, fvsPatchField, surfaceMesh>& vField
) )
{
Field<Type> values(sample(vField));
if (Pstream::master())
{
unsigned int w = IOstream::defaultPrecision() + 7;
OFstream& os = *probeFilePtrs_[vField.name()];
os << setw(w) << vField.time().value();
forAll(values, probeI)
{
os << ' ' << setw(w) << values[probeI];
}
os << endl;
}
}
template <class Type>
void Foam::probes::sampleAndWrite(const fieldGroup<Type>& fields)
{ {
forAll(fields, fieldI) forAll(fields, fieldI)
{ {
@ -138,6 +160,54 @@ void Foam::probes::sampleAndWrite
} }
template<class Type>
void Foam::probes::sampleAndWriteSurfaceFields(const fieldGroup<Type>& fields)
{
forAll(fields, fieldI)
{
if (loadFromFiles_)
{
sampleAndWrite
(
GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fields[fieldI],
mesh_.time().timeName(),
mesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
mesh_
)
);
}
else
{
objectRegistry::const_iterator iter = mesh_.find(fields[fieldI]);
if
(
iter != objectRegistry::end()
&& iter()->type()
== GeometricField<Type, fvsPatchField, surfaceMesh>::typeName
)
{
sampleAndWrite
(
mesh_.lookupObject
<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
fields[fieldI]
)
);
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type> template<class Type>
@ -185,4 +255,48 @@ Foam::probes::sample(const word& fieldName) const
} }
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::probes::sample
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& vField
) const
{
const Type unsetVal(-VGREAT*pTraits<Type>::one);
tmp<Field<Type> > tValues
(
new Field<Type>(this->size(), unsetVal)
);
Field<Type>& values = tValues();
forAll(*this, probeI)
{
if (faceList_[probeI] >= 0)
{
values[probeI] = vField[faceList_[probeI]];
}
}
Pstream::listCombineGather(values, isNotEqOp<Type>());
Pstream::listCombineScatter(values);
return tValues;
}
template<class Type>
Foam::tmp<Foam::Field<Type> >
Foam::probes::sampleSurfaceFields(const word& fieldName) const
{
return sample
(
mesh_.lookupObject<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
fieldName
)
);
}
// ************************************************************************* // // ************************************************************************* //