Merge branch 'feature-function-objects-2206' into 'develop'
New function objects See merge request Development/openfoam!541
This commit is contained in:
commit
c6d9c0317d
@ -20,7 +20,6 @@ fieldValues/fieldValue/fieldValue.C
|
||||
fieldValues/fieldValue/fieldValueNew.C
|
||||
fieldValues/volFieldValue/volFieldValue.C
|
||||
fieldValues/surfaceFieldValue/surfaceFieldValue.C
|
||||
fieldValues/multiFieldValue/multiFieldValue.C
|
||||
|
||||
heatTransferCoeff/heatTransferCoeff.C
|
||||
heatTransferCoeff/heatTransferCoeffModels/heatTransferCoeffModel/heatTransferCoeffModel.C
|
||||
@ -31,6 +30,8 @@ heatTransferCoeff/heatTransferCoeffModels/ReynoldsAnalogy/ReynoldsAnalogy.C
|
||||
|
||||
limitFields/limitFields.C
|
||||
|
||||
multiFieldValue/multiFieldValue.C
|
||||
|
||||
nearWallFields/nearWallFields.C
|
||||
nearWallFields/findCellParticle.C
|
||||
nearWallFields/findCellParticleCloud.C
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2012-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -63,48 +63,36 @@ Foam::functionObjects::fieldValues::multiFieldValue::operationTypeNames_
|
||||
|
||||
void Foam::functionObjects::fieldValues::multiFieldValue::writeFileHeader
|
||||
(
|
||||
const wordList& foNames,
|
||||
const List<wordList>& entries,
|
||||
const List<wordList>& types,
|
||||
Ostream& os
|
||||
) const
|
||||
{
|
||||
const wordList& fields0 = functions_[0].fields();
|
||||
const word groupPrefix("Group");
|
||||
|
||||
DynamicList<word> commonFields(fields0.size());
|
||||
|
||||
for (const word& fieldName : fields0)
|
||||
forAll(entries, i)
|
||||
{
|
||||
bool common = true;
|
||||
writeCommented(os, groupPrefix + Foam::name(i));
|
||||
os << nl;
|
||||
|
||||
for (label functioni=1; functioni < functions_.size(); ++functioni)
|
||||
forAll(entries[i], functioni)
|
||||
{
|
||||
if (!functions_[functioni].fields().found(fieldName))
|
||||
{
|
||||
common = false;
|
||||
break;
|
||||
}
|
||||
writeCommented
|
||||
(
|
||||
os,
|
||||
" - " + foNames[functioni] + ":" + entries[i][functioni]
|
||||
);
|
||||
os << nl;
|
||||
}
|
||||
|
||||
if (common)
|
||||
{
|
||||
commonFields.append(fieldName);
|
||||
}
|
||||
}
|
||||
|
||||
forAll(functions_, functioni)
|
||||
{
|
||||
writeHeaderValue
|
||||
(
|
||||
os,
|
||||
"Source" + Foam::name(functioni),
|
||||
functions_[functioni].name()
|
||||
);
|
||||
}
|
||||
|
||||
writeHeaderValue(os, "Operation", operationTypeNames_[operation_]);
|
||||
writeCommented(os, "Time");
|
||||
|
||||
for (const word& fieldName : commonFields)
|
||||
forAll(entries, entryi)
|
||||
{
|
||||
os << tab << fieldName;
|
||||
writeTabbed(os, groupPrefix + Foam::name(entryi));
|
||||
}
|
||||
|
||||
os << endl;
|
||||
@ -125,10 +113,7 @@ Foam::functionObjects::fieldValues::multiFieldValue::multiFieldValue
|
||||
operation_(opSubtract),
|
||||
functions_()
|
||||
{
|
||||
if (read(dict))
|
||||
{
|
||||
writeFileHeader(file());
|
||||
}
|
||||
read(dict);
|
||||
}
|
||||
|
||||
|
||||
@ -139,52 +124,73 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::read
|
||||
const dictionary& dict
|
||||
)
|
||||
{
|
||||
if (stateFunctionObject::read(dict) && writeFile::read(dict))
|
||||
if (!stateFunctionObject::read(dict) || !writeFile::read(dict))
|
||||
{
|
||||
const dictionary& functionsDict = dict.subDict("functions");
|
||||
functions_.resize(functionsDict.size());
|
||||
|
||||
if (functions_.empty())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "No functions specified"
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
label functioni = 0;
|
||||
for (const entry& dEntry : functionsDict)
|
||||
{
|
||||
if (!dEntry.isDict())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Functions must be specified in dictionary format"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
const dictionary& localDict = dEntry.dict();
|
||||
|
||||
functions_.set
|
||||
(
|
||||
functioni,
|
||||
fieldValue::New
|
||||
(
|
||||
IOobject::scopedName(name(), localDict.dictName()),
|
||||
time(),
|
||||
localDict,
|
||||
false
|
||||
)
|
||||
);
|
||||
|
||||
++functioni;
|
||||
}
|
||||
|
||||
operation_ = operationTypeNames_.get("operation", dict);
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
operation_ = operationTypeNames_.get("operation", dict);
|
||||
|
||||
const dictionary& functionsDict = dict.subDict("functions");
|
||||
functions_.resize(functionsDict.size());
|
||||
|
||||
if (functions_.empty())
|
||||
{
|
||||
WarningInFunction
|
||||
<< "No functions specified"
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
resultFields_.resize(functions_.size());
|
||||
|
||||
label functioni = 0;
|
||||
for (const entry& dEntry : functionsDict)
|
||||
{
|
||||
if (!dEntry.isDict())
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "Functions must be specified in dictionary format"
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
const dictionary& localDict = dEntry.dict();
|
||||
|
||||
functions_.set
|
||||
(
|
||||
functioni,
|
||||
functionObject::New
|
||||
(
|
||||
IOobject::scopedName(name(), localDict.dictName()),
|
||||
time(),
|
||||
localDict
|
||||
).ptr()
|
||||
);
|
||||
|
||||
// Deactivate logging for child function objects
|
||||
//functions_[functioni].log = false;
|
||||
|
||||
// Get result field names; not specified implies all
|
||||
resultFields_[functioni] =
|
||||
localDict.getOrDefault<wordList>("resultFields", wordList());
|
||||
|
||||
Info<< type() << ' ' << name() << ':' << nl;
|
||||
if (resultFields_[functioni].size())
|
||||
{
|
||||
Info<< " " << functions_[functioni].name()
|
||||
<< " " << resultFields_[functioni];
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< " " << functions_[functioni].name()
|
||||
<< " - using all available entries";
|
||||
}
|
||||
Info<< nl << endl;
|
||||
|
||||
++functioni;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -201,19 +207,25 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::write()
|
||||
wordList entries0;
|
||||
label nEntries = -1;
|
||||
|
||||
wordList names(nFunction);
|
||||
wordList foNames(nFunction);
|
||||
List<wordList> entries;
|
||||
List<wordList> types;
|
||||
|
||||
forAll(functions_, functioni)
|
||||
{
|
||||
auto& f = functions_[functioni];
|
||||
names[functioni] = f.name();
|
||||
foNames[functioni] = f.name();
|
||||
|
||||
// Note: results are not available until the call to write()
|
||||
// Note: replicating functionObjectList execute() and write()
|
||||
// - results may be written on either
|
||||
f.execute();
|
||||
f.write();
|
||||
|
||||
const wordList e(objectResultEntries(f.name()));
|
||||
wordList e = resultFields_[functioni];
|
||||
if (e.empty())
|
||||
{
|
||||
e = objectResultEntries(f.name());
|
||||
}
|
||||
|
||||
if (functioni == 0)
|
||||
{
|
||||
@ -237,54 +249,72 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::write()
|
||||
<< "Inconsistent number of result entries" << nl
|
||||
<< " " << f0Name << " entries:" << entries0 << nl
|
||||
<< " " << f.name() << " entries:" << e
|
||||
<< abort(FatalError);
|
||||
<< exit(FatalError);
|
||||
}
|
||||
|
||||
forAll(e, entryi)
|
||||
{
|
||||
entries[entryi][functioni] = e[entryi];
|
||||
types[entryi][functioni] = objectResultType(f.name(), e[entryi]);
|
||||
|
||||
if (types[entryi][functioni] == word::null)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Unable to find function object result" << nl
|
||||
<< " function object : " << f.name() << nl
|
||||
<< " result name : " << e[entryi] << nl
|
||||
<< " available results : "
|
||||
<< objectResultEntries(f.name())
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!writtenHeader_)
|
||||
{
|
||||
writeFileHeader(foNames, entries, types, file());
|
||||
writtenHeader_ = true;
|
||||
}
|
||||
|
||||
writeCurrentTime(file());
|
||||
|
||||
forAll(entries, entryi)
|
||||
forAll(entries, i)
|
||||
{
|
||||
const wordList& entriesi = entries[entryi];
|
||||
const word& t0 = types[entryi][0];
|
||||
const wordList& typesi = types[entryi];
|
||||
forAll(typesi, functioni)
|
||||
{
|
||||
const word& t = typesi[functioni];
|
||||
const wordList& entryi = entries[i];
|
||||
const word& expectedType = types[i][0];
|
||||
const wordList& foTypes = types[i];
|
||||
|
||||
if (t != t0)
|
||||
forAll(foTypes, functioni)
|
||||
{
|
||||
const word& foType = foTypes[functioni];
|
||||
|
||||
if (foType != expectedType)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Inconsistent function result types" << nl
|
||||
<< " " << functions_[0].name()
|
||||
<< " result type:" << t0 << nl
|
||||
<< " result type:" << expectedType << nl
|
||||
<< " " << functions_[functioni].name()
|
||||
<< " result type:" << typesi[functioni]
|
||||
<< abort(FatalError);
|
||||
<< " result type:" << foType
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
const bool ok
|
||||
(
|
||||
applyOperation<scalar>(t0, names, entriesi)
|
||||
|| applyOperation<vector>(t0, names, entriesi)
|
||||
|| applyOperation<sphericalTensor>(t0, names, entriesi)
|
||||
|| applyOperation<symmTensor>(t0, names, entriesi)
|
||||
|| applyOperation<tensor>(t0, names, entriesi)
|
||||
applyOperation<scalar>(expectedType, foNames, entryi)
|
||||
|| applyOperation<vector>(expectedType, foNames, entryi)
|
||||
|| applyOperation<sphericalTensor>(expectedType, foNames, entryi)
|
||||
|| applyOperation<symmTensor>(expectedType, foNames, entryi)
|
||||
|| applyOperation<tensor>(expectedType, foNames, entryi)
|
||||
);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
Log << "Operation not applied between functions:" << nl
|
||||
<< flatOutput(names, FlatOutput::BareComma{}) << nl
|
||||
<< flatOutput(foNames, FlatOutput::BareComma{}) << nl
|
||||
<< "with result names:" << nl
|
||||
<< flatOutput(entriesi, FlatOutput::BareComma{})
|
||||
<< flatOutput(entryi, FlatOutput::BareComma{})
|
||||
<< endl;
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -30,10 +30,9 @@ Group
|
||||
grpFieldFunctionObjects
|
||||
|
||||
Description
|
||||
Computes a selected operation between multiple \c fieldValue function
|
||||
objects.
|
||||
Computes a selected operation between multiple function objects.
|
||||
|
||||
The operation is applied to all results of each \c fieldValue object.
|
||||
The operation is applied to all results of each object.
|
||||
|
||||
Note
|
||||
Each object must generate the same number and type of results.
|
||||
@ -43,11 +42,9 @@ Usage
|
||||
\verbatim
|
||||
multiFieldValue1
|
||||
{
|
||||
// Mandatory entries (unmodifiable)
|
||||
type multiFieldValue;
|
||||
libs (fieldFunctionObjects);
|
||||
|
||||
// Mandatory entries (runtime modifiable)
|
||||
// Mandatory entries
|
||||
type multiFieldValue;
|
||||
libs (fieldFunctionObjects);
|
||||
operation average;
|
||||
|
||||
// List of fieldValue function objects as dictionaries
|
||||
@ -56,10 +53,14 @@ Usage
|
||||
region1
|
||||
{
|
||||
...
|
||||
// Optional
|
||||
resultFields (field1 field2);
|
||||
}
|
||||
region2
|
||||
{
|
||||
...
|
||||
// Optional
|
||||
resultFields (field1 field2);
|
||||
}
|
||||
|
||||
...
|
||||
@ -67,41 +68,41 @@ Usage
|
||||
regionN
|
||||
{
|
||||
...
|
||||
// Optional
|
||||
resultFields (field1 field2);
|
||||
}
|
||||
}
|
||||
|
||||
// Optional (inherited) entries
|
||||
// Inherited entries
|
||||
...
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
where the entries mean:
|
||||
\table
|
||||
Property | Description | Type | Req'd | Dflt
|
||||
type | Type name: multiFieldValue | word | yes | -
|
||||
libs | Library name: fieldFunctionObjects | word | yes | -
|
||||
operation | Operation type to apply to values | word | yes | -
|
||||
functions | List of fieldValue function objects | dict | yes | -
|
||||
Property | Description | Type | Reqd | Deflt
|
||||
type | Type name: multiFieldValue | word | yes | -
|
||||
libs | Library name: fieldFunctionObjects | word | yes | -
|
||||
operation | Operation type to apply to values | word | yes | -
|
||||
functions | List of function objects | dict | yes | -
|
||||
\endtable
|
||||
|
||||
Options for the \c operation entry:
|
||||
\plaintable
|
||||
add | add
|
||||
subtract | subtract
|
||||
min | minimum
|
||||
max | maximum
|
||||
average | average
|
||||
sum | Sum of values
|
||||
add | Add values (same as sum)
|
||||
subtract | Subtract values from first entry
|
||||
min | Minimum value
|
||||
max | Maximum value
|
||||
average | Average value
|
||||
\endplaintable
|
||||
|
||||
The \c resultFields entry can be used to set the name of the function object
|
||||
result fields to process. If omitted, all available values are employed.
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
- \link fieldValue.H \endlink
|
||||
|
||||
Usage by the \c postProcess utility is not available.
|
||||
|
||||
See also
|
||||
- Foam::functionObject
|
||||
- Foam::functionObjects::fieldValue
|
||||
- ExtendedCodeGuide::functionObjects::field::multiFieldValue
|
||||
- \link stateFunctionObject.H \endlink
|
||||
- \link writeFile.H \endlink
|
||||
|
||||
SourceFiles
|
||||
multiFieldValue.C
|
||||
@ -114,7 +115,6 @@ SourceFiles
|
||||
|
||||
#include "stateFunctionObject.H"
|
||||
#include "writeFile.H"
|
||||
#include "fieldValue.H"
|
||||
#include "Enum.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -161,8 +161,11 @@ private:
|
||||
//- Operation to apply to values
|
||||
operationType operation_;
|
||||
|
||||
//- List of fieldValue function objects
|
||||
PtrList<fieldValue> functions_;
|
||||
//- List of function objects
|
||||
PtrList<functionObject> functions_;
|
||||
|
||||
//- List of result fields per function object
|
||||
List<wordList> resultFields_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
@ -183,7 +186,13 @@ protected:
|
||||
// Protected Member Functions
|
||||
|
||||
//- Output file header information
|
||||
virtual void writeFileHeader(Ostream& os) const;
|
||||
virtual void writeFileHeader
|
||||
(
|
||||
const wordList& foNames,
|
||||
const List<wordList>& entries,
|
||||
const List<wordList>& types,
|
||||
Ostream& os
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2012-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2015-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -34,7 +34,7 @@ template<class Type>
|
||||
bool Foam::functionObjects::fieldValues::multiFieldValue::applyOperation
|
||||
(
|
||||
const word& resultType,
|
||||
const wordList& names,
|
||||
const wordList& foNames,
|
||||
const wordList& entryNames
|
||||
)
|
||||
{
|
||||
@ -45,10 +45,10 @@ bool Foam::functionObjects::fieldValues::multiFieldValue::applyOperation
|
||||
|
||||
Type result = Zero;
|
||||
|
||||
Field<Type> values(names.size());
|
||||
Field<Type> values(foNames.size());
|
||||
forAll(values, i)
|
||||
{
|
||||
values[i] = this->getObjectResult<Type>(names[i], entryNames[i]);
|
||||
values[i] = this->getObjectResult<Type>(foNames[i], entryNames[i]);
|
||||
}
|
||||
|
||||
const word& opName = operationTypeNames_[operation_];
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,7 @@ License
|
||||
#include "ParticleErosion.H"
|
||||
#include "ParticleTracks.H"
|
||||
#include "ParticleTrap.H"
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "PatchCollisionDensity.H"
|
||||
#include "PatchInteractionFields.H"
|
||||
#include "PatchPostProcessing.H"
|
||||
@ -57,6 +58,7 @@ License
|
||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleZoneInfo, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchInteractionFields, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2018 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,7 @@ License
|
||||
#include "ParticleErosion.H"
|
||||
#include "ParticleTracks.H"
|
||||
#include "ParticleTrap.H"
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "PatchCollisionDensity.H"
|
||||
#include "PatchInteractionFields.H"
|
||||
#include "PatchPostProcessing.H"
|
||||
@ -60,6 +61,7 @@ License
|
||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleZoneInfo, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchInteractionFields, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2021 OpenCFD Ltd.
|
||||
Copyright (C) 2021-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -36,6 +36,7 @@ License
|
||||
#include "ParticleErosion.H"
|
||||
#include "ParticleTracks.H"
|
||||
#include "ParticleTrap.H"
|
||||
#include "ParticleZoneInfo.H"
|
||||
#include "PatchCollisionDensity.H"
|
||||
#include "PatchInteractionFields.H"
|
||||
#include "PatchPostProcessing.H"
|
||||
@ -58,6 +59,7 @@ License
|
||||
makeCloudFunctionObjectType(ParticleErosion, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTracks, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleTrap, CloudType); \
|
||||
makeCloudFunctionObjectType(ParticleZoneInfo, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchCollisionDensity, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchInteractionFields, CloudType); \
|
||||
makeCloudFunctionObjectType(PatchPostProcessing, CloudType); \
|
||||
|
@ -0,0 +1,458 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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 "ParticleZoneInfo.H"
|
||||
#include "DynamicField.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
struct particleInfoCombineOp
|
||||
{
|
||||
void operator()(particleInfo& p1, const particleInfo& p2) const
|
||||
{
|
||||
// p2 not set
|
||||
if (p2.origID == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// p1 not set - initialise with p2
|
||||
if (p1.origID == -1)
|
||||
{
|
||||
p1 = p2;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set initial values
|
||||
if (p2.time0 < p1.time0)
|
||||
{
|
||||
p1.time0 = p2.time0;
|
||||
p1.d0 = p2.d0;
|
||||
p1.mass0 = p2.mass0;
|
||||
}
|
||||
|
||||
// Accumulate age
|
||||
p1.age += p2.age;
|
||||
|
||||
// Set latest available values
|
||||
if (p2.isOlderThan(p1))
|
||||
{
|
||||
p1.position = p2.position;
|
||||
p1.d = p2.d;
|
||||
p1.mass = p2.mass;
|
||||
}
|
||||
}
|
||||
};
|
||||
} // End namespace Foam
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::Field<Type> getData
|
||||
(
|
||||
const Foam::UList<Foam::particleInfo>& data,
|
||||
Type Foam::particleInfo::* field
|
||||
)
|
||||
{
|
||||
Field<Type> result(data.size());
|
||||
|
||||
forAll(data, i)
|
||||
{
|
||||
result[i] = data[i].*field;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::Field<Type> getParData
|
||||
(
|
||||
const Foam::List<Foam::List<Foam::particleInfo>>& parData,
|
||||
Type Foam::particleInfo::* field
|
||||
)
|
||||
{
|
||||
DynamicField<Type> result;
|
||||
|
||||
for (const auto& particles : parData)
|
||||
{
|
||||
for (const auto& p : particles)
|
||||
{
|
||||
if (p.origID != -1)
|
||||
{
|
||||
result.append(p.*field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::writeWriter
|
||||
(
|
||||
const DynamicList<particleInfo>& data
|
||||
)
|
||||
{
|
||||
coordSet coords
|
||||
(
|
||||
"zoneParticles",
|
||||
"xyz",
|
||||
getData(data_, &particleInfo::position),
|
||||
scalarList(data.size(), Zero)
|
||||
);
|
||||
|
||||
writerPtr_->open(coords, this->baseTimeDir() / "zoneParticles");
|
||||
writerPtr_->beginTime(this->owner().time());
|
||||
|
||||
#undef writeLocal
|
||||
#define writeLocal(field) \
|
||||
writerPtr_->write(#field, getData(data, &particleInfo::field));
|
||||
|
||||
writeLocal(origID);
|
||||
writeLocal(origProc);
|
||||
writeLocal(time0);
|
||||
writeLocal(age);
|
||||
writeLocal(d0);
|
||||
writeLocal(d);
|
||||
writeLocal(mass0);
|
||||
writeLocal(mass);
|
||||
#undef writeLocal
|
||||
|
||||
writerPtr_->endTime();
|
||||
writerPtr_->close();
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::writeWriter
|
||||
(
|
||||
const List<List<particleInfo>>& procData
|
||||
)
|
||||
{
|
||||
vectorField points(getParData(procData, &particleInfo::position));
|
||||
|
||||
coordSet coords
|
||||
(
|
||||
"zoneParticles",
|
||||
"xyz",
|
||||
std::move(points),
|
||||
scalarList(points.size(), Zero)
|
||||
);
|
||||
|
||||
writerPtr_->open(coords, this->baseTimeDir() / "zoneParticles");
|
||||
writerPtr_->beginTime(this->owner().time());
|
||||
|
||||
#undef writeLocal
|
||||
#define writeLocal(field) \
|
||||
writerPtr_->write(#field, getParData(procData, &particleInfo::field));
|
||||
|
||||
writeLocal(origID);
|
||||
writeLocal(origProc);
|
||||
writeLocal(time0);
|
||||
writeLocal(age);
|
||||
writeLocal(d0);
|
||||
writeLocal(d);
|
||||
writeLocal(mass0);
|
||||
writeLocal(mass);
|
||||
#undef writeLocal
|
||||
|
||||
writerPtr_->endTime();
|
||||
writerPtr_->close();
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::writeFileHeader(Ostream& os) const
|
||||
{
|
||||
this->writeHeaderValue(os, "cellZone", cellZoneName_);
|
||||
this->writeHeaderValue(os, "time", this->owner().time().timeOutputValue());
|
||||
this->writeHeader(os, "");
|
||||
this->writeCommented(os, "origID");
|
||||
os << tab << "origProc"
|
||||
<< tab << "(x y z)"
|
||||
<< tab << "time0"
|
||||
<< tab << "age"
|
||||
<< tab << "d0"
|
||||
<< tab << "d"
|
||||
<< tab << "mass0"
|
||||
<< tab << "mass"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
bool Foam::ParticleZoneInfo<CloudType>::inZone(const label celli) const
|
||||
{
|
||||
return this->owner().mesh().cellZones()[cellZoneId_].whichCell(celli) != -1;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::label Foam::ParticleZoneInfo<CloudType>::getParticleID
|
||||
(
|
||||
const particleInfo& p
|
||||
) const
|
||||
{
|
||||
forAll(data_, i)
|
||||
{
|
||||
const auto& d = data_[i];
|
||||
if ((d.origProc == p.origProc) && (d.origID == p.origID))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ParticleZoneInfo<CloudType>::ParticleZoneInfo
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner,
|
||||
const word& modelName
|
||||
)
|
||||
:
|
||||
CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
|
||||
functionObjects::writeFile
|
||||
(
|
||||
owner,
|
||||
this->localPath(),
|
||||
typeName,
|
||||
this->coeffDict()
|
||||
),
|
||||
cellZoneName_(this->coeffDict().getWord("cellZone")),
|
||||
cellZoneId_(-1),
|
||||
data_(),
|
||||
movedParticles_(),
|
||||
maxIDs_(Pstream::nProcs(), Zero),
|
||||
writerPtr_
|
||||
(
|
||||
Pstream::master()
|
||||
? coordSetWriter::New
|
||||
(
|
||||
this->coeffDict().getWord("writer"),
|
||||
this->coeffDict().subOrEmptyDict("formatOptions")
|
||||
)
|
||||
: nullptr
|
||||
)
|
||||
{
|
||||
const auto& cellZones = owner.mesh().cellZones();
|
||||
|
||||
cellZoneId_ = cellZones.findZoneID(cellZoneName_);
|
||||
if (cellZoneId_ == -1)
|
||||
{
|
||||
FatalIOErrorInFunction(this->coeffDict())
|
||||
<< "Unable to find cellZone " << cellZoneName_
|
||||
<< ". Available cellZones are:" << cellZones.names()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
Info<< " Processing cellZone" << cellZoneName_ << " with id "
|
||||
<< cellZoneId_ << endl;
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
Foam::ParticleZoneInfo<CloudType>::ParticleZoneInfo
|
||||
(
|
||||
const ParticleZoneInfo<CloudType>& pzi
|
||||
)
|
||||
:
|
||||
CloudFunctionObject<CloudType>(pzi),
|
||||
writeFile(pzi),
|
||||
cellZoneName_(pzi.cellZoneName_),
|
||||
cellZoneId_(pzi.cellZoneId_),
|
||||
data_(pzi.data_),
|
||||
movedParticles_(pzi.movedParticles_),
|
||||
maxIDs_(Pstream::nProcs()),
|
||||
writerPtr_(nullptr)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::preEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
)
|
||||
{}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::postEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
)
|
||||
{
|
||||
Info<< this->type() << ":" << nl
|
||||
<< " Cell zone = " << cellZoneName_ << nl
|
||||
<< " Contributions = "
|
||||
<< returnReduce(movedParticles_.size(), sumOp<label>())
|
||||
<< endl;
|
||||
|
||||
if (!this->writeTime())
|
||||
{
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
for (const auto& p : movedParticles_)
|
||||
{
|
||||
const label id = getParticleID(p);
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
// New particle
|
||||
data_.append(p);
|
||||
maxIDs_[p.origProc] = max(maxIDs_[p.origProc], p.origID);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add to existing particle
|
||||
data_[id] += p;
|
||||
}
|
||||
}
|
||||
|
||||
movedParticles_.clear();
|
||||
|
||||
// Calls write
|
||||
CloudFunctionObject<CloudType>::postEvolve(td);
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::postMove
|
||||
(
|
||||
parcelType& p,
|
||||
const scalar dt,
|
||||
const point&,
|
||||
bool&
|
||||
)
|
||||
{
|
||||
if (inZone(p.cell()))
|
||||
{
|
||||
particleInfo newData;
|
||||
newData.origID = p.origId();
|
||||
newData.origProc = p.origProc();
|
||||
newData.position = p.position();
|
||||
newData.time0 = this->owner().time().value() + dt;
|
||||
newData.age = dt;
|
||||
newData.d0 = p.d();
|
||||
newData.d = p.d();
|
||||
newData.mass0 = p.mass();
|
||||
newData.mass = newData.mass0;
|
||||
|
||||
movedParticles_.append(newData);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class CloudType>
|
||||
void Foam::ParticleZoneInfo<CloudType>::write()
|
||||
{
|
||||
autoPtr<OFstream> osPtr =
|
||||
this->createFile("particles", this->owner().time().timeOutputValue());
|
||||
|
||||
if (Pstream::parRun())
|
||||
{
|
||||
// Find number of particles per proc
|
||||
labelList allMaxIDs(maxIDs_);
|
||||
Pstream::listCombineGather(allMaxIDs, maxEqOp<label>());
|
||||
Pstream::scatterList(allMaxIDs);
|
||||
|
||||
List<List<particleInfo>> procParticles(Pstream::nProcs());
|
||||
forAll(procParticles, proci)
|
||||
{
|
||||
procParticles[proci].resize(allMaxIDs[proci] + 1);
|
||||
}
|
||||
|
||||
// Insert into bins for accumulation
|
||||
for (const auto& d : data_)
|
||||
{
|
||||
procParticles[d.origProc][d.origID] = d;
|
||||
}
|
||||
|
||||
for (auto& particles : procParticles)
|
||||
{
|
||||
Pstream::listCombineGather(particles, particleInfoCombineOp());
|
||||
}
|
||||
|
||||
if (Pstream::master())
|
||||
{
|
||||
writeWriter(procParticles);
|
||||
|
||||
auto& os = osPtr();
|
||||
writeFileHeader(os);
|
||||
|
||||
label nData = 0;
|
||||
for (const auto& particles : procParticles)
|
||||
{
|
||||
for (const auto& p : particles)
|
||||
{
|
||||
if (p.origID != -1)
|
||||
{
|
||||
os << p << endl;
|
||||
++nData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Info<< " Number of particles = " << nData << nl
|
||||
<< " Written data to " << os.name() << endl;
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
writeWriter(data_);
|
||||
|
||||
auto& os = osPtr();
|
||||
writeFileHeader(os);
|
||||
|
||||
for (const auto& p : data_)
|
||||
{
|
||||
os << p << nl;
|
||||
}
|
||||
|
||||
Info<< " Number of particles = " << data_.size() << nl
|
||||
<< " Written data to " << os.name() << endl;
|
||||
}
|
||||
|
||||
Info<< endl;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -0,0 +1,334 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
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/>.
|
||||
|
||||
Class
|
||||
Foam::ParticleZoneInfo
|
||||
|
||||
Group
|
||||
grpLagrangianIntermediateFunctionObjects
|
||||
|
||||
Description
|
||||
Reports cloud information for particles passing through a specified cell
|
||||
zone.
|
||||
|
||||
Usage
|
||||
Example usage:
|
||||
\verbatim
|
||||
cloudFunctions
|
||||
{
|
||||
particleZoneInfo1
|
||||
{
|
||||
// Mandatory entries
|
||||
type particleZoneInfo;
|
||||
cellZone leftFluid;
|
||||
|
||||
// Optional entries
|
||||
writer vtk;
|
||||
}
|
||||
}
|
||||
\endverbatim
|
||||
|
||||
Results are written to file:
|
||||
- \<case\>/postProcessing/lagrangian/\<cloudName\>/\<functionName\>/\<time\>
|
||||
|
||||
\verbatim
|
||||
# cellZone : leftFluid
|
||||
# time : 1.0000000000e+00
|
||||
#
|
||||
# origID origProc (x y z) time0 age d0 d mass0 mass
|
||||
\endverbatim
|
||||
|
||||
Where
|
||||
- origID : particle ID
|
||||
- origProc : processor ID
|
||||
- (x y z) : Cartesian co-ordinates
|
||||
- time0 : time particle enters the cellZone
|
||||
- age : time spent in the cellZone
|
||||
- d0 : diameter on entry to the cellZone
|
||||
- d : current diameter
|
||||
- mass0 : mass on entry to the cellZone
|
||||
- mass : current mass
|
||||
|
||||
If the optional \c writer entry is supplied, cloud data is written in the
|
||||
specified format.
|
||||
|
||||
During the run, output statistics are reported after the cloud solution,
|
||||
e.g.:
|
||||
|
||||
\verbatim
|
||||
particleZoneInfo:
|
||||
Cell zone = leftFluid
|
||||
Contributions = 257
|
||||
\endverbatim
|
||||
|
||||
Here, 'Contributions' refers to the number of incremental particle-move
|
||||
contributions recorded during this time step. At write times, the output
|
||||
is extended, e.g.:
|
||||
|
||||
\verbatim
|
||||
particleZoneInfo:
|
||||
Cell zone = leftFluid
|
||||
Contributions = 822
|
||||
Number of particles = 199
|
||||
Written data to "postProcessing/lagrangian/reactingCloud1/
|
||||
\endverbatim
|
||||
|
||||
SourceFiles
|
||||
ParticleZoneInfo.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef ParticleZoneInfo_H
|
||||
#define ParticleZoneInfo_H
|
||||
|
||||
#include "CloudFunctionObject.H"
|
||||
#include "writeFile.H"
|
||||
#include "coordSetWriter.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
struct particleInfo Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
struct particleInfo
|
||||
{
|
||||
label origID = -1;
|
||||
label origProc = -1;
|
||||
vector position = Zero;
|
||||
scalar time0 = 0;
|
||||
scalar age = 0;
|
||||
scalar d0 = 0;
|
||||
scalar d = 0;
|
||||
scalar mass0 = 0;
|
||||
scalar mass = 0;
|
||||
|
||||
void operator+=(const particleInfo& p)
|
||||
{
|
||||
// Increment age
|
||||
age += p.age;
|
||||
|
||||
// Set current values
|
||||
position = p.position;
|
||||
d = p.d;
|
||||
mass = p.mass;
|
||||
}
|
||||
|
||||
scalar isOlderThan(const particleInfo& p) const
|
||||
{
|
||||
// Cannot just use time0 - particle may leave/re-enter and
|
||||
// so age is decoupled
|
||||
return (p.time0 + p.age) < (time0 + age);
|
||||
}
|
||||
|
||||
friend bool operator==(const particleInfo& a, const particleInfo& b)
|
||||
{
|
||||
return
|
||||
a.origID == b.origID
|
||||
&& a.origProc == b.origProc
|
||||
&& a.position == b.position
|
||||
&& a.time0 == b.time0
|
||||
&& a.age == b.age
|
||||
&& a.d0 == b.d0
|
||||
&& a.d == b.d
|
||||
&& a.mass0 == b.mass0
|
||||
&& a.mass == b.mass;
|
||||
}
|
||||
|
||||
friend bool operator!=(const particleInfo& a, const particleInfo& b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
|
||||
// IOstream Operators
|
||||
|
||||
friend Istream& operator>>(Istream& is, particleInfo& pi)
|
||||
{
|
||||
is >> pi.origID
|
||||
>> pi.origProc
|
||||
>> pi.position
|
||||
>> pi.time0
|
||||
>> pi.age
|
||||
>> pi.d0
|
||||
>> pi.d
|
||||
>> pi.mass0
|
||||
>> pi.mass;
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
friend Ostream& operator<<(Ostream& os, const particleInfo& pi)
|
||||
{
|
||||
os << pi.origID
|
||||
<< " " << pi.origProc
|
||||
<< " " << pi.position
|
||||
<< " " << pi.time0
|
||||
<< " " << pi.age
|
||||
<< " " << pi.d0
|
||||
<< " " << pi.d
|
||||
<< " " << pi.mass0
|
||||
<< " " << pi.mass;
|
||||
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class ParticleZoneInfo Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
template<class CloudType>
|
||||
class ParticleZoneInfo
|
||||
:
|
||||
public CloudFunctionObject<CloudType>,
|
||||
public functionObjects::writeFile
|
||||
|
||||
{
|
||||
// Private Data
|
||||
|
||||
// Typedefs
|
||||
|
||||
//- Convenience typedef for parcel type
|
||||
typedef typename CloudType::parcelType parcelType;
|
||||
|
||||
|
||||
//- Cell zone name
|
||||
word cellZoneName_;
|
||||
|
||||
//- Cell zone index
|
||||
label cellZoneId_;
|
||||
|
||||
//- Stored data
|
||||
DynamicList<particleInfo> data_;
|
||||
|
||||
//- Work storage
|
||||
DynamicList<particleInfo> movedParticles_;
|
||||
|
||||
//- Maximum particle ID per processor
|
||||
labelList maxIDs_;
|
||||
|
||||
//- Set writer
|
||||
autoPtr<coordSetWriter> writerPtr_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Write output file header
|
||||
void writeFileHeader(Ostream& os) const;
|
||||
|
||||
//- Return true if celli is in the cellZone
|
||||
bool inZone(const label celli) const;
|
||||
|
||||
//- Return the index of the particle in the storage (data_)
|
||||
//- Returns -1 if not found
|
||||
label getParticleID(const particleInfo& p) const;
|
||||
|
||||
//- Write fields using writerPtr_ for serial runs
|
||||
void writeWriter(const DynamicList<particleInfo>& data);
|
||||
|
||||
//- Write fields using writerPtr_ for parallel runs
|
||||
void writeWriter(const List<List<particleInfo>>& procData);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//- Runtime type information
|
||||
TypeName("particleZoneInfo");
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from dictionary
|
||||
ParticleZoneInfo
|
||||
(
|
||||
const dictionary& dict,
|
||||
CloudType& owner,
|
||||
const word& modelName
|
||||
);
|
||||
|
||||
//- Construct copy
|
||||
ParticleZoneInfo(const ParticleZoneInfo<CloudType>& pe);
|
||||
|
||||
//- Construct and return a clone
|
||||
virtual autoPtr<CloudFunctionObject<CloudType>> clone() const
|
||||
{
|
||||
return autoPtr<CloudFunctionObject<CloudType>>
|
||||
(
|
||||
new ParticleZoneInfo<CloudType>(*this)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~ParticleZoneInfo() = default;
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Pre-evolve hook
|
||||
virtual void preEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
);
|
||||
|
||||
//- Post-evolve hook
|
||||
virtual void postEvolve
|
||||
(
|
||||
const typename parcelType::trackingData& td
|
||||
);
|
||||
|
||||
//- Post-move hook
|
||||
virtual void postMove
|
||||
(
|
||||
parcelType& p,
|
||||
const scalar dt,
|
||||
const point& position0,
|
||||
bool& keepParticle
|
||||
);
|
||||
|
||||
//- Write
|
||||
virtual void write();
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#ifdef NoRepository
|
||||
#include "ParticleZoneInfo.C"
|
||||
#endif
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
@ -5,4 +5,6 @@ cd "${0%/*}" || exit # Run from this directory
|
||||
|
||||
cleanCase0
|
||||
|
||||
rm -rf procs.old
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
@ -13,4 +13,21 @@ runParallel topoSet
|
||||
|
||||
runParallel $(getApplication)
|
||||
|
||||
runApplication reconstructPar
|
||||
|
||||
|
||||
latestTime=$(foamListTimes -latestTime)
|
||||
|
||||
mv -f "$latestTime" "$latestTime".bak
|
||||
|
||||
mkdir procs.old
|
||||
|
||||
mv -f processor* procs.old
|
||||
|
||||
runParallel -s "decompose" redistributePar -decompose -time 9.5
|
||||
|
||||
runParallel -s 2 $(getApplication)
|
||||
|
||||
runParallel -s "reconstruct" redistributePar -reconstruct -latestTime
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
|
@ -0,0 +1,129 @@
|
||||
/*--------------------------------*- C++ -*----------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: v2112 |
|
||||
| \\ / A nd | Website: www.openfoam.com |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
sampleEpsilon1
|
||||
{
|
||||
type sets;
|
||||
libs (sampling);
|
||||
interpolationScheme cellPointFace;
|
||||
setFormat raw;
|
||||
fields ( epsilon );
|
||||
|
||||
sets
|
||||
(
|
||||
cloud
|
||||
{
|
||||
type cloud;
|
||||
axis xyz;
|
||||
points
|
||||
(
|
||||
(0.0025 0.05 0.005)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
multiFieldValue_add
|
||||
{
|
||||
// Mandatory entries
|
||||
type multiFieldValue;
|
||||
libs (fieldFunctionObjects);
|
||||
|
||||
operation add;
|
||||
|
||||
functions
|
||||
{
|
||||
movingWallEpsilon
|
||||
{
|
||||
type surfaceFieldValue;
|
||||
operation areaAverage;
|
||||
regionType patch;
|
||||
name movingWall;
|
||||
fields (epsilon);
|
||||
|
||||
writeFields no;
|
||||
writeToFile no;
|
||||
log no;
|
||||
resultFields (areaAverage(movingWall,epsilon));
|
||||
}
|
||||
fixedWallsEpsilon
|
||||
{
|
||||
type surfaceFieldValue;
|
||||
operation areaAverage;
|
||||
regionType patch;
|
||||
name fixedWalls;
|
||||
fields (epsilon);
|
||||
|
||||
writeFields no;
|
||||
writeToFile no;
|
||||
log yes;
|
||||
}
|
||||
averageEpsilon
|
||||
{
|
||||
type valueAverage;
|
||||
functionObject sampleEpsilon1;
|
||||
fields (average(epsilon));
|
||||
writeToFile no;
|
||||
log no;
|
||||
}
|
||||
}
|
||||
|
||||
// Inherited entries
|
||||
writePrecision 10;
|
||||
writeToFile true;
|
||||
useUserTime true;
|
||||
|
||||
region region0;
|
||||
enabled true;
|
||||
log true;
|
||||
timeStart 0;
|
||||
timeEnd 1000;
|
||||
executeControl timeStep;
|
||||
executeInterval 1;
|
||||
writeControl writeTime;
|
||||
writeInterval -1;
|
||||
}
|
||||
|
||||
|
||||
multiFieldValue_sum
|
||||
{
|
||||
${multiFieldValue_add}
|
||||
operation sum;
|
||||
}
|
||||
|
||||
|
||||
multiFieldValue_subtract
|
||||
{
|
||||
${multiFieldValue_add}
|
||||
operation subtract;
|
||||
}
|
||||
|
||||
|
||||
multiFieldValue_min
|
||||
{
|
||||
${multiFieldValue_add}
|
||||
operation min;
|
||||
}
|
||||
|
||||
|
||||
multiFieldValue_max
|
||||
{
|
||||
${multiFieldValue_add}
|
||||
operation max;
|
||||
}
|
||||
|
||||
|
||||
multiFieldValue_average
|
||||
{
|
||||
${multiFieldValue_add}
|
||||
operation average;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
@ -16,7 +16,7 @@ FoamFile
|
||||
|
||||
application pisoFoam;
|
||||
|
||||
startFrom startTime;
|
||||
startFrom latestTime;
|
||||
|
||||
startTime 0;
|
||||
|
||||
@ -68,6 +68,7 @@ functions
|
||||
#include "FOlog"
|
||||
#include "FOmag"
|
||||
#include "FOmagSqr"
|
||||
#include "FOmultiFieldValue"
|
||||
#include "FOmultiply"
|
||||
#include "FOmomentum"
|
||||
#include "FOnearWallFields"
|
||||
|
@ -160,6 +160,13 @@ subModels
|
||||
|
||||
cloudFunctions
|
||||
{
|
||||
particleZoneInfo1
|
||||
{
|
||||
type particleZoneInfo;
|
||||
cellZone leftFluid;
|
||||
writer vtk;
|
||||
}
|
||||
|
||||
patchParticleHistogram1
|
||||
{
|
||||
type patchParticleHistogram;
|
||||
|
Loading…
Reference in New Issue
Block a user