ENH: fieldMinMax function object - updated for case where there are no cells on a local processor, e.g. CHT

This commit is contained in:
Andrew Heather
2018-10-03 13:06:31 +01:00
parent 6141575532
commit 6627515838
3 changed files with 133 additions and 180 deletions

View File

@ -123,12 +123,6 @@ Foam::functionObjects::fieldMinMax::fieldMinMax
} }
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::functionObjects::fieldMinMax::~fieldMinMax()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::functionObjects::fieldMinMax::read(const dictionary& dict) bool Foam::functionObjects::fieldMinMax::read(const dictionary& dict)

View File

@ -156,6 +156,14 @@ protected:
//- No copy assignment //- No copy assignment
void operator=(const fieldMinMax&) = delete; void operator=(const fieldMinMax&) = delete;
//- Calculate the field min/max for a given field type
template<class Type>
void calcMinMaxFieldType
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const word& outputFieldName
);
//- Calculate the field min/max //- Calculate the field min/max
template<class Type> template<class Type>
void calcMinMaxFields void calcMinMaxFields
@ -183,7 +191,7 @@ public:
//- Destructor //- Destructor
virtual ~fieldMinMax(); virtual ~fieldMinMax() = default;
// Member Functions // Member Functions

View File

@ -111,139 +111,59 @@ void Foam::functionObjects::fieldMinMax::output
template<class Type> template<class Type>
void Foam::functionObjects::fieldMinMax::calcMinMaxFields void Foam::functionObjects::fieldMinMax::calcMinMaxFieldType
( (
const word& fieldName, const GeometricField<Type, fvPatchField, volMesh>& field,
const modeType& mode const word& outputFieldName
) )
{ {
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
if (obr_.foundObject<fieldType>(fieldName))
{
const label proci = Pstream::myProcNo(); const label proci = Pstream::myProcNo();
const fieldType& field = lookupObject<fieldType>(fieldName); // Find min internal field value info
const volVectorField::Boundary& CfBoundary =
mesh_.C().boundaryField();
switch (mode)
{
case mdMag:
{
const volScalarField magField(mag(field));
const volScalarField::Boundary& magFieldBoundary =
magField.boundaryField();
scalarList minVs(Pstream::nProcs());
labelList minCells(Pstream::nProcs());
List<vector> minCs(Pstream::nProcs());
label minProci = findMin(magField);
minVs[proci] = magField[minProci];
minCells[proci] = minProci;
minCs[proci] = mesh_.C()[minProci];
scalarList maxVs(Pstream::nProcs());
labelList maxCells(Pstream::nProcs());
List<vector> maxCs(Pstream::nProcs());
label maxProci = findMax(magField);
maxVs[proci] = magField[maxProci];
maxCells[proci] = maxProci;
maxCs[proci] = mesh_.C()[maxProci];
forAll(magFieldBoundary, patchi)
{
const scalarField& mfp = magFieldBoundary[patchi];
if (mfp.size())
{
const vectorField& Cfp = CfBoundary[patchi];
const labelList& faceCells =
magFieldBoundary[patchi].patch().faceCells();
label minPi = findMin(mfp);
if (mfp[minPi] < minVs[proci])
{
minVs[proci] = mfp[minPi];
minCells[proci] = faceCells[minPi];
minCs[proci] = Cfp[minPi];
}
label maxPi = findMax(mfp);
if (mfp[maxPi] > maxVs[proci])
{
maxVs[proci] = mfp[maxPi];
maxCells[proci] = faceCells[maxPi];
maxCs[proci] = Cfp[maxPi];
}
}
}
Pstream::gatherList(minVs);
Pstream::scatterList(minVs);
Pstream::gatherList(minCells);
Pstream::scatterList(minCells);
Pstream::gatherList(minCs);
Pstream::scatterList(minCs);
Pstream::gatherList(maxVs);
Pstream::scatterList(maxVs);
Pstream::gatherList(maxCells);
Pstream::scatterList(maxCells);
Pstream::gatherList(maxCs);
Pstream::scatterList(maxCs);
label mini = findMin(minVs);
scalar minValue = minVs[mini];
const label minCell = minCells[mini];
const vector& minC = minCs[mini];
label maxi = findMax(maxVs);
scalar maxValue = maxVs[maxi];
const label maxCell = maxCells[maxi];
const vector& maxC = maxCs[maxi];
output
(
fieldName,
word("mag(" + fieldName + ")"),
minCell,
maxCell,
minC,
maxC,
mini,
maxi,
minValue,
maxValue
);
break;
}
case mdCmpt:
{
const typename fieldType::Boundary&
fieldBoundary = field.boundaryField();
List<Type> minVs(Pstream::nProcs()); List<Type> minVs(Pstream::nProcs());
labelList minCells(Pstream::nProcs()); labelList minCells(Pstream::nProcs());
List<vector> minCs(Pstream::nProcs()); List<vector> minCs(Pstream::nProcs());
label minProci = findMin(field); label minProci = findMin(field);
if (minProci != -1)
{
minVs[proci] = field[minProci]; minVs[proci] = field[minProci];
minCells[proci] = minProci; minCells[proci] = minProci;
minCs[proci] = mesh_.C()[minProci]; minCs[proci] = mesh_.C()[minProci];
}
else
{
minVs[proci] = pTraits<Type>::max;
minCells[proci] = -1;
minCs[proci] = vector::max;
}
// Find max internal field value info
List<Type> maxVs(Pstream::nProcs()); List<Type> maxVs(Pstream::nProcs());
labelList maxCells(Pstream::nProcs()); labelList maxCells(Pstream::nProcs());
List<vector> maxCs(Pstream::nProcs()); List<vector> maxCs(Pstream::nProcs());
label maxProci = findMax(field); label maxProci = findMax(field);
if (maxProci != -1)
{
maxVs[proci] = field[maxProci]; maxVs[proci] = field[maxProci];
maxCells[proci] = maxProci; maxCells[proci] = maxProci;
maxCs[proci] = mesh_.C()[maxProci]; maxCs[proci] = mesh_.C()[maxProci];
}
else
{
maxVs[proci] = pTraits<Type>::min;
maxCells[proci] = -1;
maxCs[proci] = vector::max;
}
// Find min and max boundary field info
const auto& fieldBoundary = field.boundaryField();
const auto& CfBoundary = mesh_.C().boundaryField();
forAll(fieldBoundary, patchi) forAll(fieldBoundary, patchi)
{ {
const Field<Type>& fp = fieldBoundary[patchi]; const Field<Type>& fp = fieldBoundary[patchi];
if (fp.size()) if (fp.size())
{ {
const vectorField& Cfp = CfBoundary[patchi]; const vectorField& Cfp = CfBoundary[patchi];
@ -269,6 +189,7 @@ void Foam::functionObjects::fieldMinMax::calcMinMaxFields
} }
} }
// Collect info from all processors and output
Pstream::gatherList(minVs); Pstream::gatherList(minVs);
Pstream::scatterList(minVs); Pstream::scatterList(minVs);
Pstream::gatherList(minCells); Pstream::gatherList(minCells);
@ -284,19 +205,19 @@ void Foam::functionObjects::fieldMinMax::calcMinMaxFields
Pstream::scatterList(maxCs); Pstream::scatterList(maxCs);
label mini = findMin(minVs); label mini = findMin(minVs);
Type minValue = minVs[mini]; const Type& minValue = minVs[mini];
const label minCell = minCells[mini]; const label minCell = minCells[mini];
const vector& minC = minCs[mini]; const vector& minC = minCs[mini];
label maxi = findMax(maxVs); label maxi = findMax(maxVs);
Type maxValue = maxVs[maxi]; const Type& maxValue = maxVs[maxi];
const label maxCell = maxCells[maxi]; const label maxCell = maxCells[maxi];
const vector& maxC = maxCs[maxi]; const vector& maxC = maxCs[maxi];
output output
( (
fieldName, field.name(),
fieldName, outputFieldName,
minCell, minCell,
maxCell, maxCell,
minC, minC,
@ -306,6 +227,36 @@ void Foam::functionObjects::fieldMinMax::calcMinMaxFields
minValue, minValue,
maxValue maxValue
); );
}
template<class Type>
void Foam::functionObjects::fieldMinMax::calcMinMaxFields
(
const word& fieldName,
const modeType& mode
)
{
typedef GeometricField<Type, fvPatchField, volMesh> fieldType;
if (obr_.foundObject<fieldType>(fieldName))
{
const fieldType& field = lookupObject<fieldType>(fieldName);
switch (mode)
{
case mdMag:
{
calcMinMaxFieldType<scalar>
(
mag(field),
word("mag(" + fieldName + ")")
);
break;
}
case mdCmpt:
{
calcMinMaxFieldType(field, fieldName);
break; break;
} }
default: default: